Module docstring
{"# Cauchy completion
This file generalizes the Cauchy completion of (ℚ, abs) to the completion of a ring
with absolute value.
"}
{"# Cauchy completion
This file generalizes the Cauchy completion of (ℚ, abs) to the completion of a ring
with absolute value.
"}
CauSeq.Completion.Cauchy
definition
/-- The Cauchy completion of a ring with absolute value. -/
def Cauchy :=
@Quotient (CauSeq _ abv) CauSeq.equiv
CauSeq.Completion.mk
definition
: CauSeq _ abv → Cauchy abv
/-- The map from Cauchy sequences into the Cauchy completion. -/
def mk : CauSeq _ abv → Cauchy abv :=
Quotient.mk''
CauSeq.Completion.mk_eq_mk
theorem
(f : CauSeq _ abv) : @Eq (Cauchy abv) ⟦f⟧ (mk f)
CauSeq.Completion.mk_eq
theorem
{f g : CauSeq _ abv} : mk f = mk g ↔ f ≈ g
theorem mk_eq {f g : CauSeq _ abv} : mkmk f = mk g ↔ f ≈ g :=
Quotient.eq
CauSeq.Completion.ofRat
definition
(x : β) : Cauchy abv
CauSeq.Completion.instZeroCauchy
instance
: Zero (Cauchy abv)
CauSeq.Completion.instOneCauchy
instance
: One (Cauchy abv)
CauSeq.Completion.instInhabitedCauchy
instance
: Inhabited (Cauchy abv)
CauSeq.Completion.ofRat_zero
theorem
: (ofRat 0 : Cauchy abv) = 0
theorem ofRat_zero : (ofRat 0 : Cauchy abv) = 0 :=
rfl
CauSeq.Completion.ofRat_one
theorem
: (ofRat 1 : Cauchy abv) = 1
CauSeq.Completion.mk_eq_zero
theorem
{f : CauSeq _ abv} : mk f = 0 ↔ LimZero f
@[simp]
theorem mk_eq_zero {f : CauSeq _ abv} : mkmk f = 0 ↔ LimZero f := by
have : mkmk f = 0 ↔ LimZero (f - 0) := Quotient.eq
rwa [sub_zero] at this
CauSeq.Completion.instAddCauchy
instance
: Add (Cauchy abv)
instance : Add (Cauchy abv) :=
⟨(Quotient.map₂ (· + ·)) fun _ _ hf _ _ hg => add_equiv_add hf hg⟩
CauSeq.Completion.mk_add
theorem
(f g : CauSeq β abv) : mk f + mk g = mk (f + g)
CauSeq.Completion.instNegCauchy
instance
: Neg (Cauchy abv)
instance : Neg (Cauchy abv) :=
⟨(Quotient.map Neg.neg) fun _ _ hf => neg_equiv_neg hf⟩
CauSeq.Completion.mk_neg
theorem
(f : CauSeq β abv) : -mk f = mk (-f)
CauSeq.Completion.instMulCauchy
instance
: Mul (Cauchy abv)
instance : Mul (Cauchy abv) :=
⟨(Quotient.map₂ (· * ·)) fun _ _ hf _ _ hg => mul_equiv_mul hf hg⟩
CauSeq.Completion.mk_mul
theorem
(f g : CauSeq β abv) : mk f * mk g = mk (f * g)
CauSeq.Completion.instSubCauchy
instance
: Sub (Cauchy abv)
instance : Sub (Cauchy abv) :=
⟨(Quotient.map₂ Sub.sub) fun _ _ hf _ _ hg => sub_equiv_sub hf hg⟩
CauSeq.Completion.mk_sub
theorem
(f g : CauSeq β abv) : mk f - mk g = mk (f - g)
CauSeq.Completion.instSMulCauchyOfIsScalarTower
instance
{γ : Type*} [SMul γ β] [IsScalarTower γ β β] : SMul γ (Cauchy abv)
instance {γ : Type*} [SMul γ β] [IsScalarTower γ β β] : SMul γ (Cauchy abv) :=
⟨fun c => (Quotient.map (c • ·)) fun _ _ hf => smul_equiv_smul _ hf⟩
CauSeq.Completion.mk_smul
theorem
{γ : Type*} [SMul γ β] [IsScalarTower γ β β] (c : γ) (f : CauSeq β abv) : c • mk f = mk (c • f)
CauSeq.Completion.instPowCauchyNat
instance
: Pow (Cauchy abv) ℕ
instance : Pow (Cauchy abv) ℕ :=
⟨fun x n => Quotient.map (· ^ n) (fun _ _ hf => pow_equiv_pow hf _) x⟩
CauSeq.Completion.mk_pow
theorem
(n : ℕ) (f : CauSeq β abv) : mk f ^ n = mk (f ^ n)
CauSeq.Completion.instNatCastCauchy
instance
: NatCast (Cauchy abv)
instance : NatCast (Cauchy abv) :=
⟨fun n => mk n⟩
CauSeq.Completion.instIntCastCauchy
instance
: IntCast (Cauchy abv)
instance : IntCast (Cauchy abv) :=
⟨fun n => mk n⟩
CauSeq.Completion.ofRat_natCast
theorem
(n : ℕ) : (ofRat n : Cauchy abv) = n
@[simp]
theorem ofRat_natCast (n : ℕ) : (ofRat n : Cauchy abv) = n :=
rfl
CauSeq.Completion.ofRat_intCast
theorem
(z : ℤ) : (ofRat z : Cauchy abv) = z
@[simp]
theorem ofRat_intCast (z : ℤ) : (ofRat z : Cauchy abv) = z :=
rfl
CauSeq.Completion.ofRat_add
theorem
(x y : β) : ofRat (x + y) = (ofRat x + ofRat y : Cauchy abv)
CauSeq.Completion.ofRat_neg
theorem
(x : β) : ofRat (-x) = (-ofRat x : Cauchy abv)
CauSeq.Completion.ofRat_mul
theorem
(x y : β) : ofRat (x * y) = (ofRat x * ofRat y : Cauchy abv)
CauSeq.Completion.Cauchy.ring
instance
: Ring (Cauchy abv)
instance Cauchy.ring : Ring (Cauchy abv) := fast_instance%
Function.Surjective.ring mk Quotient.mk'_surjective zero_def.symm one_def.symm
(fun _ _ => (mk_add _ _).symm) (fun _ _ => (mk_mul _ _).symm) (fun _ => (mk_neg _).symm)
(fun _ _ => (mk_sub _ _).symm) (fun _ _ => (mk_smul _ _).symm) (fun _ _ => (mk_smul _ _).symm)
(fun _ _ => (mk_pow _ _).symm) (fun _ => rfl) fun _ => rfl
CauSeq.Completion.ofRatRingHom
definition
: β →+* (Cauchy abv)
/-- `CauSeq.Completion.ofRat` as a `RingHom` -/
@[simps]
def ofRatRingHom : β →+* (Cauchy abv) where
toFun := ofRat
map_zero' := ofRat_zero
map_one' := ofRat_one
map_add' := ofRat_add
map_mul' := ofRat_mul
CauSeq.Completion.ofRat_sub
theorem
(x y : β) : ofRat (x - y) = (ofRat x - ofRat y : Cauchy abv)
CauSeq.Completion.Cauchy.commRing
instance
: CommRing (Cauchy abv)
instance Cauchy.commRing : CommRing (Cauchy abv) := fast_instance%
Function.Surjective.commRing mk Quotient.mk'_surjective zero_def.symm one_def.symm
(fun _ _ => (mk_add _ _).symm) (fun _ _ => (mk_mul _ _).symm) (fun _ => (mk_neg _).symm)
(fun _ _ => (mk_sub _ _).symm) (fun _ _ => (mk_smul _ _).symm) (fun _ _ => (mk_smul _ _).symm)
(fun _ _ => (mk_pow _ _).symm) (fun _ => rfl) fun _ => rfl
CauSeq.Completion.instNNRatCast
instance
: NNRatCast (Cauchy abv)
instance instNNRatCast : NNRatCast (Cauchy abv) where nnratCast q := ofRat q
CauSeq.Completion.instRatCast
instance
: RatCast (Cauchy abv)
instance instRatCast : RatCast (Cauchy abv) where ratCast q := ofRat q
CauSeq.Completion.ofRat_nnratCast
theorem
(q : ℚ≥0) : ofRat (q : β) = (q : Cauchy abv)
@[simp, norm_cast] lemma ofRat_nnratCast (q : ℚ≥0) : ofRat (q : β) = (q : Cauchy abv) := rfl
CauSeq.Completion.ofRat_ratCast
theorem
(q : ℚ) : ofRat (q : β) = (q : Cauchy abv)
@[simp, norm_cast] lemma ofRat_ratCast (q : ℚ) : ofRat (q : β) = (q : Cauchy abv) := rfl
CauSeq.Completion.instInvCauchy
instance
: Inv (Cauchy abv)
noncomputable instance : Inv (Cauchy abv) :=
⟨fun x =>
(Quotient.liftOn x fun f => mk <| if h : LimZero f then 0 else inv f h) fun f g fg => by
have := limZero_congr fg
by_cases hf : LimZero f
· simp [hf, this.1 hf, Setoid.refl]
· have hg := mt this.2 hf
simp only [hf, dite_false, hg]
have If : mk (inv f hf) * mk f = 1 := mk_eq.2 (inv_mul_cancel hf)
have Ig : mk (inv g hg) * mk g = 1 := mk_eq.2 (inv_mul_cancel hg)
have Ig' : mk g * mk (inv g hg) = 1 := mk_eq.2 (mul_inv_cancel hg)
rw [mk_eq.2 fg, ← Ig] at If
rw [← mul_one (mk (inv f hf)), ← Ig', ← mul_assoc, If, mul_assoc, Ig', mul_one]⟩
CauSeq.Completion.inv_zero
theorem
: (0 : (Cauchy abv))⁻¹ = 0
theorem inv_zero : (0 : (Cauchy abv))⁻¹ = 0 :=
congr_arg mk <| by rw [dif_pos] <;> [rfl; exact zero_limZero]
CauSeq.Completion.inv_mk
theorem
{f} (hf) : (mk (abv := abv) f)⁻¹ = mk (inv f hf)
CauSeq.Completion.cau_seq_zero_ne_one
theorem
: ¬(0 : CauSeq _ abv) ≈ 1
theorem cau_seq_zero_ne_one : ¬(0 : CauSeq _ abv) ≈ 1 := fun h =>
have : LimZero (1 - 0 : CauSeq _ abv) := Setoid.symm h
have : LimZero (1 : CauSeq _ abv) := by simpa
by apply one_ne_zero <| const_limZero.1 this
CauSeq.Completion.zero_ne_one
theorem
: (0 : (Cauchy abv)) ≠ 1
theorem zero_ne_one : (0 : (Cauchy abv)) ≠ 1 := fun h => cau_seq_zero_ne_one <| mk_eq.1 h
CauSeq.Completion.inv_mul_cancel
theorem
{x : (Cauchy abv)} : x ≠ 0 → x⁻¹ * x = 1
protected theorem inv_mul_cancel {x : (Cauchy abv)} : x ≠ 0 → x⁻¹ * x = 1 :=
Quotient.inductionOn x fun f hf => by
simp only [mk_eq_mk, ne_eq, mk_eq_zero] at hf
simp only [mk_eq_mk, hf, not_false_eq_true, inv_mk, mk_mul]
exact Quotient.sound (CauSeq.inv_mul_cancel hf)
CauSeq.Completion.mul_inv_cancel
theorem
{x : (Cauchy abv)} : x ≠ 0 → x * x⁻¹ = 1
protected theorem mul_inv_cancel {x : (Cauchy abv)} : x ≠ 0 → x * x⁻¹ = 1 :=
Quotient.inductionOn x fun f hf => by
simp only [mk_eq_mk, ne_eq, mk_eq_zero] at hf
simp only [mk_eq_mk, hf, not_false_eq_true, inv_mk, mk_mul]
exact Quotient.sound (CauSeq.mul_inv_cancel hf)
CauSeq.Completion.ofRat_inv
theorem
(x : β) : ofRat x⁻¹ = ((ofRat x)⁻¹ : (Cauchy abv))
theorem ofRat_inv (x : β) : ofRat x⁻¹ = ((ofRat x)⁻¹ : (Cauchy abv)) :=
congr_arg mk <| by split_ifs with h <;>
[simp only [const_limZero.1 h, GroupWithZero.inv_zero, const_zero]; rfl]
CauSeq.Completion.instDivInvMonoid
instance
: DivInvMonoid (Cauchy abv)
noncomputable instance instDivInvMonoid : DivInvMonoid (Cauchy abv) where
CauSeq.Completion.ofRat_div
theorem
(x y : β) : ofRat (x / y) = (ofRat x / ofRat y : Cauchy abv)
CauSeq.Completion.Cauchy.divisionRing
instance
: DivisionRing (Cauchy abv)
/-- The Cauchy completion forms a division ring. -/
noncomputable instance Cauchy.divisionRing : DivisionRing (Cauchy abv) where
exists_pair_ne := ⟨0, 1, zero_ne_one⟩
inv_zero := inv_zero
mul_inv_cancel _ := CauSeq.Completion.mul_inv_cancel
nnqsmul := (· • ·)
qsmul := (· • ·)
nnratCast_def q := by simp_rw [← ofRat_nnratCast, NNRat.cast_def, ofRat_div, ofRat_natCast]
ratCast_def q := by rw [← ofRat_ratCast, Rat.cast_def, ofRat_div, ofRat_natCast, ofRat_intCast]
nnqsmul_def _ x := Quotient.inductionOn x fun _ ↦ congr_arg mk <| ext fun _ ↦ NNRat.smul_def _ _
qsmul_def _ x := Quotient.inductionOn x fun _ ↦ congr_arg mk <| ext fun _ ↦ Rat.smul_def _ _
CauSeq.Completion.instReprCauchy
instance
[Repr β] : Repr (Cauchy abv)
/-- Show the first 10 items of a representative of this equivalence class of cauchy sequences.
The representative chosen is the one passed in the VM to `Quot.mk`, so two cauchy sequences
converging to the same number may be printed differently.
-/
unsafe instance [Repr β] : Repr (Cauchy abv) where
reprPrec r _ :=
let N := 10
let seq := r.unquot
"(sorry /- " ++ Std.Format.joinSep ((List.range N).map <| reprrepr ∘ seq) ", " ++ ", ... -/)"
CauSeq.Completion.Cauchy.field
instance
: Field (Cauchy abv)
/-- The Cauchy completion forms a field. -/
noncomputable instance Cauchy.field : Field (Cauchy abv) :=
{ Cauchy.divisionRing, Cauchy.commRing with }
CauSeq.IsComplete
structure
/-- A class stating that a ring with an absolute value is complete, i.e. every Cauchy
sequence has a limit. -/
class IsComplete : Prop where
/-- Every Cauchy sequence has a limit. -/
isComplete : ∀ s : CauSeq β abv, ∃ b : β, s ≈ const abv b
CauSeq.complete
theorem
: ∀ s : CauSeq β abv, ∃ b : β, s ≈ const abv b
theorem complete : ∀ s : CauSeq β abv, ∃ b : β, s ≈ const abv b :=
IsComplete.isComplete
CauSeq.lim
definition
(s : CauSeq β abv) : β
/-- The limit of a Cauchy sequence in a complete ring. Chosen non-computably. -/
noncomputable def lim (s : CauSeq β abv) : β :=
Classical.choose (complete s)
CauSeq.equiv_lim
theorem
(s : CauSeq β abv) : s ≈ const abv (lim s)
theorem equiv_lim (s : CauSeq β abv) : s ≈ const abv (lim s) :=
Classical.choose_spec (complete s)
CauSeq.lim_eq_of_equiv_const
theorem
{f : CauSeq β abv} {x : β} (h : f ≈ CauSeq.const abv x) : lim f = x
theorem lim_eq_of_equiv_const {f : CauSeq β abv} {x : β} (h : f ≈ CauSeq.const abv x) : lim f = x :=
(eq_lim_of_const_equiv <| Setoid.symm h).symm
CauSeq.lim_eq_lim_of_equiv
theorem
{f g : CauSeq β abv} (h : f ≈ g) : lim f = lim g
theorem lim_eq_lim_of_equiv {f g : CauSeq β abv} (h : f ≈ g) : lim f = lim g :=
lim_eq_of_equiv_const <| Setoid.trans h <| equiv_lim g
CauSeq.lim_const
theorem
(x : β) : lim (const abv x) = x
@[simp]
theorem lim_const (x : β) : lim (const abv x) = x :=
lim_eq_of_equiv_const <| Setoid.refl _
CauSeq.lim_add
theorem
(f g : CauSeq β abv) : lim f + lim g = lim (f + g)
theorem lim_add (f g : CauSeq β abv) : lim f + lim g = lim (f + g) :=
eq_lim_of_const_equiv <|
show LimZero (const abv (lim f + lim g) - (f + g)) by
rw [const_add, add_sub_add_comm]
exact add_limZero (Setoid.symm (equiv_lim f)) (Setoid.symm (equiv_lim g))
CauSeq.lim_mul_lim
theorem
(f g : CauSeq β abv) : lim f * lim g = lim (f * g)
theorem lim_mul_lim (f g : CauSeq β abv) : lim f * lim g = lim (f * g) :=
eq_lim_of_const_equiv <|
show LimZero (const abv (lim f * lim g) - f * g) by
have h :
const abv (lim f * lim g) - f * g =
(const abv (lim f) - f) * g + const abv (lim f) * (const abv (lim g) - g) := by
apply Subtype.ext
rw [coe_add]
simp [sub_mul, mul_sub]
rw [h]
exact
add_limZero (mul_limZero_left _ (Setoid.symm (equiv_lim _)))
(mul_limZero_right _ (Setoid.symm (equiv_lim _)))
CauSeq.lim_mul
theorem
(f : CauSeq β abv) (x : β) : lim f * x = lim (f * const abv x)
CauSeq.lim_neg
theorem
(f : CauSeq β abv) : lim (-f) = -lim f
theorem lim_neg (f : CauSeq β abv) : lim (-f) = -lim f :=
lim_eq_of_equiv_const
(show LimZero (-f - const abv (-lim f)) by
rw [const_neg, sub_neg_eq_add, add_comm, ← sub_eq_add_neg]
exact Setoid.symm (equiv_lim f))
CauSeq.lim_eq_zero_iff
theorem
(f : CauSeq β abv) : lim f = 0 ↔ LimZero f
theorem lim_eq_zero_iff (f : CauSeq β abv) : limlim f = 0 ↔ LimZero f :=
⟨fun h => by
have hf := equiv_lim f
rw [h] at hf
exact (limZero_congr hf).mpr (const_limZero.mpr rfl),
fun h => by
have h₁ : f = f - const abv 0 := ext fun n => by simp [sub_apply, const_apply]
rw [h₁] at h
exact lim_eq_of_equiv_const h⟩
CauSeq.lim_inv
theorem
{f : CauSeq β abv} (hf : ¬LimZero f) : lim (inv f hf) = (lim f)⁻¹
theorem lim_inv {f : CauSeq β abv} (hf : ¬LimZero f) : lim (inv f hf) = (lim f)⁻¹ :=
have hl : limlim f ≠ 0 := by rwa [← lim_eq_zero_iff] at hf
lim_eq_of_equiv_const <|
show LimZero (inv f hf - const abv (lim f)⁻¹) from
have h₁ : ∀ (g f : CauSeq β abv) (hf : ¬LimZero f), LimZero (g - f * inv f hf * g) :=
fun g f hf => by
have h₂ : g - f * inv f hf * g = 1 * g - f * inv f hf * g := by rw [one_mul g]
have h₃ : f * inv f hf * g = (f * inv f hf) * g := by simp [mul_assoc]
have h₄ : g - f * inv f hf * g = (1 - f * inv f hf) * g := by rw [h₂, h₃, ← sub_mul]
have h₅ : g - f * inv f hf * g = g * (1 - f * inv f hf) := by rw [h₄, mul_comm]
have h₆ : g - f * inv f hf * g = g * (1 - inv f hf * f) := by rw [h₅, mul_comm f]
rw [h₆]; exact mul_limZero_right _ (Setoid.symm (CauSeq.inv_mul_cancel _))
have h₂ :
LimZero
(inv f hf - const abv (lim f)⁻¹ -
(const abv (lim f) - f) * (inv f hf * const abv (lim f)⁻¹)) := by
rw [sub_mul, ← sub_add, sub_sub, sub_add_eq_sub_sub, sub_right_comm, sub_add]
show LimZero
(inv f hf - const abv (lim f) * (inv f hf * const abv (lim f)⁻¹) -
(const abv (lim f)⁻¹ - f * (inv f hf * const abv (lim f)⁻¹)))
exact sub_limZero
(by rw [← mul_assoc, mul_right_comm, const_inv hl]; exact h₁ _ _ _)
(by rw [← mul_assoc]; exact h₁ _ _ _)
(limZero_congr h₂).mpr <| mul_limZero_left _ (Setoid.symm (equiv_lim f))
CauSeq.lim_le
theorem
{f : CauSeq α abs} {x : α} (h : f ≤ CauSeq.const abs x) : lim f ≤ x
theorem lim_le {f : CauSeq α abs} {x : α} (h : f ≤ CauSeq.const abs x) : lim f ≤ x :=
CauSeq.const_le.1 <| CauSeq.le_of_eq_of_le (Setoid.symm (equiv_lim f)) h
CauSeq.le_lim
theorem
{f : CauSeq α abs} {x : α} (h : CauSeq.const abs x ≤ f) : x ≤ lim f
theorem le_lim {f : CauSeq α abs} {x : α} (h : CauSeq.const abs x ≤ f) : x ≤ lim f :=
CauSeq.const_le.1 <| CauSeq.le_of_le_of_eq h (equiv_lim f)
CauSeq.lt_lim
theorem
{f : CauSeq α abs} {x : α} (h : CauSeq.const abs x < f) : x < lim f
theorem lt_lim {f : CauSeq α abs} {x : α} (h : CauSeq.const abs x < f) : x < lim f :=
CauSeq.const_lt.1 <| CauSeq.lt_of_lt_of_eq h (equiv_lim f)
CauSeq.lim_lt
theorem
{f : CauSeq α abs} {x : α} (h : f < CauSeq.const abs x) : lim f < x
theorem lim_lt {f : CauSeq α abs} {x : α} (h : f < CauSeq.const abs x) : lim f < x :=
CauSeq.const_lt.1 <| CauSeq.lt_of_eq_of_lt (Setoid.symm (equiv_lim f)) h