Path: blob/master/src/solutions/tuto_lib.lean
292 views
import analysis.specific_limits.basic
import data.int.parity
import topology.sequences
attribute [instance] classical.prop_decidable
/-
Lemmas from that file were hidden in my course, or restating things which
were proved without name in previous files.
-/
notation `|`x`|` := abs x
-- The mathlib version is unusable because it is stated in terms of ≤
lemma ge_max_iff {α : Type*} [linear_order α] {p q r : α} : r ≥ max p q ↔ r ≥ p ∧ r ≥ q :=
max_le_iff
/- No idea why this is not in mathlib-/
lemma eq_of_abs_sub_le_all (x y : ℝ) : (∀ ε > 0, |x - y| ≤ ε) → x = y :=
begin
intro h,
apply eq_of_abs_sub_nonpos,
by_contradiction H,
push_neg at H,
specialize h ( |x-y|/2) (by linarith),
linarith,
end
def seq_limit (u : ℕ → ℝ) (l : ℝ) : Prop :=
∀ ε > 0, ∃ N, ∀ n ≥ N, |u n - l| ≤ ε
lemma unique_limit {u l l'} : seq_limit u l → seq_limit u l' → l = l' :=
begin
intros hl hl',
apply eq_of_abs_sub_le_all,
intros ε ε_pos,
specialize hl (ε/2) (by linarith),
cases hl with N hN,
specialize hl' (ε/2) (by linarith),
cases hl' with N' hN',
specialize hN (max N N') (le_max_left _ _),
specialize hN' (max N N') (le_max_right _ _),
calc |l - l'| = |(l-u (max N N')) + (u (max N N') -l')| : by ring_nf
... ≤ |l - u (max N N')| + |u (max N N') - l'| : by apply abs_add
... = |u (max N N') - l| + |u (max N N') - l'| : by rw abs_sub_comm
... ≤ ε/2 + ε/2 : by linarith
... = ε : by ring,
end
lemma le_of_le_add_all {x y : ℝ} :
(∀ ε > 0, y ≤ x + ε) → y ≤ x :=
begin
contrapose!,
intro h,
use (y-x)/2,
split ; linarith,
end
def upper_bound (A : set ℝ) (x : ℝ) := ∀ a ∈ A, a ≤ x
def is_sup (A : set ℝ) (x : ℝ) := upper_bound A x ∧ ∀ y, upper_bound A y → x ≤ y
lemma lt_sup {A : set ℝ} {x : ℝ} (hx : is_sup A x) :
∀ y, y < x → ∃ a ∈ A, y < a :=
begin
intro y,
contrapose!,
exact hx.right y,
end
lemma squeeze {u v w : ℕ → ℝ} {l} (hu : seq_limit u l) (hw : seq_limit w l)
(h : ∀ n, u n ≤ v n)
(h' : ∀ n, v n ≤ w n) : seq_limit v l :=
begin
intros ε ε_pos,
cases hu ε ε_pos with N hN,
cases hw ε ε_pos with N' hN',
use max N N',
intros n hn,
rw ge_max_iff at hn,
specialize hN n (by linarith),
specialize hN' n (by linarith),
specialize h n,
specialize h' n,
rw abs_le at *,
split ; linarith
end
def extraction (φ : ℕ → ℕ) := ∀ n m, n < m → φ n < φ m
def tendsto_infinity (u : ℕ → ℝ) := ∀ A, ∃ N, ∀ n ≥ N, u n ≥ A
lemma lim_le {x y : ℝ} {u : ℕ → ℝ} (hu : seq_limit u x)
(ineg : ∀ n, u n ≤ y) : x ≤ y :=
begin
apply le_of_le_add_all,
intros ε ε_pos,
cases hu ε ε_pos with N hN,
specialize hN N (by linarith),
specialize ineg N,
rw abs_le at hN,
linarith,
end
lemma inv_succ_le_all : ∀ ε > 0, ∃ N : ℕ, ∀ n ≥ N, 1/(n + 1 : ℝ) ≤ ε :=
begin
convert metric.tendsto_at_top.mp (tendsto_one_div_add_at_top_nhds_0_nat),
apply propext,
simp only [real.dist_eq, sub_zero],
split,
intros h ε ε_pos,
cases h (ε/2) (by linarith) with N hN,
use N,
intros n hn,
rw abs_of_pos (nat.one_div_pos_of_nat : 1/(n+1 : ℝ) > 0),
specialize hN n hn,
linarith,
intros h ε ε_pos,
cases h ε (by linarith) with N hN,
use N,
intros n hn,
specialize hN n hn,
rw abs_of_pos (@nat.one_div_pos_of_nat ℝ _ n) at hN,
linarith,
end
lemma limit_const (x : ℝ) : seq_limit (λ n, x) x :=
λ ε ε_pos, ⟨0, λ _ _, by simp [le_of_lt ε_pos]⟩
lemma limit_of_sub_le_inv_succ {u : ℕ → ℝ} {x : ℝ} (h : ∀ n, |u n - x| ≤ 1/(n+1)) :
seq_limit u x :=
begin
intros ε ε_pos,
rcases inv_succ_le_all ε ε_pos with ⟨N, hN⟩,
use N,
intros n hn,
specialize h n,
specialize hN n hn,
linarith,
end
lemma limit_const_add_inv_succ (x : ℝ) : seq_limit (λ n, x + 1/(n+1)) x :=
limit_of_sub_le_inv_succ (λ n, by rw abs_of_pos ; linarith [@nat.one_div_pos_of_nat ℝ _ n])
lemma limit_const_sub_inv_succ (x : ℝ) : seq_limit (λ n, x - 1/(n+1)) x :=
begin
refine limit_of_sub_le_inv_succ (λ n, _),
rw [show x - 1 / (n + 1) - x = -(1/(n+1)), by ring, abs_neg, abs_of_pos],
linarith [@nat.one_div_pos_of_nat ℝ _ n]
end
lemma id_le_extraction {φ}: extraction φ → ∀ n, n ≤ φ n :=
begin
intros hyp n,
induction n with n hn,
{ exact nat.zero_le _ },
{ exact nat.succ_le_of_lt (by linarith [hyp n (n+1) (by linarith)]) },
end
lemma seq_limit_id : tendsto_infinity (λ n, n) :=
begin
intros A,
cases exists_nat_gt A with N hN,
use N,
intros n hn,
have : (n : ℝ) ≥ N, exact_mod_cast hn,
linarith,
end
variables {u : ℕ → ℝ} {l : ℝ} {φ : ℕ → ℕ}
open set filter
def cluster_point (u : ℕ → ℝ) (a : ℝ) :=
∃ φ, extraction φ ∧ seq_limit (u ∘ φ) a
lemma bolzano_weierstrass {a b : ℝ} {u : ℕ → ℝ} (h : ∀ n, u n ∈ Icc a b) :
∃ c ∈ Icc a b, cluster_point u c :=
begin
rcases (is_compact_Icc : is_compact (Icc a b)).tendsto_subseq h with ⟨c, c_in, φ, hφ, lim⟩,
use [c, c_in, φ, hφ],
simp_rw [metric.tendsto_nhds, eventually_at_top, real.dist_eq] at lim,
intros ε ε_pos,
rcases lim ε ε_pos with ⟨N, hN⟩,
use N,
intros n hn,
exact le_of_lt (hN n hn)
end
lemma not_seq_limit_of_tendstoinfinity {u : ℕ → ℝ} :
tendsto_infinity u → ∀ x, ¬ seq_limit u x :=
begin
intros lim_infinie x lim_x,
cases lim_x 1 (by linarith) with N hN,
cases lim_infinie (x+2) with N' hN',
let N₀ := max N N',
specialize hN N₀ (le_max_left _ _),
specialize hN' N₀ (le_max_right _ _),
rw abs_le at hN,
linarith,
end
open real
lemma sup_segment {a b : ℝ} {A : set ℝ} (hnonvide : ∃ x, x ∈ A) (h : A ⊆ Icc a b) :
∃ x ∈ Icc a b, is_sup A x :=
begin
have b_maj : ∀ (y : ℝ), y ∈ A → y ≤ b,
from λ y y_in, (h y_in).2,
have Sup_maj : upper_bound A (Sup A),
{ intro x,
apply le_cSup,
use [b, b_maj] } ,
refine ⟨Sup A, _, _⟩,
{ split,
{ cases hnonvide with x x_in,
exact le_trans (h x_in).1 (Sup_maj _ x_in) },
{ apply cSup_le hnonvide b_maj } },
{ exact ⟨Sup_maj, λ y, cSup_le hnonvide⟩ },
end
lemma subseq_tendsto_of_tendsto (h : seq_limit u l) (hφ : extraction φ) :
seq_limit (u ∘ φ) l :=
begin
intros ε ε_pos,
cases h ε ε_pos with N hN,
use N,
intros n hn,
apply hN,
calc N ≤ n : hn
... ≤ φ n : id_le_extraction hφ n,
end
namespace tactic.interactive
open tactic
meta def check_me : tactic unit :=
`[ { repeat { unfold seq_limit},
repeat { unfold continue_en },
push_neg,
try { simp only [exists_prop] },
try { exact iff.rfl },
done } <|> fail "That's not quite right. Please try again." ]
end tactic.interactive