lean2/library/theories/measure_theory/extended_real.lean
Floris van Doorn e5d5ef9d55 feat(hott/library): various changes and additions.
Most notably:
Give le.refl the attribute [refl]. This simplifies tactic proofs in various places.
Redefine the order of trunc_index, and instantiate it as weak order.
Add more about pointed equivalences.
2016-03-03 10:13:20 -08:00

408 lines
15 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2015 Jacob Gross. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jacob Gross, Jeremy Avigad
Extended reals.
-/
import data.real
open real eq.ops classical
-- This is a hack, to get around the fact that the top level names are inaccessible when
-- defining these theorems in the ereal namespace. Is there a better way?
private definition zero_mul' := @zero_mul
private definition mul_zero' := @mul_zero
private definition neg_neg' := @neg_neg
noncomputable theory
inductive ereal : Type :=
| of_real : → ereal
| infty : ereal
| neginfty : ereal
attribute ereal.of_real [coercion]
notation `∞` := ereal.infty
notation `-∞` := ereal.neginfty
namespace ereal
protected definition prio := num.pred real.prio
/- arithmetic operations on the ereals -/
definition ereal_has_zero [instance] [priority ereal.prio] : has_zero ereal :=
has_zero.mk (of_real 0)
definition ereal_has_one [instance] [priority ereal.prio] : has_one ereal :=
has_one.mk (of_real 1)
protected definition add : ereal → ereal → ereal
| (of_real x) (of_real y) := of_real (x + y)
| ∞ _ := ∞
| _ ∞ := ∞
| -∞ _ := -∞
| _ -∞ := -∞
protected definition neg : ereal → ereal
| (of_real x) := of_real (-x)
| ∞ := -∞
| -∞ := ∞
private definition blow_up [reducible] : ereal → ereal
| (of_real x) := if x = 0 then of_real 0 else if x > 0 then ∞ else -∞
| ∞ := ∞
| -∞ := -∞
protected definition mul : ereal → ereal → ereal
| (of_real x) (of_real y) := of_real (x * y)
| ∞ a := blow_up a
| a ∞ := blow_up a
| -∞ a := ereal.neg (blow_up a)
| a -∞ := ereal.neg (blow_up a)
definition ereal_has_add [instance] [priority ereal.prio] : has_add ereal :=
has_add.mk ereal.add
definition ereal_has_neg [instance] [priority ereal.prio] : has_neg ereal :=
has_neg.mk ereal.neg
protected definition sub (u v : ereal) : ereal := u + -v
definition ereal_has_sub [instance] [priority ereal.prio] : has_sub ereal :=
has_sub.mk ereal.sub
definition ereal_has_mul [instance] [priority ereal.prio] : has_mul ereal :=
has_mul.mk ereal.mul
protected theorem zero_def : (0 : ereal) = of_real 0 := rfl
protected theorem one_def : (1 : ereal) = of_real 1 := rfl
protected theorem add_def (x y : ereal) : x + y = ereal.add x y := rfl
protected theorem neg_def (x : ereal) : -x = ereal.neg x := rfl
protected theorem sub_eq_add_neg (u v : ereal) : u - v = u + -v := rfl
protected theorem mul_def (x y : ereal) : x * y = ereal.mul x y := rfl
theorem of_real.inj {x y : real} (H : of_real x = of_real y) : x = y :=
ereal.no_confusion H (assume H1, H1)
abbreviation eq_of_of_real_eq_of_real := @of_real.inj
theorem of_real_add (x y : real) : of_real (x + y) = of_real x + of_real y := rfl
theorem of_real_mul (x y : real) : of_real (x * y) = of_real x * of_real y := rfl
theorem infty_ne_neg_infty : ∞ ≠ -∞ := ereal.no_confusion
theorem infty_ne_of_real (x : real) : ∞ ≠ of_real x := ereal.no_confusion
theorem neg_infty_ne_of_real (x : real) : -∞ ≠ of_real x := ereal.no_confusion
/- properties of the arithmetic operations -/
protected theorem add_comm : ∀ u v : ereal, u + v = v + u
| (of_real x) (of_real y) := congr_arg of_real !add.comm
| ∞ v := by rewrite[*ereal.add_def, ↑ereal.add]
| u ∞ := by rewrite[*ereal.add_def, ↑ereal.add]
| -∞ v := by rewrite[*ereal.add_def, ↑ereal.add]
| u -∞ := by rewrite[*ereal.add_def, ↑ereal.add]
theorem infty_add : ∀ u, ∞ + u = ∞
| (of_real x) := rfl
| ∞ := rfl
| -∞ := rfl
theorem add_infty : ∀ u, u + ∞ = ∞
| (of_real x) := rfl
| ∞ := rfl
| -∞ := rfl
protected theorem add_assoc : ∀ u v w : ereal, (u + v) + w = u + (v + w)
| (of_real x) (of_real y) (of_real z) := congr_arg of_real !add.assoc
| ∞ v w := by rewrite [*infty_add, *add_infty]
| u ∞ w := by rewrite [*infty_add, *add_infty, infty_add]
| u v ∞ := by rewrite [*infty_add, *add_infty]
| (of_real x) (of_real y) -∞ := by rewrite[*ereal.add_def, ↑ereal.add]
| (of_real x) -∞ (of_real z) := by rewrite[*ereal.add_def, ↑ereal.add]
| -∞ (of_real y) (of_real z) := by rewrite[*ereal.add_def, ↑ereal.add]
| (of_real x) -∞ -∞ := by rewrite[*ereal.add_def, ↑ereal.add]
| -∞ (of_real y) -∞ := rfl
| -∞ -∞ (of_real z) := by rewrite[*ereal.add_def, ↑ereal.add]
| -∞ -∞ -∞ := rfl
protected theorem zero_add : ∀ u : ereal, 0 + u = u
| (of_real x) := congr_arg of_real !real.zero_add
| ∞ := rfl
| -∞ := rfl
protected theorem add_zero : ∀ u : ereal, u + 0 = u :=
by intro u; rewrite [ereal.add_comm, ereal.zero_add]
protected theorem mul_comm : ∀ u v : ereal, u * v = v * u
| (of_real x) (of_real y) := congr_arg of_real !mul.comm
| ∞ a := by rewrite [*ereal.mul_def, ↑ereal.mul]
| a ∞ := by rewrite [*ereal.mul_def, ↑ereal.mul]
| -∞ a := by rewrite [*ereal.mul_def, ↑ereal.mul]
| a -∞ := by rewrite [*ereal.mul_def, ↑ereal.mul]
protected theorem neg_neg : ∀ u : ereal, -(-u) = u
| ∞ := rfl
| (of_real x) := by rewrite [*ereal.neg_def, ↑ereal.neg, ▸*,
(neg_neg' x)]
| -∞ := rfl
theorem neg_infty : -∞ = - ∞ := rfl
protected theorem neg_zero : -(0 : ereal) = 0 := rfl
theorem infty_mul_pos {x : real} (H : x > 0) : ∞ * x = ∞ :=
have H1 : x ≠ 0, from ne_of_gt H,
by rewrite [*ereal.mul_def, ↑ereal.mul, if_neg H1, if_pos H]
theorem pos_mul_infty {x : real} (H : x > 0) : x * ∞ = ∞ :=
by rewrite [ereal.mul_comm, infty_mul_pos H]
theorem infty_mul_neg {x : real} (H : x < 0) : ∞ * x = -∞ :=
have H1 : x ≠ 0, from ne_of_lt H,
have H2 : ¬ x > 0, from not_lt_of_gt H,
by rewrite [*ereal.mul_def, ↑ereal.mul, if_neg H1, if_neg H2]
theorem neg_mul_infty {x : real} (H : x < 0) : x * ∞ = -∞ :=
by rewrite [ereal.mul_comm, infty_mul_neg H]
private theorem infty_mul_zero : ∞ * 0 = 0 :=
by rewrite [*ereal.mul_def, ↑ereal.mul, ereal.zero_def, ↑blow_up, if_pos rfl]
private theorem zero_mul_infty : 0 * ∞ = 0 :=
by rewrite [ereal.mul_comm, infty_mul_zero]
theorem infty_mul_infty : ∞ * ∞ = ∞ := rfl
protected theorem neg_of_real (x : real) : -(of_real x) = of_real (-x) :=
rfl
private theorem aux1 : ∀ v : ereal, -∞ * v = -(∞ * v)
| ∞ := rfl
| (of_real x) := rfl
| -∞ := rfl
private theorem aux2 : ∀ u : ereal, -u * ∞ = -(u * ∞)
| ∞ := rfl
| (of_real x) := lt.by_cases
(assume H : x < 0,
by rewrite [ereal.neg_of_real, pos_mul_infty (neg_pos_of_neg H),
neg_mul_infty H])
(assume H : x = 0,
by krewrite [H, ereal.neg_zero, *zero_mul_infty, ereal.neg_zero])
(assume H : x > 0,
by rewrite [ereal.neg_of_real, neg_mul_infty (neg_neg_of_pos H),
pos_mul_infty H])
| -∞ := rfl
theorem ereal_neg_mul : ∀ u v : ereal, -u * v = -(u * v)
| ∞ v := aux1 v
| -∞ v := by rewrite [aux1, *ereal.neg_neg]
| u ∞ := by rewrite [-aux2]
| u -∞ := by rewrite [ereal.mul_comm, ereal.mul_comm u,
*aux1, ereal.mul_comm, aux2, *ereal.neg_neg]
| (of_real x) (of_real y) := congr_arg of_real (eq.symm (neg_mul_eq_neg_mul x y))
theorem ereal_mul_neg (u v : ereal) : u * -v = -(u * v) :=
by rewrite [*ereal.mul_comm u, ereal_neg_mul]
protected theorem mul_zero : ∀ u : ereal, u * 0 = 0
| ∞ := infty_mul_zero
| -∞ := by rewrite [neg_infty, ereal_neg_mul, infty_mul_zero]
| (of_real x) := congr_arg of_real (mul_zero' x)
protected theorem zero_mul (u : ereal) : 0 * u = 0 :=
by rewrite [ereal.mul_comm, ereal.mul_zero]
private theorem aux3 : ∀ u, ∞ * (∞ * u) = ∞ * u
| ∞ := rfl
| (of_real x) := if H : x = 0 then
by rewrite [*ereal.mul_def, ↑ereal.mul, ↑blow_up, *H, *if_pos rfl]
else if H1 : x > 0 then
by rewrite [*ereal.mul_def, ↑ereal.mul, ↑blow_up, if_neg H, if_pos H1]
else
by rewrite [*ereal.mul_def, ↑ereal.mul, ↑blow_up, if_neg H, if_neg H1]
| -∞ := rfl
private theorem aux4 (x y : real) : ∞ * x * y = ∞ * (x * y) :=
lt.by_cases
(assume H : x < 0,
lt.by_cases
(assume H1 : y < 0, by rewrite [infty_mul_neg H, neg_infty, ereal_neg_mul, -of_real_mul,
infty_mul_neg H1, infty_mul_pos (mul_pos_of_neg_of_neg H H1)])
(assume H1 : y = 0, by krewrite [H1, *ereal.mul_zero])
(assume H1 : y > 0, by rewrite [infty_mul_neg H, neg_infty, *ereal_neg_mul, -of_real_mul,
infty_mul_pos H1, infty_mul_neg (mul_neg_of_neg_of_pos H H1)]))
(assume H : x = 0,
by krewrite [H, ereal.mul_zero, *ereal.zero_mul, ereal.mul_zero])
(assume H : x > 0,
lt.by_cases
(assume H1 : y < 0, by rewrite [infty_mul_pos H, infty_mul_neg H1, -of_real_mul,
infty_mul_neg (mul_neg_of_pos_of_neg H H1)])
(assume H1 : y = 0, by krewrite [H1, *ereal.mul_zero])
(assume H1 : y > 0, by rewrite [infty_mul_pos H, infty_mul_pos H1, -of_real_mul,
infty_mul_pos (mul_pos H H1)]))
private theorem aux5 : ∀ u v, ∞ * u * v = ∞ * (u * v)
| ∞ v := by rewrite [infty_mul_infty, aux3]
| u ∞ := by rewrite [-*ereal.mul_comm ∞]
| -∞ v := by rewrite [neg_infty, *ereal_neg_mul, *ereal_mul_neg, ereal_neg_mul, infty_mul_infty,
aux3]
| u -∞ := by rewrite [neg_infty, *ereal_mul_neg]
| (of_real x) (of_real y) := aux4 x y
protected theorem mul_assoc : ∀ u v w : ereal, u * v * w = u * (v * w)
| ∞ v w := !aux5
| u ∞ w := by rewrite [-*ereal.mul_comm ∞, *ereal.mul_comm u, *aux5, *ereal.mul_comm u]
| u v ∞ := by rewrite [-*ereal.mul_comm ∞, *ereal.mul_comm u, aux5]
| -∞ v w := by rewrite [neg_infty, *ereal_neg_mul, aux5]
| u -∞ w := by rewrite [neg_infty, *ereal_mul_neg, *ereal_neg_mul, ereal_mul_neg, *ereal.mul_comm u,
*aux5, ereal.mul_comm u]
| u v -∞ := by rewrite [neg_infty, *ereal_mul_neg, *ereal.mul_comm u, -*ereal.mul_comm ∞, aux5]
| (of_real x) (of_real y) (of_real z) := congr_arg of_real (mul.assoc x y z)
protected theorem one_mul : ∀ u : ereal, of_real 1 * u = u
| (of_real x) := !real.one_mul ▸ rfl
| ∞ := pos_mul_infty zero_lt_one
| -∞ := by rewrite [neg_infty, ereal_mul_neg, pos_mul_infty zero_lt_one]
protected theorem mul_one (u : ereal) : u * 1 = u :=
by krewrite [ereal.mul_comm, ereal.one_mul]
/- instantiating arithmetic structures -/
-- Note that distributivity fails, e.g. ∞ ⬝ (-1 + 1) ≠ ∞ * -1 + ∞ * 1
protected definition comm_monoid [trans_instance] : comm_monoid ereal :=
⦃comm_monoid,
mul := ereal.mul,
mul_assoc := ereal.mul_assoc,
one := 1,
one_mul := ereal.one_mul,
mul_one := ereal.mul_one,
mul_comm := ereal.mul_comm
protected definition add_comm_monoid [trans_instance] : add_comm_monoid ereal :=
⦃add_comm_monoid,
add := ereal.add,
add_assoc := ereal.add_assoc,
zero := 0,
zero_add := ereal.zero_add,
add_zero := ereal.add_zero,
add_comm := ereal.add_comm
/- ordering on the ereals -/
protected definition le : ereal → ereal → Prop
| u ∞ := true
| -∞ v := true
| (of_real x) (of_real y) := x ≤ y
| (of_real x) -∞ := false
| ∞ (of_real y) := false
| ∞ -∞ := false
definition ereal_has_le [instance] [priority ereal.prio] : has_le ereal :=
has_le.mk ereal.le
theorem of_real_le_of_real (x y : real) : of_real x ≤ of_real y ↔ x ≤ y :=
!iff.refl
theorem le_infty : ∀ u, u ≤ ∞
| ∞ := trivial
| (of_real x) := trivial
| -∞ := trivial
theorem neg_infty_le : ∀ v, -∞ ≤ v
| ∞ := trivial
| (of_real x) := trivial
| -∞ := trivial
protected theorem le_refl : ∀ u : ereal, u ≤ u
| ∞ := trivial
| -∞ := trivial
| (of_real x) := by rewrite [of_real_le_of_real]
protected theorem le_trans : ∀ u v w : ereal, u ≤ v → v ≤ w → u ≤ w
| u v ∞ H1 H2 := !le_infty
| -∞ v w H1 H2 := !neg_infty_le
| u ∞ (of_real x) H1 H2 := false.elim H2
| ∞ (of_real x) v H1 H2 := false.elim H1
| ∞ -∞ v H1 H2 := false.elim H1
| u (of_real x) -∞ H1 H2 := false.elim H2
| u ∞ -∞ H1 H2 := false.elim H2
| (of_real x) -∞ v H1 H2 := false.elim H1
| (of_real x) (of_real y) (of_real z) H1 H2 :=
iff.mpr !of_real_le_of_real
(le.trans (iff.mp !of_real_le_of_real H1) (iff.mp !of_real_le_of_real H2))
protected theorem le_antisymm : ∀ u v : ereal, u ≤ v → v ≤ u → u = v
| ∞ ∞ H1 H2 := rfl
| ∞ (of_real x) H1 H2 := false.elim H1
| ∞ -∞ H1 H2 := false.elim H1
| -∞ -∞ H1 H2 := rfl
| -∞ (of_real x) H1 H2 := false.elim H2
| -∞ ∞ H1 H2 := false.elim H2
| (of_real x) ∞ H1 H2 := false.elim H2
| (of_real x) -∞ H1 H2 := false.elim H1
| (of_real x) (of_real y) H1 H2 :=
congr_arg of_real (le.antisymm (iff.mp !of_real_le_of_real H1) (iff.mp !of_real_le_of_real H2))
protected definition lt (x y : ereal) : Prop := x ≤ y ∧ x ≠ y
definition ereal_has_lt [instance] [priority ereal.prio] :
has_lt ereal :=
has_lt.mk ereal.lt
protected theorem le_iff_lt_or_eq (u v : ereal) : u ≤ v ↔ u < v u = v :=
iff.intro
(assume H : u ≤ v,
by_cases
(assume H1 : u = v, or.inr H1)
(assume H1 : u ≠ v, or.inl (and.intro H H1)))
(assume H : u < v u = v,
or.elim H
(assume H1 : u < v, and.left H1)
(assume H1 : u = v, by rewrite H1; apply ereal.le_refl))
protected theorem le_total : ∀ u v : ereal, u ≤ v v ≤ u
| u ∞ := or.inl (le_infty u)
| u -∞ := or.inr (neg_infty_le u)
| ∞ v := or.inr (le_infty v)
| -∞ v := or.inl (neg_infty_le v)
| (of_real x) (of_real y) :=
or.elim (le.total x y)
(assume H : x ≤[real] y, or.inl (iff.mpr !of_real_le_of_real H))
(assume H : x ≥[real] y, or.inr (iff.mpr !of_real_le_of_real H))
theorem neg_infty_lt_infty : -∞ < ∞ := and.intro trivial (ne.symm infty_ne_neg_infty)
theorem neg_infty_lt_of_real (x : real) : -∞ < of_real x := and.intro trivial !neg_infty_ne_of_real
theorem of_real_lt_infty (x : real) : of_real x < ∞ := and.intro trivial (ne.symm !infty_ne_of_real)
protected definition decidable_linear_order [trans_instance] : decidable_linear_order ereal :=
⦃decidable_linear_order,
le := ereal.le,
le_refl := ereal.le_refl,
le_trans := ereal.le_trans,
le_antisymm := ereal.le_antisymm,
lt := ereal.lt,
le_iff_lt_or_eq := ereal.le_iff_lt_or_eq,
lt_irrefl := abstract λ u H, and.right H rfl end,
decidable_lt := abstract λ u v : ereal, prop_decidable (u < v) end,
le_total := ereal.le_total
-- TODO : we still need some properties relating the arithmetic operations and the order.
end ereal