Imports
import Mathlib.Tactic

Analysis I, Section 4.4: gaps in the rational numbers

I have attempted to make the translation as faithful a paraphrasing as possible of the original text. When there is a choice between a more idiomatic Lean solution and a more faithful translation, I have generally chosen the latter. In particular, there will be places where the Lean code could be "golfed" to be more elegant and idiomatic, but I have consciously avoided doing so.

Main constructions and results of this section:

  • Irrationality of √2, and related facts about the rational numbers

Many of the results here can be established more quickly by relying more heavily on the Mathlib API; one can set oneself the exercise of doing so.

Tips from past users

Users of the companion who have completed the exercises in this section are welcome to send their tips for future users in this section as PRs.

  • (Add tip here)

Proposition 4.4.1 (Interspersing of integers by rationals) / Exercise 4.4.1

theorem declaration uses `sorry`Rat.between_int (x:) : ∃! n:, n x x < n+1 := x:∃! n, n x x < n + 1 All goals completed! 🐙
theorem declaration uses `sorry`Nat.exists_gt (x:) : n:, n > x := x: n, n > x All goals completed! 🐙

Proposition 4.4.3 (Interspersing of rationals)

theorem Rat.exists_between_rat {x y:} (h: x < y) : z:, x < z z < y := x:y:h:x < y z, x < z z < y -- This proof is written to follow the structure of the original text. -- The reader is encouraged to find shorter proofs, for instance -- using Mathlib's `linarith` tactic. x:y:h:x < yx < (x + y) / 2 (x + y) / 2 < y have h' : x/2 < y/2 := x:y:h:x < y z, x < z z < y x:y:h:x < yx * (1 / 2) < y * (1 / 2) x:y:h:x < y0 < 1 / 2; All goals completed! 🐙 x:y:h:x < yh':x / 2 < y / 2x < (x + y) / 2x:y:h:x < yh':x / 2 < y / 2(x + y) / 2 < y x:y:h:x < yh':x / 2 < y / 2x < (x + y) / 2 x:y:h:x < yh':x / 2 < y / 2x = x / 2 + x / 2x:y:h:x < yh':x / 2 < y / 2(x + y) / 2 = x / 2 + y / 2 x:y:h:x < yh':x / 2 < y / 2x = x / 2 + x / 2x:y:h:x < yh':x / 2 < y / 2(x + y) / 2 = x / 2 + y / 2 All goals completed! 🐙 x:y:h:x < yh':x / 2 < y / 2(x + y) / 2 = y / 2 + x / 2x:y:h:x < yh':x / 2 < y / 2y = y / 2 + y / 2 x:y:h:x < yh':x / 2 < y / 2(x + y) / 2 = y / 2 + x / 2x:y:h:x < yh':x / 2 < y / 2y = y / 2 + y / 2 All goals completed! 🐙

Exercise 4.4.2 (a)

theorem declaration uses `sorry`Nat.no_infinite_descent : ¬ a: , n, a (n+1) < a n := ¬ a, (n : ), a (n + 1) < a n All goals completed! 🐙

Exercise 4.4.2 (b)

def declaration uses `sorry`Int.infinite_descent : Decidable ( a: , n, a (n+1) < a n) := Decidable (∃ a, (n : ), a (n + 1) < a n) -- the first line of this construction should be either `apply isTrue` or `apply isFalse`. All goals completed! 🐙

Exercise 4.4.2 (b)

def declaration uses `sorry`Rat.pos_infinite_descent : Decidable ( a: {x: // 0 < x}, n, a (n+1) < a n) := Decidable (∃ a, (n : ), a (n + 1) < a n) -- the first line of this construction should be either `apply isTrue` or `apply isFalse`. All goals completed! 🐙
even_iff_exists_two_mul.{u_2} {α : Type u_2} [Semiring α] {a : α} : Even a b, a = 2 * b#check even_iff_exists_two_mul
even_iff_exists_two_mul.{u_2} {α : Type u_2} [Semiring α] {a : α} : Even a   b, a = 2 * b
odd_iff_exists_bit1.{u_2} {α : Type u_2} [Semiring α] {a : α} : Odd a b, a = 2 * b + 1#check odd_iff_exists_bit1
odd_iff_exists_bit1.{u_2} {α : Type u_2} [Semiring α] {a : α} : Odd a   b, a = 2 * b + 1
theorem declaration uses `sorry`Nat.even_or_odd'' (n:) : Even n Odd n := n:Even n Odd n All goals completed! 🐙theorem declaration uses `sorry`Nat.not_even_and_odd (n:) : ¬ (Even n Odd n) := n:¬(Even n Odd n) All goals completed! 🐙Nat.rec.{u} {motive : Sort u} (zero : motive Nat.zero) (succ : (n : ) motive n motive n.succ) (t : ) : motive t#check Nat.rec
Nat.rec.{u} {motive :   Sort u} (zero : motive Nat.zero) (succ : (n : )  motive n  motive n.succ) (t : ) :
  motive t

Proposition 4.4.4 / Exercise 4.4.3

theorem declaration uses `sorry`Rat.not_exist_sqrt_two : ¬ x:, x^2 = 2 := ¬ x, x ^ 2 = 2 -- This proof is written to follow the structure of the original text. h: x, x ^ 2 = 2False; x:hx:x ^ 2 = 2False have hnon : x 0 := ¬ x, x ^ 2 = 2 All goals completed! 🐙 x:hx:x ^ 2 = 2hnon:x 0this: (x : ), x ^ 2 = 2 x 0 x > 0 Falsehpos:¬x > 0Falsex:hx:x ^ 2 = 2hnon:x 0hpos:x > 0False x:hx:x ^ 2 = 2hnon:x 0this: (x : ), x ^ 2 = 2 x 0 x > 0 Falsehpos:¬x > 0False apply this _ _ _ (show -x>0 ¬ x, x ^ 2 = 2 x:hx:x ^ 2 = 2hnon:x 0this: (x : ), x ^ 2 = 2 x 0 x > 0 Falsehpos:¬x > 0x < 0; All goals completed! 🐙) x:hx:x ^ 2 = 2hnon:x 0this: (x : ), x ^ 2 = 2 x 0 x > 0 Falsehpos:¬x > 0(-x) ^ 2 = 2x:hx:x ^ 2 = 2hnon:x 0this: (x : ), x ^ 2 = 2 x 0 x > 0 Falsehpos:¬x > 0-x 0 All goals completed! 🐙 have hrep : p q:, p > 0 q > 0 p^2 = 2*q^2 := ¬ x, x ^ 2 = 2 x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0x.num.toNat > 0 x.den > 0 x.num.toNat ^ 2 = 2 * x.den ^ 2 x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hnum_pos:0 < x.numx.num.toNat > 0 x.den > 0 x.num.toNat ^ 2 = 2 * x.den ^ 2 x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hnum_pos:0 < x.numhden_pos:0 < x.denx.num.toNat > 0 x.den > 0 x.num.toNat ^ 2 = 2 * x.den ^ 2 refine x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hnum_pos:0 < x.numhden_pos:0 < x.denx.num.toNat > 0 All goals completed! 🐙, hden_pos, ?_ x:hx:(x.num / x.den) ^ 2 = 2hnon:x 0hpos:x > 0hnum_pos:0 < x.numhden_pos:0 < x.denx.num.toNat ^ 2 = 2 * x.den ^ 2; x:hnon:x 0hpos:x > 0hnum_pos:0 < x.numhden_pos:0 < x.denhx:x.num ^ 2 = x.den ^ 2 * 2x.num.toNat ^ 2 = 2 * x.den ^ 2 have hnum_cast : x.num = x.num.toNat := Int.eq_natCast_toNat.mpr (x:hnon:x 0hpos:x > 0hnum_pos:0 < x.numhden_pos:0 < x.denhx:x.num ^ 2 = x.den ^ 2 * 20 x.num All goals completed! 🐙) x:hnon:x 0hpos:x > 0hnum_pos:0 < x.numhden_pos:0 < x.denhx:x.num.toNat ^ 2 = x.den ^ 2 * 2hnum_cast:x.num = x.num.toNatx.num.toNat ^ 2 = 2 * x.den ^ 2; x:hnon:x 0hpos:x > 0hnum_pos:0 < x.numhden_pos:0 < x.denhnum_cast:x.num = x.num.toNathx:x.num.toNat ^ 2 = x.den ^ 2 * 2x.num.toNat ^ 2 = 2 * x.den ^ 2; All goals completed! 🐙 x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2False have hP : p, P p := ¬ x, x ^ 2 = 2 All goals completed! 🐙 have hiter (p:) (hPp: P p) : q, q < p P q := ¬ x, x ^ 2 = 2 x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pp:hPp:P php:Even p q < p, P qx:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pp:hPp:P php:Odd p q < p, P q x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pp:hPp:P php:Even p q < p, P q x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pp:hPp:P php: b, p = 2 * b q < p, P q x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pk:hPp:P (2 * k) q < 2 * k, P q x:hx:x ^ 2 = 2hnon:x 0hpos✝:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pk:hPp:P (2 * k)q:hpos:q > 0hq:(2 * k) ^ 2 = 2 * q ^ 2 q < 2 * k, P q have : q^2 = 2 * k^2 := ¬ x, x ^ 2 = 2 All goals completed! 🐙 x:hx:x ^ 2 = 2hnon:x 0hpos✝:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pk:hPp:P (2 * k)q:hpos:q > 0hq:(2 * k) ^ 2 = 2 * q ^ 2this:q ^ 2 = 2 * k ^ 2q < 2 * k P q; x:hx:x ^ 2 = 2hnon:x 0hpos✝:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pk:hPp:P (2 * k)q:hpos:q > 0hq:(2 * k) ^ 2 = 2 * q ^ 2this:q ^ 2 = 2 * k ^ 2q < 2 * kx:hx:x ^ 2 = 2hnon:x 0hpos✝:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pk:hPp:P (2 * k)q:hpos:q > 0hq:(2 * k) ^ 2 = 2 * q ^ 2this:q ^ 2 = 2 * k ^ 2P q x:hx:x ^ 2 = 2hnon:x 0hpos✝:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pk:hPp:P (2 * k)q:hpos:q > 0hq:(2 * k) ^ 2 = 2 * q ^ 2this:q ^ 2 = 2 * k ^ 2q < 2 * k All goals completed! 🐙 exact hpos, k, x:hx:x ^ 2 = 2hnon:x 0hpos✝:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pk:hPp:P (2 * k)q:hpos:q > 0hq:(2 * k) ^ 2 = 2 * q ^ 2this:q ^ 2 = 2 * k ^ 2k > 0 All goals completed! 🐙, this have h1 : Odd (p^2) := ¬ x, x ^ 2 = 2 All goals completed! 🐙 have h2 : Even (p^2) := ¬ x, x ^ 2 = 2 x:hx:x ^ 2 = 2hnon:x 0hpos✝:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pp:hPp:P php:Odd ph1:Odd (p ^ 2)q:hpos:q > 0hq:p ^ 2 = 2 * q ^ 2Even (p ^ 2) x:hx:x ^ 2 = 2hnon:x 0hpos✝:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pp:hPp:P php:Odd ph1:Odd (p ^ 2)q:hpos:q > 0hq:p ^ 2 = 2 * q ^ 2 b, p ^ 2 = 2 * b All goals completed! 🐙 x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P pp:hPp:P php:Odd ph1:Odd (p ^ 2)h2:Even (p ^ 2)this:¬(Even (p ^ 2) Odd (p ^ 2)) q < p, P q All goals completed! 🐙 classical x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P phiter: (p : ), P p q < p, P qf: := fun p if hPp : P p then .choose else 0False have hf (p:) (hPp: P p) : (f p < p) P (f p) := ¬ x, x ^ 2 = 2 x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hP: p, P phiter: (p : ), P p q < p, P qf: := fun p if hPp : P p then .choose else 0p:hPp:P p.choose < p P .choose; All goals completed! 🐙 x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hiter: (p : ), P p q < p, P qf: := fun p if hPp : P p then .choose else 0hf: (p : ), P p f p < p P (f p)p:hP:P pFalse x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hiter: (p : ), P p q < p, P qf: := fun p if hPp : P p then .choose else 0hf: (p : ), P p f p < p P (f p)p:hP:P pa: := fun t Nat.rec p (fun n p f p) tFalse have ha (n:) : P (a n) := ¬ x, x ^ 2 = 2 induction n with x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hiter: (p : ), P p q < p, P qf: := fun p if hPp : P p then .choose else 0hf: (p : ), P p f p < p P (f p)p:hP:P pa: := fun t Nat.rec p (fun n p f p) tP (a 0) All goals completed! 🐙 x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hiter: (p : ), P p q < p, P qf: := fun p if hPp : P p then .choose else 0hf: (p : ), P p f p < p P (f p)p:hP:P pa: := fun t Nat.rec p (fun n p f p) tn:ih:P (a n)P (a (n + 1)) All goals completed! 🐙 have hlt (n:) : a (n+1) < a n := ¬ x, x ^ 2 = 2 x:hx:x ^ 2 = 2hnon:x 0hpos:x > 0hrep: p q, p > 0 q > 0 p ^ 2 = 2 * q ^ 2P: Prop := fun p p > 0 q > 0, p ^ 2 = 2 * q ^ 2hiter: (p : ), P p q < p, P qf: := fun p if hPp : P p then .choose else 0hf: (p : ), P p f p < p P (f p)p:hP:P pa: := fun t Nat.rec p (fun n p f p) tha: (n : ), P (a n)n:this:a (n + 1) = f (a n)a (n + 1) < a n All goals completed! 🐙 All goals completed! 🐙

Proposition 4.4.5

theorem Rat.exist_approx_sqrt_two {ε:} (:ε>0) : x (0:), x^2 < 2 2 < (x+ε)^2 := ε::ε > 0 x 0, x ^ 2 < 2 2 < (x + ε) ^ 2 -- This proof is written to follow the structure of the original text. ε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2False have (n:): (n*ε)^2 < 2 := ε::ε > 0 x 0, x ^ 2 < 2 2 < (x + ε) ^ 2 ε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2(0 * ε) ^ 2 < 2ε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2n:hn:(n * ε) ^ 2 < 2((n + 1) * ε) ^ 2 < 2; ε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2n:hn:(n * ε) ^ 2 < 2((n + 1) * ε) ^ 2 < 2 ε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2n:hn:(n * ε) ^ 2 < 2(n * ε + ε) ^ 2 < 2 apply lt_of_le_of_ne (h (n*ε) (ε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2n:hn:(n * ε) ^ 2 < 2n * ε 0 All goals completed! 🐙) hn) ε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2n:hn:(n * ε) ^ 2 < 2this:¬ x, x ^ 2 = 2(n * ε + ε) ^ 2 2 All goals completed! 🐙 ε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2this: (n : ), (n * ε) ^ 2 < 2n:hn:n > 2 / εFalse ε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2this: (n : ), (n * ε) ^ 2 < 2n:hn:2 ^ 2 < (n * ε) ^ 2Falseε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2this: (n : ), (n * ε) ^ 2 < 2n:hn:2 < n * ε0 2ε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2this: (n : ), (n * ε) ^ 2 < 2n:hn:2 < n * ε0 n * εε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2this: (n : ), (n * ε) ^ 2 < 2n:hn:2 / ε < n0 < ε ε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2this: (n : ), (n * ε) ^ 2 < 2n:hn:2 ^ 2 < (n * ε) ^ 2Falseε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2this: (n : ), (n * ε) ^ 2 < 2n:hn:2 < n * ε0 2ε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2this: (n : ), (n * ε) ^ 2 < 2n:hn:2 < n * ε0 n * εε::ε > 0h: x 0, x ^ 2 < 2 (x + ε) ^ 2 2this: (n : ), (n * ε) ^ 2 < 2n:hn:2 / ε < n0 < ε try All goals completed! 🐙 All goals completed! 🐙
/-- Example 4.4.6 -/ example : let ε: := 1/1000 let x: := 1414/1000 x^2 < 2 2 < (x+ε)^2 := let ε := 1 / 1000; let x := 1414 / 1000; x ^ 2 < 2 2 < (x + ε) ^ 2 All goals completed! 🐙