-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathleftright.lean
159 lines (128 loc) · 5.31 KB
/
leftright.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import Continuity.continuous
--------------------------------------------------------------------------------
-- # Definition of left- and right-continuity
--------------------------------------------------------------------------------
/-- Definition of a left-continuous function `f: D → ℝ`. -/
def IsLeftContinuousAt (D : Set ℝ) (f : D → ℝ) (a : D) : Prop :=
∀ ε > 0, ∃ δ > 0, ∀ x : D,
x < a → (|x.val - a.val| < δ → |f x - f a| < ε)
/-- Definition of a right-continuous function `f: D → ℝ`. -/
def IsRightContinuousAt (D : Set ℝ) (f : D → ℝ) (a : D) : Prop :=
∀ ε > 0, ∃ δ > 0, ∀ x : D,
x > a → (|x.val - a.val| < δ → |f x - f a| < ε)
--------------------------------------------------------------------------------
-- # Heaviside function as example
--------------------------------------------------------------------------------
/--
Definition of the Heaviside function, often denoted `Θ` in literature.
By the keyword `noncomputable`, we signal Lean4 that this function does not have
a constructive computational method within the confines of Lean's type theory
and logic. You may want to look up "decidability in computer science" for more
information on this topic, e.g. the halting problem and deterministic finite
automata.
The `@[simp]` attribute tells Lean to use this definition as a simplification rule
when simplifying expressions via the `simp` tactic.
-/
@[simp]
noncomputable def Heaviside (x : ℝ) : ℝ := if x < 0 then 0 else 1
/-- The Heaviside function is right-continuous. -/
example : IsRightContinuousAt Set.univ (fun x ↦ Heaviside x) ⟨0, trivial⟩ := by
intro ε hεbigger0
use 1
simp
intro x h_x_gt_zero _h_xδ_criterion
-- Variant 1: via `split_ifs`
split_ifs with h_xvalue
· linarith
· simp only [sub_self, abs_zero]
exact hεbigger0
-- Variant 2: via `if_neg`
-- rw [if_neg]
-- · simp only [sub_self, abs_zero]
-- exact hεbigger0
-- · simp only [not_lt]
-- exact le_of_lt h_x_gt_zero
/-- The Heaviside function is not continuous (at `a = 0`). -/
example : ¬IsContinuousAt Set.univ (fun x ↦ Heaviside x) ⟨0, trivial⟩ := by
-- We proof by contradiction, so we assume that the function is continuous
-- and show that this leads to a `False` truth-value.
intro h_is_continuous
let ε := (1:ℝ)/2
choose δ δ_pos hδ using h_is_continuous ε (by positivity)
let x := -δ/2
have h_x_smaller_zero : x < 0 := by dsimp [x]; linarith
have _h_x_smaller_delta : x < δ := by dsimp [x]; linarith
have h_x_smaller_delta' : |x| < δ := by
dsimp [x]
simp only [abs_lt]
constructor
· linarith
· linarith
-- Construct contradiction
have h_heaviside : |Heaviside x - Heaviside 0| = 1 := by
simp [Heaviside, h_x_smaller_zero]
have h_heaviside_ε : |Heaviside x - Heaviside 0| < ε := by
simp [Heaviside] at hδ
simp
exact hδ x h_x_smaller_delta'
have h_blow_up_math : ε > 1 := by
calc ε > |Heaviside x - Heaviside 0| := h_heaviside_ε
_ = 1 := h_heaviside
exact absurd h_blow_up_math (by norm_num)
--------------------------------------------------------------------------------
-- # Equivalence of continuity and left- and right-continuity
--------------------------------------------------------------------------------
theorem LeftRightContinuousIffIsContinuous
(D : Set ℝ) (f: D → ℝ) (a : D)
: (IsContinuousAt D f a)
↔ (IsLeftContinuousAt D f a ∧ IsRightContinuousAt D f a) := by
constructor
-- Left side implies right side,
-- i.e. (continuity) → (left- and right-continuity)
· intro h_continuous
constructor
-- Left-continuity
· dsimp [IsLeftContinuousAt]
intro ε h_εbigger0
obtain ⟨δ, h_δbigger0, h_δ⟩ := h_continuous ε (by linarith)
use δ
use h_δbigger0
intro x _h_x_smaller_a h_x_δ_criterion
exact h_δ x h_x_δ_criterion
-- Right-continuity
· dsimp [IsLeftContinuousAt]
intro ε h_εbigger0
obtain ⟨δ, h_δbigger0, h_δ⟩ := h_continuous ε (by linarith)
use δ
use h_δbigger0
intro x _h_x_bigger_a h_x_δ_criterion
exact h_δ x h_x_δ_criterion
-- Right side implies left side,
-- i.e. (left- and right-continuity) → (continuity)
· intro h_left_and_right_continuous
rcases h_left_and_right_continuous with ⟨left_continuous, right_continuous⟩
intro ε h_εbigger0
-- `δ₁` and `δ₂` obtained from left- and right-continuity
obtain ⟨δ₁, hδ₁, hδ₁_prop⟩ := left_continuous ε (by linarith)
obtain ⟨δ₂, hδ₂, hδ₂_prop⟩ := right_continuous (ε) (by linarith)
use min δ₁ δ₂
use lt_min hδ₁ hδ₂
intro x h_x_δ_criterion
by_cases h_a_value : x < a
-- x < a (use left-continuity)
· apply hδ₁_prop x h_a_value
apply lt_of_lt_of_le h_x_δ_criterion
apply min_le_left
-- x ≥ a
· push_neg at h_a_value
by_cases h_a_value' : x = a
-- x = a
· rewrite [h_a_value']
simp [abs_zero, h_εbigger0]
-- x > a (use right-continuity)
· have h_x_bigger_a : x > a := by
push_neg at h_a_value'
exact lt_of_le_of_ne h_a_value (id (Ne.symm h_a_value'))
apply hδ₂_prop x h_x_bigger_a
apply lt_of_lt_of_le h_x_δ_criterion
apply min_le_right