number_theory.diophantine_approximation
⟷
Mathlib.NumberTheory.DiophantineApproximation
The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -165,7 +165,7 @@ theorem exists_rat_abs_sub_le_and_den_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
obtain ⟨j, k, hk₀, hk₁, h⟩ := exists_int_int_abs_mul_sub_le ξ n_pos
have hk₀' : (0 : ℝ) < k := int.cast_pos.mpr hk₀
have hden : ((j / k : ℚ).den : ℤ) ≤ k := by convert le_of_dvd hk₀ (Rat.den_dvd j k);
- exact Rat.coe_int_div_eq_divInt
+ exact Rat.intCast_div_eq_divInt
refine' ⟨j / k, _, nat.cast_le.mp (hden.trans hk₁)⟩
rw [← div_div, le_div_iff (nat.cast_pos.mpr <| Rat.pos _ : (0 : ℝ) < _)]
refine' (mul_le_mul_of_nonneg_left (int.cast_le.mpr hden : _ ≤ (k : ℝ)) (abs_nonneg _)).trans _
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -169,8 +169,8 @@ theorem exists_rat_abs_sub_le_and_den_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
refine' ⟨j / k, _, nat.cast_le.mp (hden.trans hk₁)⟩
rw [← div_div, le_div_iff (nat.cast_pos.mpr <| Rat.pos _ : (0 : ℝ) < _)]
refine' (mul_le_mul_of_nonneg_left (int.cast_le.mpr hden : _ ≤ (k : ℝ)) (abs_nonneg _)).trans _
- rwa [← abs_of_pos hk₀', Rat.cast_div, Rat.cast_coe_int, Rat.cast_coe_int, ← abs_mul, sub_mul,
- div_mul_cancel _ hk₀'.ne', mul_comm]
+ rwa [← abs_of_pos hk₀', Rat.cast_div, Rat.cast_intCast, Rat.cast_intCast, ← abs_mul, sub_mul,
+ div_mul_cancel₀ _ hk₀'.ne', mul_comm]
#align real.exists_rat_abs_sub_le_and_denom_le Real.exists_rat_abs_sub_le_and_den_le
-/
@@ -254,7 +254,7 @@ theorem den_le_and_le_num_le_of_sub_lt_one_div_den_sq {ξ q : ℚ} (h : |ξ - q|
replace h : |ξ * q.denom - q.num| < 1 / q.denom
· rw [← mul_lt_mul_right hq₀] at h
conv_lhs at h => rw [← abs_of_pos hq₀, ← abs_mul, sub_mul, mul_denom_eq_num]
- rwa [sq, div_mul, mul_div_cancel_left _ hq₀.ne'] at h
+ rwa [sq, div_mul, mul_div_cancel_left₀ _ hq₀.ne'] at h
constructor
· rcases eq_or_ne ξ q with (rfl | H)
· exact le_rfl
@@ -419,7 +419,7 @@ theorem continued_fraction_convergent_eq_convergent (ξ : ℝ) (n : ℕ) :
(GeneralizedContinuedFraction.of ξ).convergents n = ξ.convergent n :=
by
induction' n with n ih generalizing ξ
- · simp only [zeroth_convergent_eq_h, of_h_eq_floor, convergent_zero, Rat.cast_coe_int]
+ · simp only [zeroth_convergent_eq_h, of_h_eq_floor, convergent_zero, Rat.cast_intCast]
· rw [convergents_succ, ih (fract ξ)⁻¹, convergent_succ, one_div]
norm_cast
#align real.continued_fraction_convergent_eq_convergent Real.continued_fraction_convergent_eq_convergent
@@ -482,7 +482,7 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v :=
obtain ⟨hv₀, hv₀'⟩ := aux₀ (zero_lt_two.trans_le hv)
have hv₁ : 0 < 2 * v - 1 := by linarith only [hv]
rw [← one_div, lt_div_iff (mul_pos hv₀ hv₀'), ← abs_of_pos (mul_pos hv₀ hv₀'), ← abs_mul, sub_mul,
- ← mul_assoc, ← mul_assoc, div_mul_cancel _ hv₀.ne', abs_sub_comm, abs_lt, lt_sub_iff_add_lt,
+ ← mul_assoc, ← mul_assoc, div_mul_cancel₀ _ hv₀.ne', abs_sub_comm, abs_lt, lt_sub_iff_add_lt,
sub_lt_iff_lt_add, mul_assoc] at h
have hu₀ : 0 ≤ u - ⌊ξ⌋ * v :=
by
@@ -527,13 +527,13 @@ private theorem aux₃ :
have H₁ := div_pos (div_pos Hv Hu) hξ₀
replace h := h.2.2
have h' : |fract ξ - u' / v| < (v * (2 * v - 1))⁻¹ := by
- rwa [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm] at h
+ rwa [hu'ℝ, add_div, mul_div_cancel_right₀ _ Hv.ne', ← sub_sub, sub_right_comm] at h
have H : (2 * u' - 1 : ℝ) ≤ (2 * v - 1) * fract ξ :=
by
replace h := (abs_lt.mp h).1
have : (2 * (v : ℝ) - 1) * (-(v * (2 * v - 1))⁻¹ + u' / v) = 2 * u' - (1 + u') / v := by
field_simp [Hv.ne', Hv'.ne']; ring
- rw [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm, self_sub_floor,
+ rw [hu'ℝ, add_div, mul_div_cancel_right₀ _ Hv.ne', ← sub_sub, sub_right_comm, self_sub_floor,
lt_sub_iff_add_lt, ← mul_lt_mul_left Hv', this] at h
refine' LE.le.trans _ h.le
rw [sub_le_sub_iff_left, div_le_one Hv, add_comm]
@@ -617,7 +617,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h : ContfracLegendre.Ass ξ u v) :
use n + 1
rw [convergent_succ, ← hn,
(by exact_mod_cast to_nat_of_nonneg huv₀.le : ((u - ⌊ξ⌋ * v).toNat : ℚ) = u - ⌊ξ⌋ * v), ←
- coe_coe, inv_div, sub_div, mul_div_cancel _ Hv, add_sub_cancel'_right]
+ coe_coe, inv_div, sub_div, mul_div_cancel_right₀ _ Hv, add_sub_cancel]
#align real.exists_rat_eq_convergent' Real.exists_rat_eq_convergent'
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -119,7 +119,7 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
refine'
⟨le_sub_iff_add_le.mpr _, sub_le_iff_le_add.mpr <| le_of_lt <| (hfu m).trans <| lt_one_add _⟩
simpa only [neg_add_cancel_comm_assoc] using hf'
- · simp_rw [not_exists] at H
+ · simp_rw [not_exists] at H
have hD : (Ico (0 : ℤ) n).card < D.card := by rw [card_Icc, card_Ico]; exact lt_add_one n
have hfu' : ∀ m, f m ≤ n := fun m => lt_add_one_iff.mp (floor_lt.mpr (by exact_mod_cast hfu m))
have hwd : ∀ m : ℤ, m ∈ D → f m ∈ Ico (0 : ℤ) n := fun x hx =>
@@ -150,7 +150,7 @@ theorem exists_nat_abs_mul_sub_round_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
by
obtain ⟨j, k, hk₀, hk₁, h⟩ := exists_int_int_abs_mul_sub_le ξ n_pos
have hk := to_nat_of_nonneg hk₀.le
- rw [← hk] at hk₀ hk₁ h
+ rw [← hk] at hk₀ hk₁ h
exact ⟨k.to_nat, coe_nat_pos.mp hk₀, nat.cast_le.mp hk₁, (round_le (↑k.to_nat * ξ) j).trans h⟩
#align real.exists_nat_abs_mul_sub_round_le Real.exists_nat_abs_mul_sub_round_le
-/
@@ -252,15 +252,15 @@ theorem den_le_and_le_num_le_of_sub_lt_one_div_den_sq {ξ q : ℚ} (h : |ξ - q|
by
have hq₀ : (0 : ℚ) < q.denom := nat.cast_pos.mpr q.pos
replace h : |ξ * q.denom - q.num| < 1 / q.denom
- · rw [← mul_lt_mul_right hq₀] at h
+ · rw [← mul_lt_mul_right hq₀] at h
conv_lhs at h => rw [← abs_of_pos hq₀, ← abs_mul, sub_mul, mul_denom_eq_num]
- rwa [sq, div_mul, mul_div_cancel_left _ hq₀.ne'] at h
+ rwa [sq, div_mul, mul_div_cancel_left _ hq₀.ne'] at h
constructor
· rcases eq_or_ne ξ q with (rfl | H)
· exact le_rfl
· have hξ₀ : (0 : ℚ) < ξ.denom := nat.cast_pos.mpr ξ.pos
rw [← Rat.num_div_den ξ, div_mul_eq_mul_div, div_sub' _ _ _ hξ₀.ne', abs_div, abs_of_pos hξ₀,
- div_lt_iff hξ₀, div_mul_comm, mul_one] at h
+ div_lt_iff hξ₀, div_mul_comm, mul_one] at h
refine' nat.cast_le.mp ((one_lt_div hq₀).mp <| lt_of_le_of_lt _ h).le
norm_cast
rw [mul_comm _ q.num]
@@ -269,9 +269,9 @@ theorem den_le_and_le_num_le_of_sub_lt_one_div_den_sq {ξ q : ℚ} (h : |ξ - q|
abs_sub_lt_iff.mp
(h.trans_le <|
(one_div_le zero_lt_one hq₀).mp <| (@one_div_one ℚ _).symm ▸ nat.cast_le.mpr q.pos)
- rw [sub_lt_iff_lt_add, add_comm] at h₁ h₂
- rw [← sub_lt_iff_lt_add] at h₂
- norm_cast at h₁ h₂
+ rw [sub_lt_iff_lt_add, add_comm] at h₁ h₂
+ rw [← sub_lt_iff_lt_add] at h₂
+ norm_cast at h₁ h₂
exact
⟨sub_le_iff_le_add.mpr (int.ceil_le.mpr h₁.le), sub_le_iff_le_add.mp (int.le_floor.mpr h₂.le)⟩
#align rat.denom_le_and_le_num_le_of_sub_lt_one_div_denom_sq Rat.den_le_and_le_num_le_of_sub_lt_one_div_den_sq
@@ -286,12 +286,12 @@ theorem finite_rat_abs_sub_lt_one_div_den_sq (ξ : ℚ) : {q : ℚ | |ξ - q| <
set s := {q : ℚ | |ξ - q| < 1 / q.den ^ 2}
have hinj : Function.Injective f := by
intro a b hab
- simp only [Prod.mk.inj_iff] at hab
+ simp only [Prod.mk.inj_iff] at hab
rw [← Rat.num_div_den a, ← Rat.num_div_den b, hab.1, hab.2]
have H : f '' s ⊆ ⋃ (y : ℕ) (hy : y ∈ Ioc 0 ξ.denom), Icc (⌈ξ * y⌉ - 1) (⌊ξ * y⌋ + 1) ×ˢ {y} :=
by
intro xy hxy
- simp only [mem_image, mem_set_of_eq] at hxy
+ simp only [mem_image, mem_set_of_eq] at hxy
obtain ⟨q, hq₁, hq₂⟩ := hxy
obtain ⟨hd, hn⟩ := denom_le_and_le_num_le_of_sub_lt_one_div_denom_sq hq₁
simp_rw [mem_Union]
@@ -461,7 +461,7 @@ private theorem aux₁ : 0 < fract ξ :=
obtain ⟨hv₁, hv₂⟩ := aux₀ (zero_lt_two.trans_le hv)
obtain ⟨hcop, _, h⟩ := h
refine' fract_pos.mpr fun hf => _
- rw [hf] at h
+ rw [hf] at h
have H : (2 * v - 1 : ℝ) < 1 :=
by
refine'
@@ -472,7 +472,7 @@ private theorem aux₁ : 0 < fract ξ :=
rw [← zero_add (1 : ℤ), add_one_le_iff, abs_pos, sub_ne_zero]
rintro rfl
cases is_unit_iff.mp (is_coprime_self.mp (is_coprime.mul_left_iff.mp hcop).2) <;> linarith
- norm_cast at H
+ norm_cast at H
linarith only [hv, H]
-- An auxiliary lemma for the inductive step.
@@ -483,12 +483,12 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v :=
have hv₁ : 0 < 2 * v - 1 := by linarith only [hv]
rw [← one_div, lt_div_iff (mul_pos hv₀ hv₀'), ← abs_of_pos (mul_pos hv₀ hv₀'), ← abs_mul, sub_mul,
← mul_assoc, ← mul_assoc, div_mul_cancel _ hv₀.ne', abs_sub_comm, abs_lt, lt_sub_iff_add_lt,
- sub_lt_iff_lt_add, mul_assoc] at h
+ sub_lt_iff_lt_add, mul_assoc] at h
have hu₀ : 0 ≤ u - ⌊ξ⌋ * v :=
by
refine' (mul_nonneg_iff_of_pos_right hv₁).mp ((lt_iff_add_one_le (-1 : ℤ) _).mp _)
replace h := h.1
- rw [← lt_sub_iff_add_lt, ← mul_assoc, ← sub_mul] at h
+ rw [← lt_sub_iff_add_lt, ← mul_assoc, ← sub_mul] at h
exact_mod_cast
h.trans_le
((mul_le_mul_right <| hv₀').mpr <|
@@ -498,18 +498,18 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v :=
refine' le_of_mul_le_mul_right (le_of_lt_add_one _) hv₁
replace h := h.2
rw [← sub_lt_iff_lt_add, ← mul_assoc, ← sub_mul, ← add_lt_add_iff_right (v * (2 * v - 1) : ℝ),
- add_comm (1 : ℝ)] at h
+ add_comm (1 : ℝ)] at h
have :=
(mul_lt_mul_right <| hv₀').mpr
((sub_lt_sub_iff_left (u : ℝ)).mpr <|
(mul_lt_mul_right hv₀).mpr <| sub_right_lt_of_lt_add <| lt_floor_add_one ξ)
- rw [sub_mul ξ, one_mul, ← sub_add, add_mul] at this
+ rw [sub_mul ξ, one_mul, ← sub_add, add_mul] at this
exact_mod_cast this.trans h
have huv_cop : IsCoprime (u - ⌊ξ⌋ * v) v := by
rwa [sub_eq_add_neg, ← neg_mul, IsCoprime.add_mul_right_left_iff]
refine' ⟨lt_of_le_of_ne' hu₀ fun hf => _, lt_of_le_of_ne hu₁ fun hf => _⟩ <;>
- · rw [hf] at huv_cop
- simp only [isCoprime_zero_left, isCoprime_self, is_unit_iff] at huv_cop
+ · rw [hf] at huv_cop
+ simp only [isCoprime_zero_left, isCoprime_self, is_unit_iff] at huv_cop
cases huv_cop <;> linarith only [hv, huv_cop]
-- The key step: the relevant inequality persists in the inductive step.
@@ -527,14 +527,14 @@ private theorem aux₃ :
have H₁ := div_pos (div_pos Hv Hu) hξ₀
replace h := h.2.2
have h' : |fract ξ - u' / v| < (v * (2 * v - 1))⁻¹ := by
- rwa [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm] at h
+ rwa [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm] at h
have H : (2 * u' - 1 : ℝ) ≤ (2 * v - 1) * fract ξ :=
by
replace h := (abs_lt.mp h).1
have : (2 * (v : ℝ) - 1) * (-(v * (2 * v - 1))⁻¹ + u' / v) = 2 * u' - (1 + u') / v := by
field_simp [Hv.ne', Hv'.ne']; ring
rw [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm, self_sub_floor,
- lt_sub_iff_add_lt, ← mul_lt_mul_left Hv', this] at h
+ lt_sub_iff_add_lt, ← mul_lt_mul_left Hv', this] at h
refine' LE.le.trans _ h.le
rw [sub_le_sub_iff_left, div_le_one Hv, add_comm]
exact_mod_cast huv
@@ -564,7 +564,7 @@ private theorem invariant : ContfracLegendre.Ass (fract ξ)⁻¹ v (u - ⌊ξ⌋
ring
have Huv : (u / v : ℝ) = ⌊ξ⌋ + v⁻¹ := by rw [sub_eq_iff_eq_add'.mp huv]; field_simp [hv₀.ne']
have h' := (abs_sub_lt_iff.mp h.2.2).1
- rw [Huv, ← sub_sub, sub_lt_iff_lt_add, self_sub_floor, Hv] at h'
+ rw [Huv, ← sub_sub, sub_lt_iff_lt_add, self_sub_floor, Hv] at h'
rwa [lt_sub_iff_add_lt', (by ring : (v : ℝ) + -(1 / 2) = (2 * v - 1) / 2),
lt_inv (div_pos hv₀' zero_lt_two) (aux₁ hv h), inv_div]
@@ -582,7 +582,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h : ContfracLegendre.Ass ξ u v) :
rcases lt_trichotomy v 1 with (ht | rfl | ht)
· replace h := h.2.2
simp only [nat.lt_one_iff.mp ht, Nat.cast_zero, div_zero, tsub_zero, MulZeroClass.zero_mul,
- cast_zero, inv_zero] at h
+ cast_zero, inv_zero] at h
exact False.elim (lt_irrefl _ <| (abs_nonneg ξ).trans_lt h)
· rw [Nat.cast_one, div_one]
obtain ⟨_, h₁, h₂⟩ := h
@@ -596,7 +596,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h : ContfracLegendre.Ass ξ u v) :
rw [floor_eq_iff, cast_sub, cast_one, sub_add_cancel]
exact ⟨(((sub_lt_sub_iff_left _).mpr one_half_lt_one).trans h₁).le, ht⟩
cases' eq_or_ne ξ ⌊ξ⌋ with Hξ Hξ
- · rw [Hξ, hξ₁, cast_sub, cast_one, ← sub_eq_add_neg, sub_lt_sub_iff_left] at h₁
+ · rw [Hξ, hξ₁, cast_sub, cast_one, ← sub_eq_add_neg, sub_lt_sub_iff_left] at h₁
exact False.elim (lt_irrefl _ <| h₁.trans one_half_lt_one)
· have hξ₂ : ⌊(fract ξ)⁻¹⌋ = 1 :=
by
@@ -631,7 +631,7 @@ theorem exists_rat_eq_convergent {q : ℚ} (h : |ξ - q| < 1 / (2 * q.den ^ 2))
by
refine' q.num_div_denom ▸ exists_rat_eq_convergent' ⟨_, fun hd => _, _⟩
· exact coprime_iff_nat_coprime.mpr (nat_abs_of_nat q.denom ▸ q.cop)
- · rw [← q.denom_eq_one_iff.mp (nat.cast_eq_one.mp hd)] at h
+ · rw [← q.denom_eq_one_iff.mp (nat.cast_eq_one.mp hd)] at h
simpa only [Rat.coe_int_den, Nat.cast_one, one_pow, mul_one] using (abs_lt.mp h).1
· obtain ⟨hq₀, hq₁⟩ := aux₀ (nat.cast_pos.mpr q.pos)
replace hq₁ := mul_pos hq₀ hq₁
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -486,7 +486,7 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v :=
sub_lt_iff_lt_add, mul_assoc] at h
have hu₀ : 0 ≤ u - ⌊ξ⌋ * v :=
by
- refine' (zero_le_mul_right hv₁).mp ((lt_iff_add_one_le (-1 : ℤ) _).mp _)
+ refine' (mul_nonneg_iff_of_pos_right hv₁).mp ((lt_iff_add_one_le (-1 : ℤ) _).mp _)
replace h := h.1
rw [← lt_sub_iff_add_lt, ← mul_assoc, ← sub_mul] at h
exact_mod_cast
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -135,7 +135,7 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
⟨⌊ξ * y⌋ - ⌊ξ * x⌋, y - x, sub_pos_of_lt x_lt_y,
sub_le_iff_le_add.mpr <| le_add_of_le_of_nonneg (mem_Icc.mp hy).2 (mem_Icc.mp hx).1, _⟩
convert_to |fract (ξ * y) * (n + 1) - fract (ξ * x) * (n + 1)| ≤ 1
- · congr; push_cast ; simp only [fract]; ring
+ · congr; push_cast; simp only [fract]; ring
exact (abs_sub_lt_one_of_floor_eq_floor hxy.symm).le
#align real.exists_int_int_abs_mul_sub_le Real.exists_int_int_abs_mul_sub_le
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,13 +3,13 @@ Copyright (c) 2022 Michael Stoll. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Michael Geißer, Michael Stoll
-/
-import Mathbin.Algebra.ContinuedFractions.Computation.ApproximationCorollaries
-import Mathbin.Algebra.ContinuedFractions.Computation.Translations
-import Mathbin.Combinatorics.Pigeonhole
-import Mathbin.Data.Int.Units
-import Mathbin.Data.Real.Irrational
-import Mathbin.RingTheory.Coprime.Lemmas
-import Mathbin.Tactic.Basic
+import Algebra.ContinuedFractions.Computation.ApproximationCorollaries
+import Algebra.ContinuedFractions.Computation.Translations
+import Combinatorics.Pigeonhole
+import Data.Int.Units
+import Data.Real.Irrational
+import RingTheory.Coprime.Lemmas
+import Tactic.Basic
#align_import number_theory.diophantine_approximation from "leanprover-community/mathlib"@"2a0ce625dbb0ffbc7d1316597de0b25c1ec75303"
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,11 +2,6 @@
Copyright (c) 2022 Michael Stoll. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Michael Geißer, Michael Stoll
-
-! This file was ported from Lean 3 source module number_theory.diophantine_approximation
-! leanprover-community/mathlib commit 2a0ce625dbb0ffbc7d1316597de0b25c1ec75303
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.Algebra.ContinuedFractions.Computation.ApproximationCorollaries
import Mathbin.Algebra.ContinuedFractions.Computation.Translations
@@ -16,6 +11,8 @@ import Mathbin.Data.Real.Irrational
import Mathbin.RingTheory.Coprime.Lemmas
import Mathbin.Tactic.Basic
+#align_import number_theory.diophantine_approximation from "leanprover-community/mathlib"@"2a0ce625dbb0ffbc7d1316597de0b25c1ec75303"
+
/-!
# Diophantine Approximation
mathlib commit https://github.com/leanprover-community/mathlib/commit/2a0ce625dbb0ffbc7d1316597de0b25c1ec75303
@@ -93,6 +93,7 @@ such that `q.denom ≤ n` and `|ξ - q| ≤ 1/((n+1)*q.denom)`.
open Finset Int
+#print Real.exists_int_int_abs_mul_sub_le /-
/-- *Dirichlet's approximation theorem:*
For any real number `ξ` and positive natural `n`, there are integers `j` and `k`,
with `0 < k ≤ n` and `|k*ξ - j| ≤ 1/(n+1)`.
@@ -140,7 +141,9 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
· congr; push_cast ; simp only [fract]; ring
exact (abs_sub_lt_one_of_floor_eq_floor hxy.symm).le
#align real.exists_int_int_abs_mul_sub_le Real.exists_int_int_abs_mul_sub_le
+-/
+#print Real.exists_nat_abs_mul_sub_round_le /-
/-- *Dirichlet's approximation theorem:*
For any real number `ξ` and positive natural `n`, there is a natural number `k`,
with `0 < k ≤ n` such that `|k*ξ - round(k*ξ)| ≤ 1/(n+1)`.
@@ -153,7 +156,9 @@ theorem exists_nat_abs_mul_sub_round_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
rw [← hk] at hk₀ hk₁ h
exact ⟨k.to_nat, coe_nat_pos.mp hk₀, nat.cast_le.mp hk₁, (round_le (↑k.to_nat * ξ) j).trans h⟩
#align real.exists_nat_abs_mul_sub_round_le Real.exists_nat_abs_mul_sub_round_le
+-/
+#print Real.exists_rat_abs_sub_le_and_den_le /-
/-- *Dirichlet's approximation theorem:*
For any real number `ξ` and positive natural `n`, there is a fraction `q`
such that `q.denom ≤ n` and `|ξ - q| ≤ 1/((n+1)*q.denom)`. -/
@@ -170,6 +175,7 @@ theorem exists_rat_abs_sub_le_and_den_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
rwa [← abs_of_pos hk₀', Rat.cast_div, Rat.cast_coe_int, Rat.cast_coe_int, ← abs_mul, sub_mul,
div_mul_cancel _ hk₀'.ne', mul_comm]
#align real.exists_rat_abs_sub_le_and_denom_le Real.exists_rat_abs_sub_le_and_den_le
+-/
end Dirichlet
@@ -185,6 +191,7 @@ i.e., fractions `x/y` in lowest terms such that `|ξ - x/y| < 1/y^2`.
open Set
+#print Real.exists_rat_abs_sub_lt_and_lt_of_irrational /-
/-- Given any rational approximation `q` to the irrational real number `ξ`, there is
a good rational approximation `q'` such that `|ξ - q'| < |ξ - q|`. -/
theorem exists_rat_abs_sub_lt_and_lt_of_irrational {ξ : ℝ} (hξ : Irrational ξ) (q : ℚ) :
@@ -207,7 +214,9 @@ theorem exists_rat_abs_sub_lt_and_lt_of_irrational {ξ : ℝ} (hξ : Irrational
rw [sq, one_div_lt_one_div md_pos (mul_pos den_pos den_pos), mul_lt_mul_right den_pos]
exact lt_add_of_le_of_pos (nat.cast_le.mpr hden) zero_lt_one
#align real.exists_rat_abs_sub_lt_and_lt_of_irrational Real.exists_rat_abs_sub_lt_and_lt_of_irrational
+-/
+#print Real.infinite_rat_abs_sub_lt_one_div_den_sq_of_irrational /-
/-- If `ξ` is an irrational real number, then there are infinitely many good
rational approximations to `ξ`. -/
theorem infinite_rat_abs_sub_lt_one_div_den_sq_of_irrational {ξ : ℝ} (hξ : Irrational ξ) :
@@ -220,6 +229,7 @@ theorem infinite_rat_abs_sub_lt_one_div_den_sq_of_irrational {ξ : ℝ} (hξ : I
obtain ⟨q', hmem, hbetter⟩ := exists_rat_abs_sub_lt_and_lt_of_irrational hξ q
exact lt_irrefl _ (lt_of_le_of_lt (hq q' hmem) hbetter)
#align real.infinite_rat_abs_sub_lt_one_div_denom_sq_of_irrational Real.infinite_rat_abs_sub_lt_one_div_den_sq_of_irrational
+-/
end RatApprox
@@ -237,6 +247,7 @@ approximations.
open Set
+#print Rat.den_le_and_le_num_le_of_sub_lt_one_div_den_sq /-
/-- If `ξ` is rational, then the good rational approximations to `ξ` have bounded
numerator and denominator. -/
theorem den_le_and_le_num_le_of_sub_lt_one_div_den_sq {ξ q : ℚ} (h : |ξ - q| < 1 / q.den ^ 2) :
@@ -267,8 +278,10 @@ theorem den_le_and_le_num_le_of_sub_lt_one_div_den_sq {ξ q : ℚ} (h : |ξ - q|
exact
⟨sub_le_iff_le_add.mpr (int.ceil_le.mpr h₁.le), sub_le_iff_le_add.mp (int.le_floor.mpr h₂.le)⟩
#align rat.denom_le_and_le_num_le_of_sub_lt_one_div_denom_sq Rat.den_le_and_le_num_le_of_sub_lt_one_div_den_sq
+-/
/- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Rat.finite_rat_abs_sub_lt_one_div_den_sq /-
/-- A rational number has only finitely many good rational approximations. -/
theorem finite_rat_abs_sub_lt_one_div_den_sq (ξ : ℚ) : {q : ℚ | |ξ - q| < 1 / q.den ^ 2}.Finite :=
by
@@ -291,9 +304,11 @@ theorem finite_rat_abs_sub_lt_one_div_den_sq (ξ : ℚ) : {q : ℚ | |ξ - q| <
refine' finite.of_finite_image (finite.subset _ H) (inj_on_of_injective hinj s)
exact finite.bUnion (finite_Ioc _ _) fun x hx => finite.prod (finite_Icc _ _) (finite_singleton _)
#align rat.finite_rat_abs_sub_lt_one_div_denom_sq Rat.finite_rat_abs_sub_lt_one_div_den_sq
+-/
end Rat
+#print Real.infinite_rat_abs_sub_lt_one_div_den_sq_iff_irrational /-
/-- The set of good rational approximations to a real number `ξ` is infinite if and only if
`ξ` is irrational. -/
theorem Real.infinite_rat_abs_sub_lt_one_div_den_sq_iff_irrational (ξ : ℝ) :
@@ -307,6 +322,7 @@ theorem Real.infinite_rat_abs_sub_lt_one_div_den_sq_iff_irrational (ξ : ℝ) :
rw [H, (by push_cast : (1 : ℝ) / q.denom ^ 2 = (1 / q.denom ^ 2 : ℚ))]
norm_cast
#align real.infinite_rat_abs_sub_lt_one_div_denom_sq_iff_irrational Real.infinite_rat_abs_sub_lt_one_div_den_sq_iff_irrational
+-/
/-!
### Legendre's Theorem on Rational Approximation
@@ -334,6 +350,7 @@ open Int
-/
+#print Real.convergent /-
/-- We give a direct recursive definition of the convergents of the continued fraction
expansion of a real number `ξ`. The main reason for that is that we want to have the
convergents as rational numbers; the versions
@@ -349,19 +366,25 @@ noncomputable def convergent : ℝ → ℕ → ℚ
| ξ, 0 => ⌊ξ⌋
| ξ, n + 1 => ⌊ξ⌋ + (convergent (fract ξ)⁻¹ n)⁻¹
#align real.convergent Real.convergent
+-/
+#print Real.convergent_zero /-
/-- The zeroth convergent of `ξ` is `⌊ξ⌋`. -/
@[simp]
theorem convergent_zero (ξ : ℝ) : ξ.convergent 0 = ⌊ξ⌋ :=
rfl
#align real.convergent_zero Real.convergent_zero
+-/
+#print Real.convergent_succ /-
/-- The `(n+1)`th convergent of `ξ` is the `n`th convergent of `1/(fract ξ)`. -/
@[simp]
theorem convergent_succ (ξ : ℝ) (n : ℕ) :
ξ.convergent (n + 1) = ⌊ξ⌋ + ((fract ξ)⁻¹.convergent n)⁻¹ := by simp only [convergent]
#align real.convergent_succ Real.convergent_succ
+-/
+#print Real.convergent_of_zero /-
/-- All convergents of `0` are zero. -/
@[simp]
theorem convergent_of_zero (n : ℕ) : convergent 0 n = 0 :=
@@ -370,7 +393,9 @@ theorem convergent_of_zero (n : ℕ) : convergent 0 n = 0 :=
· simp only [convergent_zero, floor_zero, cast_zero]
· simp only [ih, convergent_succ, floor_zero, cast_zero, fract_zero, add_zero, inv_zero]
#align real.convergent_of_zero Real.convergent_of_zero
+-/
+#print Real.convergent_of_int /-
/-- If `ξ` is an integer, all its convergents equal `ξ`. -/
@[simp]
theorem convergent_of_int {ξ : ℤ} (n : ℕ) : convergent ξ n = ξ :=
@@ -381,6 +406,7 @@ theorem convergent_of_int {ξ : ℤ} (n : ℕ) : convergent ξ n = ξ :=
simp only [convergent_succ, floor_int_cast, fract_int_cast, convergent_of_zero, add_zero,
inv_zero]
#align real.convergent_of_int Real.convergent_of_int
+-/
/-!
Our `convergent`s agree with `generalized_continued_fraction.convergents`.
@@ -389,6 +415,7 @@ Our `convergent`s agree with `generalized_continued_fraction.convergents`.
open GeneralizedContinuedFraction
+#print Real.continued_fraction_convergent_eq_convergent /-
/-- The `n`th convergent of the `generalized_continued_fraction.of ξ`
agrees with `ξ.convergent n`. -/
theorem continued_fraction_convergent_eq_convergent (ξ : ℝ) (n : ℕ) :
@@ -399,6 +426,7 @@ theorem continued_fraction_convergent_eq_convergent (ξ : ℝ) (n : ℕ) :
· rw [convergents_succ, ih (fract ξ)⁻¹, convergent_succ, one_div]
norm_cast
#align real.continued_fraction_convergent_eq_convergent Real.continued_fraction_convergent_eq_convergent
+-/
end Real
@@ -413,11 +441,13 @@ namespace Real
open Int
+#print Real.ContfracLegendre.Ass /-
-- this is not `private`, as it is used in the public `exists_rat_eq_convergent'` below.
/-- Define the technical condition to be used as assumption in the inductive proof. -/
def ContfracLegendre.Ass (ξ : ℝ) (u v : ℤ) : Prop :=
IsCoprime u v ∧ (v = 1 → (-(1 / 2) : ℝ) < ξ - u) ∧ |ξ - u / v| < (v * (2 * v - 1))⁻¹
#align real.contfrac_legendre.ass Real.ContfracLegendre.Ass
+-/
-- ### Auxiliary lemmas
-- This saves a few lines below, as it is frequently needed.
@@ -546,6 +576,7 @@ private theorem invariant : ContfracLegendre.Ass (fract ξ)⁻¹ v (u - ⌊ξ⌋
-/
+#print Real.exists_rat_eq_convergent' /-
/-- The technical version of *Legendre's Theorem*. -/
theorem exists_rat_eq_convergent' {v : ℕ} (h : ContfracLegendre.Ass ξ u v) :
∃ n, (u / v : ℚ) = ξ.convergent n :=
@@ -591,7 +622,9 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h : ContfracLegendre.Ass ξ u v) :
(by exact_mod_cast to_nat_of_nonneg huv₀.le : ((u - ⌊ξ⌋ * v).toNat : ℚ) = u - ⌊ξ⌋ * v), ←
coe_coe, inv_div, sub_div, mul_div_cancel _ Hv, add_sub_cancel'_right]
#align real.exists_rat_eq_convergent' Real.exists_rat_eq_convergent'
+-/
+#print Real.exists_rat_eq_convergent /-
/-- The main result, *Legendre's Theorem* on rational approximation:
if `ξ` is a real number and `q` is a rational number such that `|ξ - q| < 1/(2*q.denom^2)`,
then `q` is a convergent of the continued fraction expansion of `ξ`.
@@ -610,7 +643,9 @@ theorem exists_rat_eq_convergent {q : ℚ} (h : |ξ - q| < 1 / (2 * q.den ^ 2))
rw [(by norm_cast : (q.num / q.denom : ℝ) = (q.num / q.denom : ℚ)), Rat.num_div_den]
exact h.trans (by rw [← one_div, sq, one_div_lt_one_div hq₂ hq₁, ← sub_pos]; ring_nf; exact hq₀)
#align real.exists_rat_eq_convergent Real.exists_rat_eq_convergent
+-/
+#print Real.exists_continued_fraction_convergent_eq_rat /-
/-- The main result, *Legendre's Theorem* on rational approximation:
if `ξ` is a real number and `q` is a rational number such that `|ξ - q| < 1/(2*q.denom^2)`,
then `q` is a convergent of the continued fraction expansion of `ξ`.
@@ -621,6 +656,7 @@ theorem exists_continued_fraction_convergent_eq_rat {q : ℚ} (h : |ξ - q| < 1
obtain ⟨n, hn⟩ := exists_rat_eq_convergent h
exact ⟨n, hn.symm ▸ continued_fraction_convergent_eq_convergent ξ n⟩
#align real.exists_continued_fraction_convergent_eq_rat Real.exists_continued_fraction_convergent_eq_rat
+-/
end Real
mathlib commit https://github.com/leanprover-community/mathlib/commit/2a0ce625dbb0ffbc7d1316597de0b25c1ec75303
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Michael Geißer, Michael Stoll
! This file was ported from Lean 3 source module number_theory.diophantine_approximation
-! leanprover-community/mathlib commit e25a317463bd37d88e33da164465d8c47922b1cd
+! leanprover-community/mathlib commit 2a0ce625dbb0ffbc7d1316597de0b25c1ec75303
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -19,6 +19,9 @@ import Mathbin.Tactic.Basic
/-!
# Diophantine Approximation
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
The first part of this file gives proofs of various versions of
**Dirichlet's approximation theorem** and its important consequence that when $\xi$ is an
irrational real number, then there are infinitely many rationals $x/y$ (in lowest terms)
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -424,8 +424,6 @@ private theorem aux₀ {v : ℤ} (hv : 0 < v) : (0 : ℝ) < v ∧ (0 : ℝ) < 2
-- In the following, we assume that `ass ξ u v` holds and `v ≥ 2`.
variable {ξ : ℝ} {u v : ℤ} (hv : 2 ≤ v) (h : ContfracLegendre.Ass ξ u v)
-include hv h
-
-- The fractional part of `ξ` is positive.
private theorem aux₁ : 0 < fract ξ :=
by
@@ -540,8 +538,6 @@ private theorem invariant : ContfracLegendre.Ass (fract ξ)⁻¹ v (u - ⌊ξ⌋
rwa [lt_sub_iff_add_lt', (by ring : (v : ℝ) + -(1 / 2) = (2 * v - 1) / 2),
lt_inv (div_pos hv₀' zero_lt_two) (aux₁ hv h), inv_div]
-omit h hv
-
/-!
### The main result
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/7e5137f579de09a059a5ce98f364a04e221aabf0
@@ -524,7 +524,6 @@ private theorem aux₃ :
_ ≤ (u' * (2 * u' - 1))⁻¹ := by
rwa [inv_le_inv (mul_pos (mul_pos Hu Hv') hξ₀) <| mul_pos Hu Hu', mul_assoc,
mul_le_mul_left Hu]
-
-- The conditions `ass ξ u v` persist in the inductive step.
private theorem invariant : ContfracLegendre.Ass (fract ξ)⁻¹ v (u - ⌊ξ⌋ * v) :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -133,7 +133,7 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
refine'
⟨⌊ξ * y⌋ - ⌊ξ * x⌋, y - x, sub_pos_of_lt x_lt_y,
sub_le_iff_le_add.mpr <| le_add_of_le_of_nonneg (mem_Icc.mp hy).2 (mem_Icc.mp hx).1, _⟩
- convert_to|fract (ξ * y) * (n + 1) - fract (ξ * x) * (n + 1)| ≤ 1
+ convert_to |fract (ξ * y) * (n + 1) - fract (ξ * x) * (n + 1)| ≤ 1
· congr; push_cast ; simp only [fract]; ring
exact (abs_sub_lt_one_of_floor_eq_floor hxy.symm).le
#align real.exists_int_int_abs_mul_sub_le Real.exists_int_int_abs_mul_sub_le
@@ -208,11 +208,11 @@ theorem exists_rat_abs_sub_lt_and_lt_of_irrational {ξ : ℝ} (hξ : Irrational
/-- If `ξ` is an irrational real number, then there are infinitely many good
rational approximations to `ξ`. -/
theorem infinite_rat_abs_sub_lt_one_div_den_sq_of_irrational {ξ : ℝ} (hξ : Irrational ξ) :
- { q : ℚ | |ξ - q| < 1 / q.den ^ 2 }.Infinite :=
+ {q : ℚ | |ξ - q| < 1 / q.den ^ 2}.Infinite :=
by
refine' Or.resolve_left (Set.finite_or_infinite _) fun h => _
obtain ⟨q, _, hq⟩ :=
- exists_min_image { q : ℚ | |ξ - q| < 1 / q.den ^ 2 } (fun q => |ξ - q|) h
+ exists_min_image {q : ℚ | |ξ - q| < 1 / q.den ^ 2} (fun q => |ξ - q|) h
⟨⌊ξ⌋, by simp [abs_of_nonneg, Int.fract_lt_one]⟩
obtain ⟨q', hmem, hbetter⟩ := exists_rat_abs_sub_lt_and_lt_of_irrational hξ q
exact lt_irrefl _ (lt_of_le_of_lt (hq q' hmem) hbetter)
@@ -260,17 +260,17 @@ theorem den_le_and_le_num_le_of_sub_lt_one_div_den_sq {ξ q : ℚ} (h : |ξ - q|
(one_div_le zero_lt_one hq₀).mp <| (@one_div_one ℚ _).symm ▸ nat.cast_le.mpr q.pos)
rw [sub_lt_iff_lt_add, add_comm] at h₁ h₂
rw [← sub_lt_iff_lt_add] at h₂
- norm_cast at h₁ h₂
+ norm_cast at h₁ h₂
exact
⟨sub_le_iff_le_add.mpr (int.ceil_le.mpr h₁.le), sub_le_iff_le_add.mp (int.le_floor.mpr h₂.le)⟩
#align rat.denom_le_and_le_num_le_of_sub_lt_one_div_denom_sq Rat.den_le_and_le_num_le_of_sub_lt_one_div_den_sq
/- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
/-- A rational number has only finitely many good rational approximations. -/
-theorem finite_rat_abs_sub_lt_one_div_den_sq (ξ : ℚ) : { q : ℚ | |ξ - q| < 1 / q.den ^ 2 }.Finite :=
+theorem finite_rat_abs_sub_lt_one_div_den_sq (ξ : ℚ) : {q : ℚ | |ξ - q| < 1 / q.den ^ 2}.Finite :=
by
let f : ℚ → ℤ × ℕ := fun q => (q.num, q.den)
- set s := { q : ℚ | |ξ - q| < 1 / q.den ^ 2 }
+ set s := {q : ℚ | |ξ - q| < 1 / q.den ^ 2}
have hinj : Function.Injective f := by
intro a b hab
simp only [Prod.mk.inj_iff] at hab
@@ -294,7 +294,7 @@ end Rat
/-- The set of good rational approximations to a real number `ξ` is infinite if and only if
`ξ` is irrational. -/
theorem Real.infinite_rat_abs_sub_lt_one_div_den_sq_iff_irrational (ξ : ℝ) :
- { q : ℚ | |ξ - q| < 1 / q.den ^ 2 }.Infinite ↔ Irrational ξ :=
+ {q : ℚ | |ξ - q| < 1 / q.den ^ 2}.Infinite ↔ Irrational ξ :=
by
refine'
⟨fun h => (irrational_iff_ne_rational ξ).mpr fun a b H => set.not_infinite.mpr _ h,
@@ -444,7 +444,7 @@ private theorem aux₁ : 0 < fract ξ :=
rw [← zero_add (1 : ℤ), add_one_le_iff, abs_pos, sub_ne_zero]
rintro rfl
cases is_unit_iff.mp (is_coprime_self.mp (is_coprime.mul_left_iff.mp hcop).2) <;> linarith
- norm_cast at H
+ norm_cast at H
linarith only [hv, H]
-- An auxiliary lemma for the inductive step.
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -118,23 +118,23 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
refine'
⟨le_sub_iff_add_le.mpr _, sub_le_iff_le_add.mpr <| le_of_lt <| (hfu m).trans <| lt_one_add _⟩
simpa only [neg_add_cancel_comm_assoc] using hf'
- · simp_rw [not_exists] at H
+ · simp_rw [not_exists] at H
have hD : (Ico (0 : ℤ) n).card < D.card := by rw [card_Icc, card_Ico]; exact lt_add_one n
have hfu' : ∀ m, f m ≤ n := fun m => lt_add_one_iff.mp (floor_lt.mpr (by exact_mod_cast hfu m))
have hwd : ∀ m : ℤ, m ∈ D → f m ∈ Ico (0 : ℤ) n := fun x hx =>
mem_Ico.mpr
⟨floor_nonneg.mpr (mul_nonneg (fract_nonneg (ξ * x)) hn.le), Ne.lt_of_le (H x hx) (hfu' x)⟩
- have : ∃ (x : ℤ)(hx : x ∈ D)(y : ℤ)(hy : y ∈ D), x < y ∧ f x = f y :=
+ have : ∃ (x : ℤ) (hx : x ∈ D) (y : ℤ) (hy : y ∈ D), x < y ∧ f x = f y :=
by
obtain ⟨x, hx, y, hy, x_ne_y, hxy⟩ := exists_ne_map_eq_of_card_lt_of_maps_to hD hwd
rcases lt_trichotomy x y with (h | h | h)
- exacts[⟨x, hx, y, hy, h, hxy⟩, False.elim (x_ne_y h), ⟨y, hy, x, hx, h, hxy.symm⟩]
+ exacts [⟨x, hx, y, hy, h, hxy⟩, False.elim (x_ne_y h), ⟨y, hy, x, hx, h, hxy.symm⟩]
obtain ⟨x, hx, y, hy, x_lt_y, hxy⟩ := this
refine'
⟨⌊ξ * y⌋ - ⌊ξ * x⌋, y - x, sub_pos_of_lt x_lt_y,
sub_le_iff_le_add.mpr <| le_add_of_le_of_nonneg (mem_Icc.mp hy).2 (mem_Icc.mp hx).1, _⟩
convert_to|fract (ξ * y) * (n + 1) - fract (ξ * x) * (n + 1)| ≤ 1
- · congr ; push_cast ; simp only [fract]; ring
+ · congr; push_cast ; simp only [fract]; ring
exact (abs_sub_lt_one_of_floor_eq_floor hxy.symm).le
#align real.exists_int_int_abs_mul_sub_le Real.exists_int_int_abs_mul_sub_le
@@ -147,7 +147,7 @@ theorem exists_nat_abs_mul_sub_round_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
by
obtain ⟨j, k, hk₀, hk₁, h⟩ := exists_int_int_abs_mul_sub_le ξ n_pos
have hk := to_nat_of_nonneg hk₀.le
- rw [← hk] at hk₀ hk₁ h
+ rw [← hk] at hk₀ hk₁ h
exact ⟨k.to_nat, coe_nat_pos.mp hk₀, nat.cast_le.mp hk₁, (round_le (↑k.to_nat * ξ) j).trans h⟩
#align real.exists_nat_abs_mul_sub_round_le Real.exists_nat_abs_mul_sub_round_le
@@ -241,15 +241,15 @@ theorem den_le_and_le_num_le_of_sub_lt_one_div_den_sq {ξ q : ℚ} (h : |ξ - q|
by
have hq₀ : (0 : ℚ) < q.denom := nat.cast_pos.mpr q.pos
replace h : |ξ * q.denom - q.num| < 1 / q.denom
- · rw [← mul_lt_mul_right hq₀] at h
+ · rw [← mul_lt_mul_right hq₀] at h
conv_lhs at h => rw [← abs_of_pos hq₀, ← abs_mul, sub_mul, mul_denom_eq_num]
- rwa [sq, div_mul, mul_div_cancel_left _ hq₀.ne'] at h
+ rwa [sq, div_mul, mul_div_cancel_left _ hq₀.ne'] at h
constructor
· rcases eq_or_ne ξ q with (rfl | H)
· exact le_rfl
· have hξ₀ : (0 : ℚ) < ξ.denom := nat.cast_pos.mpr ξ.pos
rw [← Rat.num_div_den ξ, div_mul_eq_mul_div, div_sub' _ _ _ hξ₀.ne', abs_div, abs_of_pos hξ₀,
- div_lt_iff hξ₀, div_mul_comm, mul_one] at h
+ div_lt_iff hξ₀, div_mul_comm, mul_one] at h
refine' nat.cast_le.mp ((one_lt_div hq₀).mp <| lt_of_le_of_lt _ h).le
norm_cast
rw [mul_comm _ q.num]
@@ -258,9 +258,9 @@ theorem den_le_and_le_num_le_of_sub_lt_one_div_den_sq {ξ q : ℚ} (h : |ξ - q|
abs_sub_lt_iff.mp
(h.trans_le <|
(one_div_le zero_lt_one hq₀).mp <| (@one_div_one ℚ _).symm ▸ nat.cast_le.mpr q.pos)
- rw [sub_lt_iff_lt_add, add_comm] at h₁ h₂
- rw [← sub_lt_iff_lt_add] at h₂
- norm_cast at h₁ h₂
+ rw [sub_lt_iff_lt_add, add_comm] at h₁ h₂
+ rw [← sub_lt_iff_lt_add] at h₂
+ norm_cast at h₁ h₂
exact
⟨sub_le_iff_le_add.mpr (int.ceil_le.mpr h₁.le), sub_le_iff_le_add.mp (int.le_floor.mpr h₂.le)⟩
#align rat.denom_le_and_le_num_le_of_sub_lt_one_div_denom_sq Rat.den_le_and_le_num_le_of_sub_lt_one_div_den_sq
@@ -273,12 +273,12 @@ theorem finite_rat_abs_sub_lt_one_div_den_sq (ξ : ℚ) : { q : ℚ | |ξ - q| <
set s := { q : ℚ | |ξ - q| < 1 / q.den ^ 2 }
have hinj : Function.Injective f := by
intro a b hab
- simp only [Prod.mk.inj_iff] at hab
+ simp only [Prod.mk.inj_iff] at hab
rw [← Rat.num_div_den a, ← Rat.num_div_den b, hab.1, hab.2]
have H : f '' s ⊆ ⋃ (y : ℕ) (hy : y ∈ Ioc 0 ξ.denom), Icc (⌈ξ * y⌉ - 1) (⌊ξ * y⌋ + 1) ×ˢ {y} :=
by
intro xy hxy
- simp only [mem_image, mem_set_of_eq] at hxy
+ simp only [mem_image, mem_set_of_eq] at hxy
obtain ⟨q, hq₁, hq₂⟩ := hxy
obtain ⟨hd, hn⟩ := denom_le_and_le_num_le_of_sub_lt_one_div_denom_sq hq₁
simp_rw [mem_Union]
@@ -433,7 +433,7 @@ private theorem aux₁ : 0 < fract ξ :=
obtain ⟨hv₁, hv₂⟩ := aux₀ (zero_lt_two.trans_le hv)
obtain ⟨hcop, _, h⟩ := h
refine' fract_pos.mpr fun hf => _
- rw [hf] at h
+ rw [hf] at h
have H : (2 * v - 1 : ℝ) < 1 :=
by
refine'
@@ -444,7 +444,7 @@ private theorem aux₁ : 0 < fract ξ :=
rw [← zero_add (1 : ℤ), add_one_le_iff, abs_pos, sub_ne_zero]
rintro rfl
cases is_unit_iff.mp (is_coprime_self.mp (is_coprime.mul_left_iff.mp hcop).2) <;> linarith
- norm_cast at H
+ norm_cast at H
linarith only [hv, H]
-- An auxiliary lemma for the inductive step.
@@ -455,12 +455,12 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v :=
have hv₁ : 0 < 2 * v - 1 := by linarith only [hv]
rw [← one_div, lt_div_iff (mul_pos hv₀ hv₀'), ← abs_of_pos (mul_pos hv₀ hv₀'), ← abs_mul, sub_mul,
← mul_assoc, ← mul_assoc, div_mul_cancel _ hv₀.ne', abs_sub_comm, abs_lt, lt_sub_iff_add_lt,
- sub_lt_iff_lt_add, mul_assoc] at h
+ sub_lt_iff_lt_add, mul_assoc] at h
have hu₀ : 0 ≤ u - ⌊ξ⌋ * v :=
by
refine' (zero_le_mul_right hv₁).mp ((lt_iff_add_one_le (-1 : ℤ) _).mp _)
replace h := h.1
- rw [← lt_sub_iff_add_lt, ← mul_assoc, ← sub_mul] at h
+ rw [← lt_sub_iff_add_lt, ← mul_assoc, ← sub_mul] at h
exact_mod_cast
h.trans_le
((mul_le_mul_right <| hv₀').mpr <|
@@ -470,18 +470,18 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v :=
refine' le_of_mul_le_mul_right (le_of_lt_add_one _) hv₁
replace h := h.2
rw [← sub_lt_iff_lt_add, ← mul_assoc, ← sub_mul, ← add_lt_add_iff_right (v * (2 * v - 1) : ℝ),
- add_comm (1 : ℝ)] at h
+ add_comm (1 : ℝ)] at h
have :=
(mul_lt_mul_right <| hv₀').mpr
((sub_lt_sub_iff_left (u : ℝ)).mpr <|
(mul_lt_mul_right hv₀).mpr <| sub_right_lt_of_lt_add <| lt_floor_add_one ξ)
- rw [sub_mul ξ, one_mul, ← sub_add, add_mul] at this
+ rw [sub_mul ξ, one_mul, ← sub_add, add_mul] at this
exact_mod_cast this.trans h
have huv_cop : IsCoprime (u - ⌊ξ⌋ * v) v := by
rwa [sub_eq_add_neg, ← neg_mul, IsCoprime.add_mul_right_left_iff]
refine' ⟨lt_of_le_of_ne' hu₀ fun hf => _, lt_of_le_of_ne hu₁ fun hf => _⟩ <;>
- · rw [hf] at huv_cop
- simp only [isCoprime_zero_left, isCoprime_self, is_unit_iff] at huv_cop
+ · rw [hf] at huv_cop
+ simp only [isCoprime_zero_left, isCoprime_self, is_unit_iff] at huv_cop
cases huv_cop <;> linarith only [hv, huv_cop]
-- The key step: the relevant inequality persists in the inductive step.
@@ -499,22 +499,22 @@ private theorem aux₃ :
have H₁ := div_pos (div_pos Hv Hu) hξ₀
replace h := h.2.2
have h' : |fract ξ - u' / v| < (v * (2 * v - 1))⁻¹ := by
- rwa [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm] at h
+ rwa [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm] at h
have H : (2 * u' - 1 : ℝ) ≤ (2 * v - 1) * fract ξ :=
by
replace h := (abs_lt.mp h).1
have : (2 * (v : ℝ) - 1) * (-(v * (2 * v - 1))⁻¹ + u' / v) = 2 * u' - (1 + u') / v := by
- field_simp [Hv.ne', Hv'.ne'] ; ring
+ field_simp [Hv.ne', Hv'.ne']; ring
rw [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm, self_sub_floor,
- lt_sub_iff_add_lt, ← mul_lt_mul_left Hv', this] at h
+ lt_sub_iff_add_lt, ← mul_lt_mul_left Hv', this] at h
refine' LE.le.trans _ h.le
rw [sub_le_sub_iff_left, div_le_one Hv, add_comm]
exact_mod_cast huv
have help₁ : ∀ {a b c : ℝ}, a ≠ 0 → b ≠ 0 → c ≠ 0 → |a⁻¹ - b / c| = |(a - c / b) * (b / c / a)| :=
- by intros ; rw [abs_sub_comm]; congr 1; field_simp; ring
+ by intros; rw [abs_sub_comm]; congr 1; field_simp; ring
have help₂ :
∀ {a b c d : ℝ}, a ≠ 0 → b ≠ 0 → c ≠ 0 → d ≠ 0 → (b * c)⁻¹ * (b / d / a) = (d * c * a)⁻¹ := by
- intros ; field_simp; ring
+ intros; field_simp; ring
calc
|(fract ξ)⁻¹ - v / u'| = |(fract ξ - u' / v) * (v / u' / fract ξ)| :=
help₁ hξ₀.ne' Hv.ne' Hu.ne'
@@ -533,11 +533,11 @@ private theorem invariant : ContfracLegendre.Ass (fract ξ)⁻¹ v (u - ⌊ξ⌋
· rw [sub_eq_add_neg, ← neg_mul, isCoprime_comm, IsCoprime.add_mul_right_left_iff]
exact h.1
· obtain ⟨hv₀, hv₀'⟩ := aux₀ (zero_lt_two.trans_le hv)
- have Hv : (v * (2 * v - 1) : ℝ)⁻¹ + v⁻¹ = 2 / (2 * v - 1) := by field_simp [hv₀.ne', hv₀'.ne'] ;
+ have Hv : (v * (2 * v - 1) : ℝ)⁻¹ + v⁻¹ = 2 / (2 * v - 1) := by field_simp [hv₀.ne', hv₀'.ne'];
ring
have Huv : (u / v : ℝ) = ⌊ξ⌋ + v⁻¹ := by rw [sub_eq_iff_eq_add'.mp huv]; field_simp [hv₀.ne']
have h' := (abs_sub_lt_iff.mp h.2.2).1
- rw [Huv, ← sub_sub, sub_lt_iff_lt_add, self_sub_floor, Hv] at h'
+ rw [Huv, ← sub_sub, sub_lt_iff_lt_add, self_sub_floor, Hv] at h'
rwa [lt_sub_iff_add_lt', (by ring : (v : ℝ) + -(1 / 2) = (2 * v - 1) / 2),
lt_inv (div_pos hv₀' zero_lt_two) (aux₁ hv h), inv_div]
@@ -556,7 +556,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h : ContfracLegendre.Ass ξ u v) :
rcases lt_trichotomy v 1 with (ht | rfl | ht)
· replace h := h.2.2
simp only [nat.lt_one_iff.mp ht, Nat.cast_zero, div_zero, tsub_zero, MulZeroClass.zero_mul,
- cast_zero, inv_zero] at h
+ cast_zero, inv_zero] at h
exact False.elim (lt_irrefl _ <| (abs_nonneg ξ).trans_lt h)
· rw [Nat.cast_one, div_one]
obtain ⟨_, h₁, h₂⟩ := h
@@ -570,7 +570,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h : ContfracLegendre.Ass ξ u v) :
rw [floor_eq_iff, cast_sub, cast_one, sub_add_cancel]
exact ⟨(((sub_lt_sub_iff_left _).mpr one_half_lt_one).trans h₁).le, ht⟩
cases' eq_or_ne ξ ⌊ξ⌋ with Hξ Hξ
- · rw [Hξ, hξ₁, cast_sub, cast_one, ← sub_eq_add_neg, sub_lt_sub_iff_left] at h₁
+ · rw [Hξ, hξ₁, cast_sub, cast_one, ← sub_eq_add_neg, sub_lt_sub_iff_left] at h₁
exact False.elim (lt_irrefl _ <| h₁.trans one_half_lt_one)
· have hξ₂ : ⌊(fract ξ)⁻¹⌋ = 1 :=
by
@@ -603,7 +603,7 @@ theorem exists_rat_eq_convergent {q : ℚ} (h : |ξ - q| < 1 / (2 * q.den ^ 2))
by
refine' q.num_div_denom ▸ exists_rat_eq_convergent' ⟨_, fun hd => _, _⟩
· exact coprime_iff_nat_coprime.mpr (nat_abs_of_nat q.denom ▸ q.cop)
- · rw [← q.denom_eq_one_iff.mp (nat.cast_eq_one.mp hd)] at h
+ · rw [← q.denom_eq_one_iff.mp (nat.cast_eq_one.mp hd)] at h
simpa only [Rat.coe_int_den, Nat.cast_one, one_pow, mul_one] using (abs_lt.mp h).1
· obtain ⟨hq₀, hq₁⟩ := aux₀ (nat.cast_pos.mpr q.pos)
replace hq₁ := mul_pos hq₀ hq₁
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -119,10 +119,7 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
⟨le_sub_iff_add_le.mpr _, sub_le_iff_le_add.mpr <| le_of_lt <| (hfu m).trans <| lt_one_add _⟩
simpa only [neg_add_cancel_comm_assoc] using hf'
· simp_rw [not_exists] at H
- have hD : (Ico (0 : ℤ) n).card < D.card :=
- by
- rw [card_Icc, card_Ico]
- exact lt_add_one n
+ have hD : (Ico (0 : ℤ) n).card < D.card := by rw [card_Icc, card_Ico]; exact lt_add_one n
have hfu' : ∀ m, f m ≤ n := fun m => lt_add_one_iff.mp (floor_lt.mpr (by exact_mod_cast hfu m))
have hwd : ∀ m : ℤ, m ∈ D → f m ∈ Ico (0 : ℤ) n := fun x hx =>
mem_Ico.mpr
@@ -137,10 +134,7 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
⟨⌊ξ * y⌋ - ⌊ξ * x⌋, y - x, sub_pos_of_lt x_lt_y,
sub_le_iff_le_add.mpr <| le_add_of_le_of_nonneg (mem_Icc.mp hy).2 (mem_Icc.mp hx).1, _⟩
convert_to|fract (ξ * y) * (n + 1) - fract (ξ * x) * (n + 1)| ≤ 1
- · congr
- push_cast
- simp only [fract]
- ring
+ · congr ; push_cast ; simp only [fract]; ring
exact (abs_sub_lt_one_of_floor_eq_floor hxy.symm).le
#align real.exists_int_int_abs_mul_sub_le Real.exists_int_int_abs_mul_sub_le
@@ -165,9 +159,7 @@ theorem exists_rat_abs_sub_le_and_den_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
by
obtain ⟨j, k, hk₀, hk₁, h⟩ := exists_int_int_abs_mul_sub_le ξ n_pos
have hk₀' : (0 : ℝ) < k := int.cast_pos.mpr hk₀
- have hden : ((j / k : ℚ).den : ℤ) ≤ k :=
- by
- convert le_of_dvd hk₀ (Rat.den_dvd j k)
+ have hden : ((j / k : ℚ).den : ℤ) ≤ k := by convert le_of_dvd hk₀ (Rat.den_dvd j k);
exact Rat.coe_int_div_eq_divInt
refine' ⟨j / k, _, nat.cast_le.mp (hden.trans hk₁)⟩
rw [← div_div, le_div_iff (nat.cast_pos.mpr <| Rat.pos _ : (0 : ℝ) < _)]
@@ -427,9 +419,7 @@ def ContfracLegendre.Ass (ξ : ℝ) (u v : ℤ) : Prop :=
-- ### Auxiliary lemmas
-- This saves a few lines below, as it is frequently needed.
private theorem aux₀ {v : ℤ} (hv : 0 < v) : (0 : ℝ) < v ∧ (0 : ℝ) < 2 * v - 1 :=
- ⟨cast_pos.mpr hv, by
- norm_cast
- linarith⟩
+ ⟨cast_pos.mpr hv, by norm_cast; linarith⟩
-- In the following, we assume that `ass ξ u v` holds and `v ≥ 2`.
variable {ξ : ℝ} {u v : ℤ} (hv : 2 ≤ v) (h : ContfracLegendre.Ass ξ u v)
@@ -513,28 +503,18 @@ private theorem aux₃ :
have H : (2 * u' - 1 : ℝ) ≤ (2 * v - 1) * fract ξ :=
by
replace h := (abs_lt.mp h).1
- have : (2 * (v : ℝ) - 1) * (-(v * (2 * v - 1))⁻¹ + u' / v) = 2 * u' - (1 + u') / v :=
- by
- field_simp [Hv.ne', Hv'.ne']
- ring
+ have : (2 * (v : ℝ) - 1) * (-(v * (2 * v - 1))⁻¹ + u' / v) = 2 * u' - (1 + u') / v := by
+ field_simp [Hv.ne', Hv'.ne'] ; ring
rw [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm, self_sub_floor,
lt_sub_iff_add_lt, ← mul_lt_mul_left Hv', this] at h
refine' LE.le.trans _ h.le
rw [sub_le_sub_iff_left, div_le_one Hv, add_comm]
exact_mod_cast huv
have help₁ : ∀ {a b c : ℝ}, a ≠ 0 → b ≠ 0 → c ≠ 0 → |a⁻¹ - b / c| = |(a - c / b) * (b / c / a)| :=
- by
- intros
- rw [abs_sub_comm]
- congr 1
- field_simp
- ring
+ by intros ; rw [abs_sub_comm]; congr 1; field_simp; ring
have help₂ :
- ∀ {a b c d : ℝ}, a ≠ 0 → b ≠ 0 → c ≠ 0 → d ≠ 0 → (b * c)⁻¹ * (b / d / a) = (d * c * a)⁻¹ :=
- by
- intros
- field_simp
- ring
+ ∀ {a b c d : ℝ}, a ≠ 0 → b ≠ 0 → c ≠ 0 → d ≠ 0 → (b * c)⁻¹ * (b / d / a) = (d * c * a)⁻¹ := by
+ intros ; field_simp; ring
calc
|(fract ξ)⁻¹ - v / u'| = |(fract ξ - u' / v) * (v / u' / fract ξ)| :=
help₁ hξ₀.ne' Hv.ne' Hu.ne'
@@ -553,14 +533,9 @@ private theorem invariant : ContfracLegendre.Ass (fract ξ)⁻¹ v (u - ⌊ξ⌋
· rw [sub_eq_add_neg, ← neg_mul, isCoprime_comm, IsCoprime.add_mul_right_left_iff]
exact h.1
· obtain ⟨hv₀, hv₀'⟩ := aux₀ (zero_lt_two.trans_le hv)
- have Hv : (v * (2 * v - 1) : ℝ)⁻¹ + v⁻¹ = 2 / (2 * v - 1) :=
- by
- field_simp [hv₀.ne', hv₀'.ne']
+ have Hv : (v * (2 * v - 1) : ℝ)⁻¹ + v⁻¹ = 2 / (2 * v - 1) := by field_simp [hv₀.ne', hv₀'.ne'] ;
ring
- have Huv : (u / v : ℝ) = ⌊ξ⌋ + v⁻¹ :=
- by
- rw [sub_eq_iff_eq_add'.mp huv]
- field_simp [hv₀.ne']
+ have Huv : (u / v : ℝ) = ⌊ξ⌋ + v⁻¹ := by rw [sub_eq_iff_eq_add'.mp huv]; field_simp [hv₀.ne']
have h' := (abs_sub_lt_iff.mp h.2.2).1
rw [Huv, ← sub_sub, sub_lt_iff_lt_add, self_sub_floor, Hv] at h'
rwa [lt_sub_iff_add_lt', (by ring : (v : ℝ) + -(1 / 2) = (2 * v - 1) / 2),
@@ -609,9 +584,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h : ContfracLegendre.Ass ξ u v) :
simp [convergent, hξ₁, hξ₂, cast_sub, cast_one]
· obtain ⟨huv₀, huv₁⟩ := aux₂ (nat.cast_le.mpr ht) h
have Hv : (v : ℚ) ≠ 0 := (nat.cast_pos.mpr (zero_lt_one.trans ht)).ne'
- have huv₁' : (u - ⌊ξ⌋ * v).toNat < v := by
- zify
- rwa [to_nat_of_nonneg huv₀.le]
+ have huv₁' : (u - ⌊ξ⌋ * v).toNat < v := by zify; rwa [to_nat_of_nonneg huv₀.le]
have inv : contfrac_legendre.ass (fract ξ)⁻¹ v (u - ⌊ξ⌋ * ↑v).toNat :=
(to_nat_of_nonneg huv₀.le).symm ▸ invariant (nat.cast_le.mpr ht) h
obtain ⟨n, hn⟩ := ih (u - ⌊ξ⌋ * v).toNat huv₁' inv
@@ -637,12 +610,7 @@ theorem exists_rat_eq_convergent {q : ℚ} (h : |ξ - q| < 1 / (2 * q.den ^ 2))
have hq₂ : (0 : ℝ) < 2 * (q.denom * q.denom) := mul_pos zero_lt_two (mul_pos hq₀ hq₀)
rw [← coe_coe] at *
rw [(by norm_cast : (q.num / q.denom : ℝ) = (q.num / q.denom : ℚ)), Rat.num_div_den]
- exact
- h.trans
- (by
- rw [← one_div, sq, one_div_lt_one_div hq₂ hq₁, ← sub_pos]
- ring_nf
- exact hq₀)
+ exact h.trans (by rw [← one_div, sq, one_div_lt_one_div hq₂ hq₁, ← sub_pos]; ring_nf; exact hq₀)
#align real.exists_rat_eq_convergent Real.exists_rat_eq_convergent
/-- The main result, *Legendre's Theorem* on rational approximation:
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -430,7 +430,6 @@ private theorem aux₀ {v : ℤ} (hv : 0 < v) : (0 : ℝ) < v ∧ (0 : ℝ) < 2
⟨cast_pos.mpr hv, by
norm_cast
linarith⟩
-#align real.aux₀ real.aux₀
-- In the following, we assume that `ass ξ u v` holds and `v ≥ 2`.
variable {ξ : ℝ} {u v : ℤ} (hv : 2 ≤ v) (h : ContfracLegendre.Ass ξ u v)
@@ -457,7 +456,6 @@ private theorem aux₁ : 0 < fract ξ :=
cases is_unit_iff.mp (is_coprime_self.mp (is_coprime.mul_left_iff.mp hcop).2) <;> linarith
norm_cast at H
linarith only [hv, H]
-#align real.aux₁ real.aux₁
-- An auxiliary lemma for the inductive step.
private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v :=
@@ -495,7 +493,6 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v :=
· rw [hf] at huv_cop
simp only [isCoprime_zero_left, isCoprime_self, is_unit_iff] at huv_cop
cases huv_cop <;> linarith only [hv, huv_cop]
-#align real.aux₂ real.aux₂
-- The key step: the relevant inequality persists in the inductive step.
private theorem aux₃ :
@@ -548,7 +545,6 @@ private theorem aux₃ :
rwa [inv_le_inv (mul_pos (mul_pos Hu Hv') hξ₀) <| mul_pos Hu Hu', mul_assoc,
mul_le_mul_left Hu]
-#align real.aux₃ real.aux₃
-- The conditions `ass ξ u v` persist in the inductive step.
private theorem invariant : ContfracLegendre.Ass (fract ξ)⁻¹ v (u - ⌊ξ⌋ * v) :=
@@ -569,7 +565,6 @@ private theorem invariant : ContfracLegendre.Ass (fract ξ)⁻¹ v (u - ⌊ξ⌋
rw [Huv, ← sub_sub, sub_lt_iff_lt_add, self_sub_floor, Hv] at h'
rwa [lt_sub_iff_add_lt', (by ring : (v : ℝ) + -(1 / 2) = (2 * v - 1) / 2),
lt_inv (div_pos hv₀' zero_lt_two) (aux₁ hv h), inv_div]
-#align real.invariant real.invariant
omit h hv
mathlib commit https://github.com/leanprover-community/mathlib/commit/28b2a92f2996d28e580450863c130955de0ed398
@@ -4,22 +4,33 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Michael Geißer, Michael Stoll
! This file was ported from Lean 3 source module number_theory.diophantine_approximation
-! leanprover-community/mathlib commit f0c8bf9245297a541f468be517f1bde6195105e9
+! leanprover-community/mathlib commit e25a317463bd37d88e33da164465d8c47922b1cd
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
-import Mathbin.Tactic.Basic
+import Mathbin.Algebra.ContinuedFractions.Computation.ApproximationCorollaries
+import Mathbin.Algebra.ContinuedFractions.Computation.Translations
+import Mathbin.Combinatorics.Pigeonhole
+import Mathbin.Data.Int.Units
import Mathbin.Data.Real.Irrational
+import Mathbin.RingTheory.Coprime.Lemmas
+import Mathbin.Tactic.Basic
/-!
# Diophantine Approximation
-This file gives proofs of various versions of **Dirichlet's approximation theorem**
-and its important consequence that when `ξ` is an irrational real number, then there are
-infinitely many rationals `x/y` (in lowest terms) such that `|ξ - x/y| < 1/y^2`.
-
+The first part of this file gives proofs of various versions of
+**Dirichlet's approximation theorem** and its important consequence that when $\xi$ is an
+irrational real number, then there are infinitely many rationals $x/y$ (in lowest terms)
+such that
+$$\left|\xi - \frac{x}{y}\right| < \frac{1}{y^2} \,.$$
The proof is based on the pigeonhole principle.
+The second part of the file gives a proof of **Legendre's Theorem** on rational approximation,
+which states that if $\xi$ is a real number and $x/y$ is a rational number such that
+$$\left|\xi - \frac{x}{y}\right| < \frac{1}{2y^2} \,,$$
+then $x/y$ must be a convergent of the continued fraction expansion of $\xi$.
+
## Main statements
The main results are three variants of Dirichlet's approximation theorem:
@@ -41,18 +52,27 @@ We also show a converse,
Both statements are combined to give an equivalence,
`real.infinite_rat_abs_sub_lt_one_div_denom_sq_iff_irrational`.
+There are two versions of Legendre's Theorem. One, `real.exists_rat_eq_convergent`, uses
+`real.convergent`, a simple recursive definition of the convergents that is also defined
+in this file, whereas the other, `real.exists_continued_fraction_convergent_eq_rat`, uses
+`generalized_continued_fraction.convergents` of `generalized_continued_fraction.of ξ`.
+
## Implementation notes
We use the namespace `real` for the results on real numbers and `rat` for the results
-on rational numbers.
+on rational numbers. We introduce a secondary namespace `real.contfrac_legendre`
+to separate off a definition and some technical auxiliary lemmas used in the proof
+of Legendre's Theorem. For remarks on the proof of Legendre's Theorem, see below.
## References
<https://en.wikipedia.org/wiki/Dirichlet%27s_approximation_theorem>
+<https://de.wikipedia.org/wiki/Kettenbruch> (The German Wikipedia page on continued
+fractions is much more extensive than the English one.)
## Tags
-Diophantine approximation, Dirichlet's approximation theorem
+Diophantine approximation, Dirichlet's approximation theorem, continued fraction
-/
@@ -293,3 +313,353 @@ theorem Real.infinite_rat_abs_sub_lt_one_div_den_sq_iff_irrational (ξ : ℝ) :
norm_cast
#align real.infinite_rat_abs_sub_lt_one_div_denom_sq_iff_irrational Real.infinite_rat_abs_sub_lt_one_div_den_sq_iff_irrational
+/-!
+### Legendre's Theorem on Rational Approximation
+
+We prove **Legendre's Theorem** on rational approximation: If $\xi$ is a real number and
+$x/y$ is a rational number such that $|\xi - x/y| < 1/(2y^2)$,
+then $x/y$ is a convergent of the continued fraction expansion of $\xi$.
+
+The proof is by induction. However, the induction proof does not work with the
+statement as given, since the assumption is too weak to imply the corresponding
+statement for the application of the induction hypothesis. This can be remedied
+by making the statement slightly stronger. Namely, we assume that $|\xi - x/y| < 1/(y(2y-1))$
+when $y \ge 2$ and $-\frac{1}{2} < \xi - x < 1$ when $y = 1$.
+-/
+
+
+section Convergent
+
+namespace Real
+
+open Int
+
+/-!
+### Convergents: definition and API lemmas
+-/
+
+
+/-- We give a direct recursive definition of the convergents of the continued fraction
+expansion of a real number `ξ`. The main reason for that is that we want to have the
+convergents as rational numbers; the versions
+`(generalized_continued_fraction.of ξ).convergents` and
+`(generalized_continued_fraction.of ξ).convergents'` always give something of the
+same type as `ξ`. We can then also use dot notation `ξ.convergent n`.
+Another minor reason is that this demonstrates that the proof
+of Legendre's theorem does not need anything beyond this definition.
+We provide a proof that this definition agrees with the other one;
+see `real.continued_fraction_convergent_eq_convergent`.
+(Note that we use the fact that `1/0 = 0` here to make it work for rational `ξ`.) -/
+noncomputable def convergent : ℝ → ℕ → ℚ
+ | ξ, 0 => ⌊ξ⌋
+ | ξ, n + 1 => ⌊ξ⌋ + (convergent (fract ξ)⁻¹ n)⁻¹
+#align real.convergent Real.convergent
+
+/-- The zeroth convergent of `ξ` is `⌊ξ⌋`. -/
+@[simp]
+theorem convergent_zero (ξ : ℝ) : ξ.convergent 0 = ⌊ξ⌋ :=
+ rfl
+#align real.convergent_zero Real.convergent_zero
+
+/-- The `(n+1)`th convergent of `ξ` is the `n`th convergent of `1/(fract ξ)`. -/
+@[simp]
+theorem convergent_succ (ξ : ℝ) (n : ℕ) :
+ ξ.convergent (n + 1) = ⌊ξ⌋ + ((fract ξ)⁻¹.convergent n)⁻¹ := by simp only [convergent]
+#align real.convergent_succ Real.convergent_succ
+
+/-- All convergents of `0` are zero. -/
+@[simp]
+theorem convergent_of_zero (n : ℕ) : convergent 0 n = 0 :=
+ by
+ induction' n with n ih
+ · simp only [convergent_zero, floor_zero, cast_zero]
+ · simp only [ih, convergent_succ, floor_zero, cast_zero, fract_zero, add_zero, inv_zero]
+#align real.convergent_of_zero Real.convergent_of_zero
+
+/-- If `ξ` is an integer, all its convergents equal `ξ`. -/
+@[simp]
+theorem convergent_of_int {ξ : ℤ} (n : ℕ) : convergent ξ n = ξ :=
+ by
+ cases n
+ · simp only [convergent_zero, floor_int_cast]
+ ·
+ simp only [convergent_succ, floor_int_cast, fract_int_cast, convergent_of_zero, add_zero,
+ inv_zero]
+#align real.convergent_of_int Real.convergent_of_int
+
+/-!
+Our `convergent`s agree with `generalized_continued_fraction.convergents`.
+-/
+
+
+open GeneralizedContinuedFraction
+
+/-- The `n`th convergent of the `generalized_continued_fraction.of ξ`
+agrees with `ξ.convergent n`. -/
+theorem continued_fraction_convergent_eq_convergent (ξ : ℝ) (n : ℕ) :
+ (GeneralizedContinuedFraction.of ξ).convergents n = ξ.convergent n :=
+ by
+ induction' n with n ih generalizing ξ
+ · simp only [zeroth_convergent_eq_h, of_h_eq_floor, convergent_zero, Rat.cast_coe_int]
+ · rw [convergents_succ, ih (fract ξ)⁻¹, convergent_succ, one_div]
+ norm_cast
+#align real.continued_fraction_convergent_eq_convergent Real.continued_fraction_convergent_eq_convergent
+
+end Real
+
+end Convergent
+
+/-!
+### The key technical condition for the induction proof
+-/
+
+
+namespace Real
+
+open Int
+
+-- this is not `private`, as it is used in the public `exists_rat_eq_convergent'` below.
+/-- Define the technical condition to be used as assumption in the inductive proof. -/
+def ContfracLegendre.Ass (ξ : ℝ) (u v : ℤ) : Prop :=
+ IsCoprime u v ∧ (v = 1 → (-(1 / 2) : ℝ) < ξ - u) ∧ |ξ - u / v| < (v * (2 * v - 1))⁻¹
+#align real.contfrac_legendre.ass Real.ContfracLegendre.Ass
+
+-- ### Auxiliary lemmas
+-- This saves a few lines below, as it is frequently needed.
+private theorem aux₀ {v : ℤ} (hv : 0 < v) : (0 : ℝ) < v ∧ (0 : ℝ) < 2 * v - 1 :=
+ ⟨cast_pos.mpr hv, by
+ norm_cast
+ linarith⟩
+#align real.aux₀ real.aux₀
+
+-- In the following, we assume that `ass ξ u v` holds and `v ≥ 2`.
+variable {ξ : ℝ} {u v : ℤ} (hv : 2 ≤ v) (h : ContfracLegendre.Ass ξ u v)
+
+include hv h
+
+-- The fractional part of `ξ` is positive.
+private theorem aux₁ : 0 < fract ξ :=
+ by
+ have hv₀ : (0 : ℝ) < v := cast_pos.mpr (zero_lt_two.trans_le hv)
+ obtain ⟨hv₁, hv₂⟩ := aux₀ (zero_lt_two.trans_le hv)
+ obtain ⟨hcop, _, h⟩ := h
+ refine' fract_pos.mpr fun hf => _
+ rw [hf] at h
+ have H : (2 * v - 1 : ℝ) < 1 :=
+ by
+ refine'
+ (mul_lt_iff_lt_one_right hv₀).mp ((inv_lt_inv hv₀ (mul_pos hv₁ hv₂)).mp (lt_of_le_of_lt _ h))
+ have h' : (⌊ξ⌋ : ℝ) - u / v = (⌊ξ⌋ * v - u) / v := by field_simp [hv₀.ne']
+ rw [h', abs_div, abs_of_pos hv₀, ← one_div, div_le_div_right hv₀]
+ norm_cast
+ rw [← zero_add (1 : ℤ), add_one_le_iff, abs_pos, sub_ne_zero]
+ rintro rfl
+ cases is_unit_iff.mp (is_coprime_self.mp (is_coprime.mul_left_iff.mp hcop).2) <;> linarith
+ norm_cast at H
+ linarith only [hv, H]
+#align real.aux₁ real.aux₁
+
+-- An auxiliary lemma for the inductive step.
+private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v :=
+ by
+ obtain ⟨hcop, _, h⟩ := h
+ obtain ⟨hv₀, hv₀'⟩ := aux₀ (zero_lt_two.trans_le hv)
+ have hv₁ : 0 < 2 * v - 1 := by linarith only [hv]
+ rw [← one_div, lt_div_iff (mul_pos hv₀ hv₀'), ← abs_of_pos (mul_pos hv₀ hv₀'), ← abs_mul, sub_mul,
+ ← mul_assoc, ← mul_assoc, div_mul_cancel _ hv₀.ne', abs_sub_comm, abs_lt, lt_sub_iff_add_lt,
+ sub_lt_iff_lt_add, mul_assoc] at h
+ have hu₀ : 0 ≤ u - ⌊ξ⌋ * v :=
+ by
+ refine' (zero_le_mul_right hv₁).mp ((lt_iff_add_one_le (-1 : ℤ) _).mp _)
+ replace h := h.1
+ rw [← lt_sub_iff_add_lt, ← mul_assoc, ← sub_mul] at h
+ exact_mod_cast
+ h.trans_le
+ ((mul_le_mul_right <| hv₀').mpr <|
+ (sub_le_sub_iff_left (u : ℝ)).mpr ((mul_le_mul_right hv₀).mpr (floor_le ξ)))
+ have hu₁ : u - ⌊ξ⌋ * v ≤ v :=
+ by
+ refine' le_of_mul_le_mul_right (le_of_lt_add_one _) hv₁
+ replace h := h.2
+ rw [← sub_lt_iff_lt_add, ← mul_assoc, ← sub_mul, ← add_lt_add_iff_right (v * (2 * v - 1) : ℝ),
+ add_comm (1 : ℝ)] at h
+ have :=
+ (mul_lt_mul_right <| hv₀').mpr
+ ((sub_lt_sub_iff_left (u : ℝ)).mpr <|
+ (mul_lt_mul_right hv₀).mpr <| sub_right_lt_of_lt_add <| lt_floor_add_one ξ)
+ rw [sub_mul ξ, one_mul, ← sub_add, add_mul] at this
+ exact_mod_cast this.trans h
+ have huv_cop : IsCoprime (u - ⌊ξ⌋ * v) v := by
+ rwa [sub_eq_add_neg, ← neg_mul, IsCoprime.add_mul_right_left_iff]
+ refine' ⟨lt_of_le_of_ne' hu₀ fun hf => _, lt_of_le_of_ne hu₁ fun hf => _⟩ <;>
+ · rw [hf] at huv_cop
+ simp only [isCoprime_zero_left, isCoprime_self, is_unit_iff] at huv_cop
+ cases huv_cop <;> linarith only [hv, huv_cop]
+#align real.aux₂ real.aux₂
+
+-- The key step: the relevant inequality persists in the inductive step.
+private theorem aux₃ :
+ |(fract ξ)⁻¹ - v / (u - ⌊ξ⌋ * v)| < ((u - ⌊ξ⌋ * v) * (2 * (u - ⌊ξ⌋ * v) - 1))⁻¹ :=
+ by
+ obtain ⟨hu₀, huv⟩ := aux₂ hv h
+ have hξ₀ := aux₁ hv h
+ set u' := u - ⌊ξ⌋ * v with hu'
+ have hu'ℝ : (u' : ℝ) = u - ⌊ξ⌋ * v := by exact_mod_cast hu'
+ rw [← hu'ℝ]
+ replace hu'ℝ := (eq_sub_iff_add_eq.mp hu'ℝ).symm
+ obtain ⟨Hu, Hu'⟩ := aux₀ hu₀
+ obtain ⟨Hv, Hv'⟩ := aux₀ (zero_lt_two.trans_le hv)
+ have H₁ := div_pos (div_pos Hv Hu) hξ₀
+ replace h := h.2.2
+ have h' : |fract ξ - u' / v| < (v * (2 * v - 1))⁻¹ := by
+ rwa [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm] at h
+ have H : (2 * u' - 1 : ℝ) ≤ (2 * v - 1) * fract ξ :=
+ by
+ replace h := (abs_lt.mp h).1
+ have : (2 * (v : ℝ) - 1) * (-(v * (2 * v - 1))⁻¹ + u' / v) = 2 * u' - (1 + u') / v :=
+ by
+ field_simp [Hv.ne', Hv'.ne']
+ ring
+ rw [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm, self_sub_floor,
+ lt_sub_iff_add_lt, ← mul_lt_mul_left Hv', this] at h
+ refine' LE.le.trans _ h.le
+ rw [sub_le_sub_iff_left, div_le_one Hv, add_comm]
+ exact_mod_cast huv
+ have help₁ : ∀ {a b c : ℝ}, a ≠ 0 → b ≠ 0 → c ≠ 0 → |a⁻¹ - b / c| = |(a - c / b) * (b / c / a)| :=
+ by
+ intros
+ rw [abs_sub_comm]
+ congr 1
+ field_simp
+ ring
+ have help₂ :
+ ∀ {a b c d : ℝ}, a ≠ 0 → b ≠ 0 → c ≠ 0 → d ≠ 0 → (b * c)⁻¹ * (b / d / a) = (d * c * a)⁻¹ :=
+ by
+ intros
+ field_simp
+ ring
+ calc
+ |(fract ξ)⁻¹ - v / u'| = |(fract ξ - u' / v) * (v / u' / fract ξ)| :=
+ help₁ hξ₀.ne' Hv.ne' Hu.ne'
+ _ = |fract ξ - u' / v| * (v / u' / fract ξ) := by rw [abs_mul, abs_of_pos H₁, abs_sub_comm]
+ _ < (v * (2 * v - 1))⁻¹ * (v / u' / fract ξ) := ((mul_lt_mul_right H₁).mpr h')
+ _ = (u' * (2 * v - 1) * fract ξ)⁻¹ := (help₂ hξ₀.ne' Hv.ne' Hv'.ne' Hu.ne')
+ _ ≤ (u' * (2 * u' - 1))⁻¹ := by
+ rwa [inv_le_inv (mul_pos (mul_pos Hu Hv') hξ₀) <| mul_pos Hu Hu', mul_assoc,
+ mul_le_mul_left Hu]
+
+#align real.aux₃ real.aux₃
+
+-- The conditions `ass ξ u v` persist in the inductive step.
+private theorem invariant : ContfracLegendre.Ass (fract ξ)⁻¹ v (u - ⌊ξ⌋ * v) :=
+ by
+ refine' ⟨_, fun huv => _, by exact_mod_cast aux₃ hv h⟩
+ · rw [sub_eq_add_neg, ← neg_mul, isCoprime_comm, IsCoprime.add_mul_right_left_iff]
+ exact h.1
+ · obtain ⟨hv₀, hv₀'⟩ := aux₀ (zero_lt_two.trans_le hv)
+ have Hv : (v * (2 * v - 1) : ℝ)⁻¹ + v⁻¹ = 2 / (2 * v - 1) :=
+ by
+ field_simp [hv₀.ne', hv₀'.ne']
+ ring
+ have Huv : (u / v : ℝ) = ⌊ξ⌋ + v⁻¹ :=
+ by
+ rw [sub_eq_iff_eq_add'.mp huv]
+ field_simp [hv₀.ne']
+ have h' := (abs_sub_lt_iff.mp h.2.2).1
+ rw [Huv, ← sub_sub, sub_lt_iff_lt_add, self_sub_floor, Hv] at h'
+ rwa [lt_sub_iff_add_lt', (by ring : (v : ℝ) + -(1 / 2) = (2 * v - 1) / 2),
+ lt_inv (div_pos hv₀' zero_lt_two) (aux₁ hv h), inv_div]
+#align real.invariant real.invariant
+
+omit h hv
+
+/-!
+### The main result
+-/
+
+
+/-- The technical version of *Legendre's Theorem*. -/
+theorem exists_rat_eq_convergent' {v : ℕ} (h : ContfracLegendre.Ass ξ u v) :
+ ∃ n, (u / v : ℚ) = ξ.convergent n :=
+ by
+ induction' v using Nat.strong_induction_on with v ih generalizing ξ u
+ rcases lt_trichotomy v 1 with (ht | rfl | ht)
+ · replace h := h.2.2
+ simp only [nat.lt_one_iff.mp ht, Nat.cast_zero, div_zero, tsub_zero, MulZeroClass.zero_mul,
+ cast_zero, inv_zero] at h
+ exact False.elim (lt_irrefl _ <| (abs_nonneg ξ).trans_lt h)
+ · rw [Nat.cast_one, div_one]
+ obtain ⟨_, h₁, h₂⟩ := h
+ cases' le_or_lt (u : ℝ) ξ with ht ht
+ · use 0
+ rw [convergent_zero, Rat.coe_int_inj, eq_comm, floor_eq_iff]
+ convert And.intro ht (sub_lt_iff_lt_add'.mp (abs_lt.mp h₂).2) <;> norm_num
+ · replace h₁ := lt_sub_iff_add_lt'.mp (h₁ rfl)
+ have hξ₁ : ⌊ξ⌋ = u - 1 :=
+ by
+ rw [floor_eq_iff, cast_sub, cast_one, sub_add_cancel]
+ exact ⟨(((sub_lt_sub_iff_left _).mpr one_half_lt_one).trans h₁).le, ht⟩
+ cases' eq_or_ne ξ ⌊ξ⌋ with Hξ Hξ
+ · rw [Hξ, hξ₁, cast_sub, cast_one, ← sub_eq_add_neg, sub_lt_sub_iff_left] at h₁
+ exact False.elim (lt_irrefl _ <| h₁.trans one_half_lt_one)
+ · have hξ₂ : ⌊(fract ξ)⁻¹⌋ = 1 :=
+ by
+ rw [floor_eq_iff, cast_one, le_inv zero_lt_one (fract_pos.mpr Hξ), inv_one,
+ one_add_one_eq_two, inv_lt (fract_pos.mpr Hξ) zero_lt_two]
+ refine' ⟨(fract_lt_one ξ).le, _⟩
+ rw [fract, hξ₁, cast_sub, cast_one, lt_sub_iff_add_lt', sub_add]
+ convert h₁
+ norm_num
+ use 1
+ simp [convergent, hξ₁, hξ₂, cast_sub, cast_one]
+ · obtain ⟨huv₀, huv₁⟩ := aux₂ (nat.cast_le.mpr ht) h
+ have Hv : (v : ℚ) ≠ 0 := (nat.cast_pos.mpr (zero_lt_one.trans ht)).ne'
+ have huv₁' : (u - ⌊ξ⌋ * v).toNat < v := by
+ zify
+ rwa [to_nat_of_nonneg huv₀.le]
+ have inv : contfrac_legendre.ass (fract ξ)⁻¹ v (u - ⌊ξ⌋ * ↑v).toNat :=
+ (to_nat_of_nonneg huv₀.le).symm ▸ invariant (nat.cast_le.mpr ht) h
+ obtain ⟨n, hn⟩ := ih (u - ⌊ξ⌋ * v).toNat huv₁' inv
+ use n + 1
+ rw [convergent_succ, ← hn,
+ (by exact_mod_cast to_nat_of_nonneg huv₀.le : ((u - ⌊ξ⌋ * v).toNat : ℚ) = u - ⌊ξ⌋ * v), ←
+ coe_coe, inv_div, sub_div, mul_div_cancel _ Hv, add_sub_cancel'_right]
+#align real.exists_rat_eq_convergent' Real.exists_rat_eq_convergent'
+
+/-- The main result, *Legendre's Theorem* on rational approximation:
+if `ξ` is a real number and `q` is a rational number such that `|ξ - q| < 1/(2*q.denom^2)`,
+then `q` is a convergent of the continued fraction expansion of `ξ`.
+This version uses `real.convergent`. -/
+theorem exists_rat_eq_convergent {q : ℚ} (h : |ξ - q| < 1 / (2 * q.den ^ 2)) :
+ ∃ n, q = ξ.convergent n :=
+ by
+ refine' q.num_div_denom ▸ exists_rat_eq_convergent' ⟨_, fun hd => _, _⟩
+ · exact coprime_iff_nat_coprime.mpr (nat_abs_of_nat q.denom ▸ q.cop)
+ · rw [← q.denom_eq_one_iff.mp (nat.cast_eq_one.mp hd)] at h
+ simpa only [Rat.coe_int_den, Nat.cast_one, one_pow, mul_one] using (abs_lt.mp h).1
+ · obtain ⟨hq₀, hq₁⟩ := aux₀ (nat.cast_pos.mpr q.pos)
+ replace hq₁ := mul_pos hq₀ hq₁
+ have hq₂ : (0 : ℝ) < 2 * (q.denom * q.denom) := mul_pos zero_lt_two (mul_pos hq₀ hq₀)
+ rw [← coe_coe] at *
+ rw [(by norm_cast : (q.num / q.denom : ℝ) = (q.num / q.denom : ℚ)), Rat.num_div_den]
+ exact
+ h.trans
+ (by
+ rw [← one_div, sq, one_div_lt_one_div hq₂ hq₁, ← sub_pos]
+ ring_nf
+ exact hq₀)
+#align real.exists_rat_eq_convergent Real.exists_rat_eq_convergent
+
+/-- The main result, *Legendre's Theorem* on rational approximation:
+if `ξ` is a real number and `q` is a rational number such that `|ξ - q| < 1/(2*q.denom^2)`,
+then `q` is a convergent of the continued fraction expansion of `ξ`.
+This is the version using `generalized_contined_fraction.convergents`. -/
+theorem exists_continued_fraction_convergent_eq_rat {q : ℚ} (h : |ξ - q| < 1 / (2 * q.den ^ 2)) :
+ ∃ n, (GeneralizedContinuedFraction.of ξ).convergents n = q :=
+ by
+ obtain ⟨n, hn⟩ := exists_rat_eq_convergent h
+ exact ⟨n, hn.symm ▸ continued_fraction_convergent_eq_convergent ξ n⟩
+#align real.exists_continued_fraction_convergent_eq_rat Real.exists_continued_fraction_convergent_eq_rat
+
+end Real
+
mathlib commit https://github.com/leanprover-community/mathlib/commit/738054fa93d43512da144ec45ce799d18fd44248
@@ -4,13 +4,12 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Michael Geißer, Michael Stoll
! This file was ported from Lean 3 source module number_theory.diophantine_approximation
-! leanprover-community/mathlib commit 9956c3806d0f9553e5c6e6af68970563a1619cd1
+! leanprover-community/mathlib commit f0c8bf9245297a541f468be517f1bde6195105e9
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.Tactic.Basic
import Mathbin.Data.Real.Irrational
-import Mathbin.Combinatorics.Pigeonhole
/-!
# Diophantine Approximation
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce7e9d53d4bbc38065db3b595cd5bd73c323bc1d
@@ -117,7 +117,7 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
refine'
⟨⌊ξ * y⌋ - ⌊ξ * x⌋, y - x, sub_pos_of_lt x_lt_y,
sub_le_iff_le_add.mpr <| le_add_of_le_of_nonneg (mem_Icc.mp hy).2 (mem_Icc.mp hx).1, _⟩
- convert_to |fract (ξ * y) * (n + 1) - fract (ξ * x) * (n + 1)| ≤ 1
+ convert_to|fract (ξ * y) * (n + 1) - fract (ξ * x) * (n + 1)| ≤ 1
· congr
push_cast
simp only [fract]
mathlib commit https://github.com/leanprover-community/mathlib/commit/3180fab693e2cee3bff62675571264cb8778b212
@@ -90,8 +90,8 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
have hm₀ : 0 < m :=
by
have hf₀ : f 0 = 0 := by
- simp only [floor_eq_zero_iff, algebraMap.coe_zero, mul_zero, fract_zero, zero_mul,
- Set.left_mem_Ico, zero_lt_one]
+ simp only [floor_eq_zero_iff, algebraMap.coe_zero, MulZeroClass.mul_zero, fract_zero,
+ MulZeroClass.zero_mul, Set.left_mem_Ico, zero_lt_one]
refine' Ne.lt_of_le (fun h => n_pos.ne _) (mem_Icc.mp hm).1
exact_mod_cast hf₀.symm.trans (h.symm ▸ hf : f 0 = n)
refine' ⟨⌊ξ * m⌋ + 1, m, hm₀, (mem_Icc.mp hm).2, _⟩
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
q ^ n
(#12506)
Prove (q ^ n).num = q.num ^ n
and (q ^ n).den = q.den ^ n
by making those defeq. It is somewhat painful. (q ^ n).den = q.den ^ n
is also defeq for NNRat
, but not (q ^ n).num = q.num ^ n
due to the Int.natAbs
in the definition of NNRat.num
.
Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
@@ -156,7 +156,7 @@ theorem exists_rat_abs_sub_le_and_den_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
have hk₀' : (0 : ℝ) < k := Int.cast_pos.mpr hk₀
have hden : ((j / k : ℚ).den : ℤ) ≤ k := by
convert le_of_dvd hk₀ (Rat.den_dvd j k)
- exact Rat.intCast_div_eq_divInt
+ exact Rat.intCast_div_eq_divInt _ _
refine' ⟨j / k, _, Nat.cast_le.mp (hden.trans hk₁)⟩
rw [← div_div, le_div_iff (Nat.cast_pos.mpr <| Rat.pos _ : (0 : ℝ) < _)]
refine' (mul_le_mul_of_nonneg_left (Int.cast_le.mpr hden : _ ≤ (k : ℝ)) (abs_nonneg _)).trans _
There are more wrong lemmas in Std, but it's out of my scope
@@ -586,7 +586,7 @@ theorem exists_rat_eq_convergent {q : ℚ} (h : |ξ - q| < 1 / (2 * (q.den : ℝ
refine' q.num_div_den ▸ exists_rat_eq_convergent' ⟨_, fun hd => _, _⟩
· exact coprime_iff_nat_coprime.mpr (natAbs_ofNat q.den ▸ q.reduced)
· rw [← q.den_eq_one_iff.mp (Nat.cast_eq_one.mp hd)] at h
- simpa only [Rat.coe_int_den, Nat.cast_one, one_pow, mul_one] using (abs_lt.mp h).1
+ simpa only [Rat.den_intCast, Nat.cast_one, one_pow, mul_one] using (abs_lt.mp h).1
· obtain ⟨hq₀, hq₁⟩ := aux₀ (Nat.cast_pos.mpr q.pos)
replace hq₁ := mul_pos hq₀ hq₁
have hq₂ : (0 : ℝ) < 2 * (q.den * q.den) := mul_pos zero_lt_two (mul_pos hq₀ hq₀)
@@ -445,7 +445,7 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v := by
have hu₀ : 0 ≤ u - ⌊ξ⌋ * v := by
-- Porting note: this abused the definitional equality `-1 + 1 = 0`
-- refine' (mul_nonneg_iff_of_pos_right hv₁).mp ((lt_iff_add_one_le (-1 : ℤ) _).mp _)
- refine' (mul_nonneg_iff_of_pos_right hv₁).mp ?_
+ refine (mul_nonneg_iff_of_pos_right hv₁).mp ?_
rw [← sub_one_lt_iff, zero_sub]
replace h := h.1
rw [← lt_sub_iff_add_lt, ← mul_assoc, ← sub_mul] at h
@@ -504,8 +504,8 @@ private theorem aux₃ :
|(fract ξ)⁻¹ - v / u'| = |(fract ξ - u' / v) * (v / u' / fract ξ)| :=
help₁ hξ₀.ne' Hv.ne' Hu.ne'
_ = |fract ξ - u' / v| * (v / u' / fract ξ) := by rw [abs_mul, abs_of_pos H₁]
- _ < ((v : ℝ) * (2 * v - 1))⁻¹ * (v / u' / fract ξ) := ((mul_lt_mul_right H₁).mpr h')
- _ = (u' * (2 * v - 1) * fract ξ)⁻¹ := (help₂ hξ₀.ne' Hv.ne' Hv'.ne' Hu.ne')
+ _ < ((v : ℝ) * (2 * v - 1))⁻¹ * (v / u' / fract ξ) := (mul_lt_mul_right H₁).mpr h'
+ _ = (u' * (2 * v - 1) * fract ξ)⁻¹ := help₂ hξ₀.ne' Hv.ne' Hv'.ne' Hu.ne'
_ ≤ ((u' : ℝ) * (2 * u' - 1))⁻¹ := by
rwa [inv_le_inv (mul_pos (mul_pos Hu Hv') hξ₀) <| mul_pos Hu Hu', mul_assoc,
mul_le_mul_left Hu]
@@ -142,7 +142,7 @@ theorem exists_nat_abs_mul_sub_round_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
obtain ⟨j, k, hk₀, hk₁, h⟩ := exists_int_int_abs_mul_sub_le ξ n_pos
have hk := toNat_of_nonneg hk₀.le
rw [← hk] at hk₀ hk₁ h
- exact ⟨k.toNat, coe_nat_pos.mp hk₀, Nat.cast_le.mp hk₁, (round_le (↑k.toNat * ξ) j).trans h⟩
+ exact ⟨k.toNat, natCast_pos.mp hk₀, Nat.cast_le.mp hk₁, (round_le (↑k.toNat * ξ) j).trans h⟩
#align real.exists_nat_abs_mul_sub_round_le Real.exists_nat_abs_mul_sub_round_le
/-- *Dirichlet's approximation theorem:*
@@ -156,7 +156,7 @@ theorem exists_rat_abs_sub_le_and_den_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
have hk₀' : (0 : ℝ) < k := Int.cast_pos.mpr hk₀
have hden : ((j / k : ℚ).den : ℤ) ≤ k := by
convert le_of_dvd hk₀ (Rat.den_dvd j k)
- exact Rat.coe_int_div_eq_divInt
+ exact Rat.intCast_div_eq_divInt
refine' ⟨j / k, _, Nat.cast_le.mp (hden.trans hk₁)⟩
rw [← div_div, le_div_iff (Nat.cast_pos.mpr <| Rat.pos _ : (0 : ℝ) < _)]
refine' (mul_le_mul_of_nonneg_left (Int.cast_le.mpr hden : _ ≤ (k : ℝ)) (abs_nonneg _)).trans _
OfNat
and Nat.cast
lemmas (#11861)
This renames
Int.cast_ofNat
to Int.cast_natCast
Int.int_cast_ofNat
to Int.cast_ofNat
I think the history here is that this lemma was previously about Int.ofNat
, before we globally fixed the simp-normal form to be Nat.cast
.
Since the Int.cast_ofNat
name is repurposed, it can't be deprecated. Int.int_cast_ofNat
is such a wonky name that it was probably never used.
@@ -574,7 +574,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h' : ContfracLegendre.Ass ξ u v) :
use n + 1
rw [convergent_succ, ← hn,
(mod_cast toNat_of_nonneg huv₀.le : ((u - ⌊ξ⌋ * v).toNat : ℚ) = u - ⌊ξ⌋ * v),
- cast_ofNat, inv_div, sub_div, mul_div_cancel_right₀ _ Hv, add_sub_cancel]
+ cast_natCast, inv_div, sub_div, mul_div_cancel_right₀ _ Hv, add_sub_cancel]
#align real.exists_rat_eq_convergent' Real.exists_rat_eq_convergent'
/-- The main result, *Legendre's Theorem* on rational approximation:
@@ -590,7 +590,7 @@ theorem exists_rat_eq_convergent {q : ℚ} (h : |ξ - q| < 1 / (2 * (q.den : ℝ
· obtain ⟨hq₀, hq₁⟩ := aux₀ (Nat.cast_pos.mpr q.pos)
replace hq₁ := mul_pos hq₀ hq₁
have hq₂ : (0 : ℝ) < 2 * (q.den * q.den) := mul_pos zero_lt_two (mul_pos hq₀ hq₀)
- rw [cast_ofNat] at *
+ rw [cast_natCast] at *
rw [(by norm_cast : (q.num / q.den : ℝ) = (q.num / q.den : ℚ)), Rat.num_div_den]
exact h.trans (by rw [← one_div, sq, one_div_lt_one_div hq₂ hq₁, ← sub_pos]; ring_nf; exact hq₀)
#align real.exists_rat_eq_convergent Real.exists_rat_eq_convergent
mul
-div
cancellation lemmas (#11530)
Lemma names around cancellation of multiplication and division are a mess.
This PR renames a handful of them according to the following table (each big row contains the multiplicative statement, then the three rows contain the GroupWithZero
lemma name, the Group
lemma, the AddGroup
lemma name).
| Statement | New name | Old name | |
@@ -161,7 +161,7 @@ theorem exists_rat_abs_sub_le_and_den_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
rw [← div_div, le_div_iff (Nat.cast_pos.mpr <| Rat.pos _ : (0 : ℝ) < _)]
refine' (mul_le_mul_of_nonneg_left (Int.cast_le.mpr hden : _ ≤ (k : ℝ)) (abs_nonneg _)).trans _
rwa [← abs_of_pos hk₀', Rat.cast_div, Rat.cast_intCast, Rat.cast_intCast, ← abs_mul, sub_mul,
- div_mul_cancel _ hk₀'.ne', mul_comm]
+ div_mul_cancel₀ _ hk₀'.ne', mul_comm]
#align real.exists_rat_abs_sub_le_and_denom_le Real.exists_rat_abs_sub_le_and_den_le
end Dirichlet
@@ -237,7 +237,7 @@ theorem den_le_and_le_num_le_of_sub_lt_one_div_den_sq {ξ q : ℚ}
replace h : |ξ * q.den - q.num| < 1 / q.den := by
rw [← mul_lt_mul_right hq₀] at h
conv_lhs at h => rw [← abs_of_pos hq₀, ← abs_mul, sub_mul, mul_den_eq_num]
- rwa [sq, div_mul, mul_div_cancel_left _ hq₀.ne'] at h
+ rwa [sq, div_mul, mul_div_cancel_left₀ _ hq₀.ne'] at h
constructor
· rcases eq_or_ne ξ q with (rfl | H)
· exact le_rfl
@@ -440,7 +440,7 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v := by
obtain ⟨hv₀, hv₀'⟩ := aux₀ (zero_lt_two.trans_le hv)
have hv₁ : 0 < 2 * v - 1 := by linarith only [hv]
rw [← one_div, lt_div_iff (mul_pos hv₀ hv₀'), ← abs_of_pos (mul_pos hv₀ hv₀'), ← abs_mul, sub_mul,
- ← mul_assoc, ← mul_assoc, div_mul_cancel _ hv₀.ne', abs_sub_comm, abs_lt, lt_sub_iff_add_lt,
+ ← mul_assoc, ← mul_assoc, div_mul_cancel₀ _ hv₀.ne', abs_sub_comm, abs_lt, lt_sub_iff_add_lt,
sub_lt_iff_lt_add, mul_assoc] at h
have hu₀ : 0 ≤ u - ⌊ξ⌋ * v := by
-- Porting note: this abused the definitional equality `-1 + 1 = 0`
@@ -485,12 +485,12 @@ private theorem aux₃ :
have H₁ := div_pos (div_pos Hv Hu) hξ₀
replace h := h.2.2
have h' : |fract ξ - u' / v| < ((v : ℝ) * (2 * v - 1))⁻¹ := by
- rwa [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm] at h
+ rwa [hu'ℝ, add_div, mul_div_cancel_right₀ _ Hv.ne', ← sub_sub, sub_right_comm] at h
have H : (2 * u' - 1 : ℝ) ≤ (2 * v - 1) * fract ξ := by
replace h := (abs_lt.mp h).1
have : (2 * (v : ℝ) - 1) * (-((v : ℝ) * (2 * v - 1))⁻¹ + u' / v) = 2 * u' - (1 + u') / v := by
field_simp; ring
- rw [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm, self_sub_floor,
+ rw [hu'ℝ, add_div, mul_div_cancel_right₀ _ Hv.ne', ← sub_sub, sub_right_comm, self_sub_floor,
lt_sub_iff_add_lt, ← mul_lt_mul_left Hv', this] at h
refine' LE.le.trans _ h.le
rw [sub_le_sub_iff_left, div_le_one Hv, add_comm]
@@ -574,7 +574,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h' : ContfracLegendre.Ass ξ u v) :
use n + 1
rw [convergent_succ, ← hn,
(mod_cast toNat_of_nonneg huv₀.le : ((u - ⌊ξ⌋ * v).toNat : ℚ) = u - ⌊ξ⌋ * v),
- cast_ofNat, inv_div, sub_div, mul_div_cancel _ Hv, add_sub_cancel'_right]
+ cast_ofNat, inv_div, sub_div, mul_div_cancel_right₀ _ Hv, add_sub_cancel]
#align real.exists_rat_eq_convergent' Real.exists_rat_eq_convergent'
/-- The main result, *Legendre's Theorem* on rational approximation:
@@ -160,7 +160,7 @@ theorem exists_rat_abs_sub_le_and_den_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
refine' ⟨j / k, _, Nat.cast_le.mp (hden.trans hk₁)⟩
rw [← div_div, le_div_iff (Nat.cast_pos.mpr <| Rat.pos _ : (0 : ℝ) < _)]
refine' (mul_le_mul_of_nonneg_left (Int.cast_le.mpr hden : _ ≤ (k : ℝ)) (abs_nonneg _)).trans _
- rwa [← abs_of_pos hk₀', Rat.cast_div, Rat.cast_coe_int, Rat.cast_coe_int, ← abs_mul, sub_mul,
+ rwa [← abs_of_pos hk₀', Rat.cast_div, Rat.cast_intCast, Rat.cast_intCast, ← abs_mul, sub_mul,
div_mul_cancel _ hk₀'.ne', mul_comm]
#align real.exists_rat_abs_sub_le_and_denom_le Real.exists_rat_abs_sub_le_and_den_le
@@ -382,7 +382,7 @@ theorem continued_fraction_convergent_eq_convergent (ξ : ℝ) (n : ℕ) :
(GeneralizedContinuedFraction.of ξ).convergents n = ξ.convergent n := by
induction' n with n ih generalizing ξ
· simp only [Nat.zero_eq, zeroth_convergent_eq_h, of_h_eq_floor, convergent_zero,
- Rat.cast_coe_int]
+ Rat.cast_intCast]
· rw [convergents_succ, ih (fract ξ)⁻¹, convergent_succ, one_div]
norm_cast
#align real.continued_fraction_convergent_eq_convergent Real.continued_fraction_convergent_eq_convergent
I ran tryAtEachStep on all files under Mathlib
to find all locations where omega
succeeds. For each that was a linarith
without an only
, I tried replacing it with omega
, and I verified that elaboration time got smaller. (In almost all cases, there was a noticeable speedup.) I also replaced some slow aesop
s along the way.
@@ -410,7 +410,7 @@ def ContfracLegendre.Ass (ξ : ℝ) (u v : ℤ) : Prop :=
-- ### Auxiliary lemmas
-- This saves a few lines below, as it is frequently needed.
private theorem aux₀ {v : ℤ} (hv : 0 < v) : (0 : ℝ) < v ∧ (0 : ℝ) < 2 * v - 1 :=
- ⟨cast_pos.mpr hv, by norm_cast; linarith⟩
+ ⟨cast_pos.mpr hv, by norm_cast; omega⟩
-- In the following, we assume that `ass ξ u v` holds and `v ≥ 2`.
variable {ξ : ℝ} {u v : ℤ} (hv : 2 ≤ v) (h : ContfracLegendre.Ass ξ u v)
@@ -430,7 +430,7 @@ private theorem aux₁ : 0 < fract ξ := by
norm_cast
rw [← zero_add (1 : ℤ), add_one_le_iff, abs_pos, sub_ne_zero]
rintro rfl
- cases isUnit_iff.mp (isCoprime_self.mp (IsCoprime.mul_left_iff.mp hcop).2) <;> linarith
+ cases isUnit_iff.mp (isCoprime_self.mp (IsCoprime.mul_left_iff.mp hcop).2) <;> omega
norm_cast at H
linarith only [hv, H]
@@ -106,7 +106,7 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
-- Porting note: was
-- simp only [floor_eq_zero_iff, algebraMap.coe_zero, mul_zero, fract_zero,
-- zero_mul, Set.left_mem_Ico, zero_lt_one]
- simp only [cast_zero, mul_zero, fract_zero, zero_mul, floor_zero]
+ simp only [f, cast_zero, mul_zero, fract_zero, zero_mul, floor_zero]
refine' Ne.lt_of_le (fun h => n_pos.ne _) (mem_Icc.mp hm).1
exact mod_cast hf₀.symm.trans (h.symm ▸ hf : f 0 = n)
refine' ⟨⌊ξ * m⌋ + 1, m, hm₀, (mem_Icc.mp hm).2, _⟩
@@ -266,7 +266,7 @@ theorem finite_rat_abs_sub_lt_one_div_den_sq (ξ : ℚ) :
set s := {q : ℚ | |ξ - q| < 1 / (q.den : ℚ) ^ 2}
have hinj : Function.Injective f := by
intro a b hab
- simp only [Prod.mk.inj_iff] at hab
+ simp only [f, Prod.mk.inj_iff] at hab
rw [← Rat.num_div_den a, ← Rat.num_div_den b, hab.1, hab.2]
have H : f '' s ⊆ ⋃ (y : ℕ) (_ : y ∈ Ioc 0 ξ.den), Icc (⌈ξ * y⌉ - 1) (⌊ξ * y⌋ + 1) ×ˢ {y} := by
intro xy hxy
@@ -454,7 +454,7 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v := by
((mul_le_mul_right <| hv₀').mpr <|
(sub_le_sub_iff_left (u : ℝ)).mpr ((mul_le_mul_right hv₀).mpr (floor_le ξ)))
have hu₁ : u - ⌊ξ⌋ * v ≤ v := by
- refine' le_of_mul_le_mul_right (le_of_lt_add_one _) hv₁
+ refine' _root_.le_of_mul_le_mul_right (le_of_lt_add_one _) hv₁
replace h := h.2
rw [← sub_lt_iff_lt_add, ← mul_assoc, ← sub_mul, ← add_lt_add_iff_right (v * (2 * v - 1) : ℝ),
add_comm (1 : ℝ)] at h
@@ -503,7 +503,7 @@ private theorem aux₃ :
calc
|(fract ξ)⁻¹ - v / u'| = |(fract ξ - u' / v) * (v / u' / fract ξ)| :=
help₁ hξ₀.ne' Hv.ne' Hu.ne'
- _ = |fract ξ - u' / v| * (v / u' / fract ξ) := by rw [abs_mul, abs_of_pos H₁, abs_sub_comm]
+ _ = |fract ξ - u' / v| * (v / u' / fract ξ) := by rw [abs_mul, abs_of_pos H₁]
_ < ((v : ℝ) * (2 * v - 1))⁻¹ * (v / u' / fract ξ) := ((mul_lt_mul_right H₁).mpr h')
_ = (u' * (2 * v - 1) * fract ξ)⁻¹ := (help₂ hξ₀.ne' Hv.ne' Hv'.ne' Hu.ne')
_ ≤ ((u' : ℝ) * (2 * u' - 1))⁻¹ := by
have
, replace
and suffices
(#10640)
No changes to tactic file, it's just boring fixes throughout the library.
This follows on from #6964.
Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
@@ -234,8 +234,8 @@ theorem den_le_and_le_num_le_of_sub_lt_one_div_den_sq {ξ q : ℚ}
(h : |ξ - q| < 1 / (q.den : ℚ) ^ 2) :
q.den ≤ ξ.den ∧ ⌈ξ * q.den⌉ - 1 ≤ q.num ∧ q.num ≤ ⌊ξ * q.den⌋ + 1 := by
have hq₀ : (0 : ℚ) < q.den := Nat.cast_pos.mpr q.pos
- replace h : |ξ * q.den - q.num| < 1 / q.den
- · rw [← mul_lt_mul_right hq₀] at h
+ replace h : |ξ * q.den - q.num| < 1 / q.den := by
+ rw [← mul_lt_mul_right hq₀] at h
conv_lhs at h => rw [← abs_of_pos hq₀, ← abs_mul, sub_mul, mul_den_eq_num]
rwa [sq, div_mul, mul_div_cancel_left _ hq₀.ne'] at h
constructor
@@ -5,7 +5,6 @@ Authors: Michael Geißer, Michael Stoll
-/
import Mathlib.Algebra.ContinuedFractions.Computation.ApproximationCorollaries
import Mathlib.Algebra.ContinuedFractions.Computation.Translations
-import Mathlib.Combinatorics.Pigeonhole
import Mathlib.Data.Int.Units
import Mathlib.Data.Real.Irrational
import Mathlib.RingTheory.Coprime.Lemmas
@@ -122,11 +122,10 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
have hwd : ∀ m : ℤ, m ∈ D → f m ∈ Ico (0 : ℤ) n := fun x hx =>
mem_Ico.mpr
⟨floor_nonneg.mpr (mul_nonneg (fract_nonneg (ξ * x)) hn.le), Ne.lt_of_le (H x hx) (hfu' x)⟩
- have : ∃ (x : ℤ) (_ : x ∈ D) (y : ℤ) (_ : y ∈ D), x < y ∧ f x = f y := by
+ obtain ⟨x, hx, y, hy, x_lt_y, hxy⟩ : ∃ x ∈ D, ∃ y ∈ D, x < y ∧ f x = f y := by
obtain ⟨x, hx, y, hy, x_ne_y, hxy⟩ := exists_ne_map_eq_of_card_lt_of_maps_to hD hwd
rcases lt_trichotomy x y with (h | h | h)
exacts [⟨x, hx, y, hy, h, hxy⟩, False.elim (x_ne_y h), ⟨y, hy, x, hx, h, hxy.symm⟩]
- obtain ⟨x, hx, y, hy, x_lt_y, hxy⟩ := this
refine'
⟨⌊ξ * y⌋ - ⌊ξ * x⌋, y - x, sub_pos_of_lt x_lt_y,
sub_le_iff_le_add.mpr <| le_add_of_le_of_nonneg (mem_Icc.mp hy).2 (mem_Icc.mp hx).1, _⟩
0 ≤ a * b ↔ (0 < a → 0 ≤ b) ∧ (0 < b → 0 ≤ a)
(#9219)
I had a slightly logic-heavy argument that was nicely simplified by stating this lemma. Also fix a few lemma names.
From LeanAPAP and LeanCamCombi
@@ -446,8 +446,8 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v := by
sub_lt_iff_lt_add, mul_assoc] at h
have hu₀ : 0 ≤ u - ⌊ξ⌋ * v := by
-- Porting note: this abused the definitional equality `-1 + 1 = 0`
- -- refine' (zero_le_mul_right hv₁).mp ((lt_iff_add_one_le (-1 : ℤ) _).mp _)
- refine' (zero_le_mul_right hv₁).mp ?_
+ -- refine' (mul_nonneg_iff_of_pos_right hv₁).mp ((lt_iff_add_one_le (-1 : ℤ) _).mp _)
+ refine' (mul_nonneg_iff_of_pos_right hv₁).mp ?_
rw [← sub_one_lt_iff, zero_sub]
replace h := h.1
rw [← lt_sub_iff_add_lt, ← mul_assoc, ← sub_mul] at h
cases'
(#9171)
I literally went through and regex'd some uses of cases'
, replacing them with rcases
; this is meant to be a low effort PR as I hope that tools can do this in the future.
rcases
is an easier replacement than cases
, though with better tools we could in future do a second pass converting simple rcases
added here (and existing ones) to cases
.
@@ -545,7 +545,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h' : ContfracLegendre.Ass ξ u v) :
exact False.elim (lt_irrefl _ <| (abs_nonneg ξ).trans_lt h)
· rw [Nat.cast_one, div_one]
obtain ⟨_, h₁, h₂⟩ := h
- cases' le_or_lt (u : ℝ) ξ with ht ht
+ rcases le_or_lt (u : ℝ) ξ with ht | ht
· use 0
rw [convergent_zero, Rat.coe_int_inj, eq_comm, floor_eq_iff]
convert And.intro ht (sub_lt_iff_lt_add'.mp (abs_lt.mp h₂).2) <;> norm_num
@@ -553,7 +553,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h' : ContfracLegendre.Ass ξ u v) :
have hξ₁ : ⌊ξ⌋ = u - 1 := by
rw [floor_eq_iff, cast_sub, cast_one, sub_add_cancel]
exact ⟨(((sub_lt_sub_iff_left _).mpr one_half_lt_one).trans h₁).le, ht⟩
- cases' eq_or_ne ξ ⌊ξ⌋ with Hξ Hξ
+ rcases eq_or_ne ξ ⌊ξ⌋ with Hξ | Hξ
· rw [Hξ, hξ₁, cast_sub, cast_one, ← sub_eq_add_neg, sub_lt_sub_iff_left] at h₁
exact False.elim (lt_irrefl _ <| h₁.trans one_half_lt_one)
· have hξ₂ : ⌊(fract ξ)⁻¹⌋ = 1 := by
@@ -448,7 +448,7 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v := by
-- Porting note: this abused the definitional equality `-1 + 1 = 0`
-- refine' (zero_le_mul_right hv₁).mp ((lt_iff_add_one_le (-1 : ℤ) _).mp _)
refine' (zero_le_mul_right hv₁).mp ?_
- rw [←sub_one_lt_iff, zero_sub]
+ rw [← sub_one_lt_iff, zero_sub]
replace h := h.1
rw [← lt_sub_iff_add_lt, ← mul_assoc, ← sub_mul] at h
exact mod_cast
exact_mod_cast
tactic with mod_cast
elaborator where possible (#8404)
We still have the exact_mod_cast
tactic, used in a few places, which somehow (?) works a little bit harder to prevent the expected type influencing the elaboration of the term. I would like to get to the bottom of this, and it will be easier once the only usages of exact_mod_cast
are the ones that don't work using the term elaborator by itself.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -95,7 +95,7 @@ See also `Real.exists_nat_abs_mul_sub_round_le`. -/
theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
∃ j k : ℤ, 0 < k ∧ k ≤ n ∧ |↑k * ξ - j| ≤ 1 / (n + 1) := by
let f : ℤ → ℤ := fun m => ⌊fract (ξ * m) * (n + 1)⌋
- have hn : 0 < (n : ℝ) + 1 := by exact_mod_cast Nat.succ_pos _
+ have hn : 0 < (n : ℝ) + 1 := mod_cast Nat.succ_pos _
have hfu := fun m : ℤ => mul_lt_of_lt_one_left hn <| fract_lt_one (ξ * ↑m)
conv in |_| ≤ _ => rw [mul_comm, le_div_iff hn, ← abs_of_pos hn, ← abs_mul]
let D := Icc (0 : ℤ) n
@@ -109,7 +109,7 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
-- zero_mul, Set.left_mem_Ico, zero_lt_one]
simp only [cast_zero, mul_zero, fract_zero, zero_mul, floor_zero]
refine' Ne.lt_of_le (fun h => n_pos.ne _) (mem_Icc.mp hm).1
- exact_mod_cast hf₀.symm.trans (h.symm ▸ hf : f 0 = n)
+ exact mod_cast hf₀.symm.trans (h.symm ▸ hf : f 0 = n)
refine' ⟨⌊ξ * m⌋ + 1, m, hm₀, (mem_Icc.mp hm).2, _⟩
rw [cast_add, ← sub_sub, sub_mul, cast_one, one_mul, abs_le]
refine'
@@ -118,7 +118,7 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
· -- Porting note(https://github.com/leanprover-community/mathlib4/issues/5127): added `not_and`
simp_rw [not_exists, not_and] at H
have hD : (Ico (0 : ℤ) n).card < D.card := by rw [card_Icc, card_Ico]; exact lt_add_one n
- have hfu' : ∀ m, f m ≤ n := fun m => lt_add_one_iff.mp (floor_lt.mpr (by exact_mod_cast hfu m))
+ have hfu' : ∀ m, f m ≤ n := fun m => lt_add_one_iff.mp (floor_lt.mpr (mod_cast hfu m))
have hwd : ∀ m : ℤ, m ∈ D → f m ∈ Ico (0 : ℤ) n := fun x hx =>
mem_Ico.mpr
⟨floor_nonneg.mpr (mul_nonneg (fract_nonneg (ξ * x)) hn.le), Ne.lt_of_le (H x hx) (hfu' x)⟩
@@ -196,8 +196,8 @@ theorem exists_rat_abs_sub_lt_and_lt_of_irrational {ξ : ℝ} (hξ : Irrational
(one_div_lt md_pos h).mpr <|
hm.trans <|
lt_of_lt_of_le (lt_add_one _) <|
- (le_mul_iff_one_le_right <| add_pos m_pos zero_lt_one).mpr <| by
- exact_mod_cast (q'.pos : 1 ≤ q'.den)⟩
+ (le_mul_iff_one_le_right <| add_pos m_pos zero_lt_one).mpr <|
+ mod_cast (q'.pos : 1 ≤ q'.den)⟩
rw [sq, one_div_lt_one_div md_pos (mul_pos den_pos den_pos), mul_lt_mul_right den_pos]
exact lt_add_of_le_of_pos (Nat.cast_le.mpr hden) zero_lt_one
#align real.exists_rat_abs_sub_lt_and_lt_of_irrational Real.exists_rat_abs_sub_lt_and_lt_of_irrational
@@ -451,7 +451,7 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v := by
rw [←sub_one_lt_iff, zero_sub]
replace h := h.1
rw [← lt_sub_iff_add_lt, ← mul_assoc, ← sub_mul] at h
- exact_mod_cast
+ exact mod_cast
h.trans_le
((mul_le_mul_right <| hv₀').mpr <|
(sub_le_sub_iff_left (u : ℝ)).mpr ((mul_le_mul_right hv₀).mpr (floor_le ξ)))
@@ -465,7 +465,7 @@ private theorem aux₂ : 0 < u - ⌊ξ⌋ * v ∧ u - ⌊ξ⌋ * v < v := by
((sub_lt_sub_iff_left (u : ℝ)).mpr <|
(mul_lt_mul_right hv₀).mpr <| sub_right_lt_of_lt_add <| lt_floor_add_one ξ)
rw [sub_mul ξ, one_mul, ← sub_add, add_mul] at this
- exact_mod_cast this.trans h
+ exact mod_cast this.trans h
have huv_cop : IsCoprime (u - ⌊ξ⌋ * v) v := by
rwa [sub_eq_add_neg, ← neg_mul, IsCoprime.add_mul_right_left_iff]
refine' ⟨lt_of_le_of_ne' hu₀ fun hf => _, lt_of_le_of_ne hu₁ fun hf => _⟩ <;>
@@ -479,7 +479,7 @@ private theorem aux₃ :
obtain ⟨hu₀, huv⟩ := aux₂ hv h
have hξ₀ := aux₁ hv h
set u' := u - ⌊ξ⌋ * v with hu'
- have hu'ℝ : (u' : ℝ) = u - ⌊ξ⌋ * v := by exact_mod_cast hu'
+ have hu'ℝ : (u' : ℝ) = u - ⌊ξ⌋ * v := mod_cast hu'
rw [← hu'ℝ]
replace hu'ℝ := (eq_sub_iff_add_eq.mp hu'ℝ).symm
obtain ⟨Hu, Hu'⟩ := aux₀ hu₀
@@ -496,7 +496,7 @@ private theorem aux₃ :
lt_sub_iff_add_lt, ← mul_lt_mul_left Hv', this] at h
refine' LE.le.trans _ h.le
rw [sub_le_sub_iff_left, div_le_one Hv, add_comm]
- exact_mod_cast huv
+ exact mod_cast huv
have help₁ : ∀ {a b c : ℝ}, a ≠ 0 → b ≠ 0 → c ≠ 0 → |a⁻¹ - b / c| = |(a - c / b) * (b / c / a)| :=
by intros; rw [abs_sub_comm]; congr 1; field_simp; ring
have help₂ :
@@ -514,7 +514,7 @@ private theorem aux₃ :
-- The conditions `ass ξ u v` persist in the inductive step.
private theorem invariant : ContfracLegendre.Ass (fract ξ)⁻¹ v (u - ⌊ξ⌋ * v) := by
- refine' ⟨_, fun huv => _, by exact_mod_cast aux₃ hv h⟩
+ refine' ⟨_, fun huv => _, mod_cast aux₃ hv h⟩
· rw [sub_eq_add_neg, ← neg_mul, isCoprime_comm, IsCoprime.add_mul_right_left_iff]
exact h.1
· obtain hv₀' := (aux₀ (zero_lt_two.trans_le hv)).2
@@ -575,7 +575,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h' : ContfracLegendre.Ass ξ u v) :
obtain ⟨n, hn⟩ := ih (u - ⌊ξ⌋ * v).toNat huv₁' inv
use n + 1
rw [convergent_succ, ← hn,
- (by exact_mod_cast toNat_of_nonneg huv₀.le : ((u - ⌊ξ⌋ * v).toNat : ℚ) = u - ⌊ξ⌋ * v),
+ (mod_cast toNat_of_nonneg huv₀.le : ((u - ⌊ξ⌋ * v).toNat : ℚ) = u - ⌊ξ⌋ * v),
cast_ofNat, inv_div, sub_div, mul_div_cancel _ Hv, add_sub_cancel'_right]
#align real.exists_rat_eq_convergent' Real.exists_rat_eq_convergent'
The main reasons is that having h : 0 < denom
in the context should suffice for field_simp
to do its job, without the need to manually pass h.ne
or similar.
Quite a few have := … ≠ 0
could be dropped, and some field_simp
calls no longer need explicit arguments; this is promising.
This does break some proofs where field_simp
was not used as a closing tactic, and it now
shuffles terms around a bit different. These were fixed. Using field_simp
in the middle of a proof seems rather fragile anyways.
As a drive-by contribution, positivity
now knows about π > 0
.
fixes: #4835
Co-authored-by: Matthew Ballard <matt@mrb.email>
@@ -427,7 +427,7 @@ private theorem aux₁ : 0 < fract ξ := by
have H : (2 * v - 1 : ℝ) < 1 := by
refine'
(mul_lt_iff_lt_one_right hv₀).mp ((inv_lt_inv hv₀ (mul_pos hv₁ hv₂)).mp (lt_of_le_of_lt _ h))
- have h' : (⌊ξ⌋ : ℝ) - u / v = (⌊ξ⌋ * v - u) / v := by field_simp [hv₀.ne']
+ have h' : (⌊ξ⌋ : ℝ) - u / v = (⌊ξ⌋ * v - u) / v := by field_simp
rw [h', abs_div, abs_of_pos hv₀, ← one_div, div_le_div_right hv₀]
norm_cast
rw [← zero_add (1 : ℤ), add_one_le_iff, abs_pos, sub_ne_zero]
@@ -491,7 +491,7 @@ private theorem aux₃ :
have H : (2 * u' - 1 : ℝ) ≤ (2 * v - 1) * fract ξ := by
replace h := (abs_lt.mp h).1
have : (2 * (v : ℝ) - 1) * (-((v : ℝ) * (2 * v - 1))⁻¹ + u' / v) = 2 * u' - (1 + u') / v := by
- field_simp [Hv.ne', Hv'.ne']; ring
+ field_simp; ring
rw [hu'ℝ, add_div, mul_div_cancel _ Hv.ne', ← sub_sub, sub_right_comm, self_sub_floor,
lt_sub_iff_add_lt, ← mul_lt_mul_left Hv', this] at h
refine' LE.le.trans _ h.le
@@ -517,12 +517,11 @@ private theorem invariant : ContfracLegendre.Ass (fract ξ)⁻¹ v (u - ⌊ξ⌋
refine' ⟨_, fun huv => _, by exact_mod_cast aux₃ hv h⟩
· rw [sub_eq_add_neg, ← neg_mul, isCoprime_comm, IsCoprime.add_mul_right_left_iff]
exact h.1
- · obtain ⟨hv₀, hv₀'⟩ := aux₀ (zero_lt_two.trans_le hv)
+ · obtain hv₀' := (aux₀ (zero_lt_two.trans_le hv)).2
have Hv : (v * (2 * v - 1) : ℝ)⁻¹ + (v : ℝ)⁻¹ = 2 / (2 * v - 1) := by
- field_simp [hv₀.ne', hv₀'.ne']
- ring
+ field_simp; ring
have Huv : (u / v : ℝ) = ⌊ξ⌋ + (v : ℝ)⁻¹ := by
- rw [sub_eq_iff_eq_add'.mp huv]; field_simp [hv₀.ne']
+ rw [sub_eq_iff_eq_add'.mp huv]; field_simp
have h' := (abs_sub_lt_iff.mp h.2.2).1
rw [Huv, ← sub_sub, sub_lt_iff_lt_add, self_sub_floor, Hv] at h'
rwa [lt_sub_iff_add_lt', (by ring : (v : ℝ) + -(1 / 2) = (2 * v - 1) / 2),
MulZeroClass.
in mul_zero
/zero_mul
(#6682)
Search&replace MulZeroClass.mul_zero
-> mul_zero
, MulZeroClass.zero_mul
-> zero_mul
.
These were introduced by Mathport, as the full name of mul_zero
is actually MulZeroClass.mul_zero
(it's exported with the short name).
@@ -105,8 +105,8 @@ theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
have hm₀ : 0 < m := by
have hf₀ : f 0 = 0 := by
-- Porting note: was
- -- simp only [floor_eq_zero_iff, algebraMap.coe_zero, MulZeroClass.mul_zero, fract_zero,
- -- MulZeroClass.zero_mul, Set.left_mem_Ico, zero_lt_one]
+ -- simp only [floor_eq_zero_iff, algebraMap.coe_zero, mul_zero, fract_zero,
+ -- zero_mul, Set.left_mem_Ico, zero_lt_one]
simp only [cast_zero, mul_zero, fract_zero, zero_mul, floor_zero]
refine' Ne.lt_of_le (fun h => n_pos.ne _) (mem_Icc.mp hm).1
exact_mod_cast hf₀.symm.trans (h.symm ▸ hf : f 0 = n)
@@ -541,7 +541,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h' : ContfracLegendre.Ass ξ u v) :
induction v using Nat.strong_induction_on generalizing ξ u with | h v ih => ?_
rcases lt_trichotomy v 1 with (ht | rfl | ht)
· replace h := h.2.2
- simp only [Nat.lt_one_iff.mp ht, Nat.cast_zero, div_zero, tsub_zero, MulZeroClass.zero_mul,
+ simp only [Nat.lt_one_iff.mp ht, Nat.cast_zero, div_zero, tsub_zero, zero_mul,
cast_zero, inv_zero] at h
exact False.elim (lt_irrefl _ <| (abs_nonneg ξ).trans_lt h)
· rw [Nat.cast_one, div_one]
@@ -149,7 +149,9 @@ theorem exists_nat_abs_mul_sub_round_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
/-- *Dirichlet's approximation theorem:*
For any real number `ξ` and positive natural `n`, there is a fraction `q`
-such that `q.den ≤ n` and `|ξ - q| ≤ 1/((n+1)*q.den)`. -/
+such that `q.den ≤ n` and `|ξ - q| ≤ 1/((n+1)*q.den)`.
+
+See also `AddCircle.exists_norm_nsmul_le`. -/
theorem exists_rat_abs_sub_le_and_den_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
∃ q : ℚ, |ξ - q| ≤ 1 / ((n + 1) * q.den) ∧ q.den ≤ n := by
obtain ⟨j, k, hk₀, hk₁, h⟩ := exists_int_int_abs_mul_sub_le ξ n_pos
@@ -2,11 +2,6 @@
Copyright (c) 2022 Michael Stoll. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Michael Geißer, Michael Stoll
-
-! This file was ported from Lean 3 source module number_theory.diophantine_approximation
-! leanprover-community/mathlib commit e25a317463bd37d88e33da164465d8c47922b1cd
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.Algebra.ContinuedFractions.Computation.ApproximationCorollaries
import Mathlib.Algebra.ContinuedFractions.Computation.Translations
@@ -16,6 +11,8 @@ import Mathlib.Data.Real.Irrational
import Mathlib.RingTheory.Coprime.Lemmas
import Mathlib.Tactic.Basic
+#align_import number_theory.diophantine_approximation from "leanprover-community/mathlib"@"e25a317463bd37d88e33da164465d8c47922b1cd"
+
/-!
# Diophantine Approximation
@@ -582,7 +582,7 @@ theorem exists_rat_eq_convergent' {v : ℕ} (h' : ContfracLegendre.Ass ξ u v) :
#align real.exists_rat_eq_convergent' Real.exists_rat_eq_convergent'
/-- The main result, *Legendre's Theorem* on rational approximation:
-if `ξ` is a real number and `q` is a rational number such that `|ξ - q| < 1/(2*q.den^2)`,
+if `ξ` is a real number and `q` is a rational number such that `|ξ - q| < 1/(2*q.den^2)`,
then `q` is a convergent of the continued fraction expansion of `ξ`.
This version uses `Real.convergent`. -/
theorem exists_rat_eq_convergent {q : ℚ} (h : |ξ - q| < 1 / (2 * (q.den : ℝ) ^ 2)) :
@@ -600,7 +600,7 @@ theorem exists_rat_eq_convergent {q : ℚ} (h : |ξ - q| < 1 / (2 * (q.den : ℝ
#align real.exists_rat_eq_convergent Real.exists_rat_eq_convergent
/-- The main result, *Legendre's Theorem* on rational approximation:
-if `ξ` is a real number and `q` is a rational number such that `|ξ - q| < 1/(2*q.den^2)`,
+if `ξ` is a real number and `q` is a rational number such that `|ξ - q| < 1/(2*q.den^2)`,
then `q` is a convergent of the continued fraction expansion of `ξ`.
This is the version using `generalized_contined_fraction.convergents`. -/
theorem exists_continued_fraction_convergent_eq_rat {q : ℚ}
The unported dependencies are
algebra.order.module
data.lazy_list
init.core
linear_algebra.free_module.finite.rank
algebra.order.monoid.cancel.defs
algebra.abs
algebra.group_power.lemmas
init.data.list.basic
linear_algebra.free_module.rank
algebra.order.monoid.cancel.basic
init.data.list.default
topology.subset_properties
init.logic
The following 1 dependencies have changed in mathlib3 since they were ported, which may complicate porting this file