forked from leanprover-community/mathlib4
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFixedPoint.lean
More file actions
543 lines (431 loc) · 20.1 KB
/
FixedPoint.lean
File metadata and controls
543 lines (431 loc) · 20.1 KB
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
/-
Copyright (c) 2018 Violeta Hernández Palacios, Mario Carneiro. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Violeta Hernández Palacios, Mario Carneiro
-/
module
public import Mathlib.Logic.Small.List
public import Mathlib.SetTheory.Ordinal.Enum
public import Mathlib.SetTheory.Ordinal.Exponential
/-!
# Fixed points of normal functions
We prove various statements about the fixed points of normal ordinal functions. We state them in
two forms: as statements about indexed families of normal functions, and as statements about a
single normal function.
Moreover, we prove some lemmas about the fixed points of specific normal functions.
## Main definitions and results
* `nfpFamily`, `nfp`: the next fixed point of a (family of) normal function(s).
* `not_bddAbove_fp_family`, `not_bddAbove_fp`: the (common) fixed points of a (family of) normal
function(s) are unbounded in the ordinals.
* `deriv_add_eq_mul_omega0_add`: a characterization of the derivative of addition.
* `deriv_mul_eq_opow_omega0_mul`: a characterization of the derivative of multiplication.
-/
@[expose] public section
noncomputable section
universe u v
open Function Order
namespace Ordinal
/-! ### Fixed points of type-indexed families of ordinals -/
section
variable {ι : Type*} {f : ι → Ordinal.{u} → Ordinal.{u}}
/-- The next common fixed point, at least `a`, for a family of normal functions.
This is defined for any family of functions, as the supremum of all values reachable by applying
finitely many functions in the family to `a`.
`Ordinal.nfpFamily_fp` shows this is a fixed point, `Ordinal.le_nfpFamily` shows it's at
least `a`, and `Ordinal.nfpFamily_le_fp` shows this is the least ordinal with these properties. -/
def nfpFamily (f : ι → Ordinal.{u} → Ordinal.{u}) (a : Ordinal.{u}) : Ordinal :=
⨆ i, List.foldr f a i
theorem foldr_le_nfpFamily [Small.{u} ι] (f : ι → Ordinal.{u} → Ordinal.{u}) (a l) :
List.foldr f a l ≤ nfpFamily f a :=
Ordinal.le_iSup _ _
theorem le_nfpFamily [Small.{u} ι] (f : ι → Ordinal.{u} → Ordinal.{u}) (a) : a ≤ nfpFamily f a :=
foldr_le_nfpFamily f a []
theorem lt_nfpFamily_iff [Small.{u} ι] {a b} : a < nfpFamily f b ↔ ∃ l, a < List.foldr f b l :=
Ordinal.lt_iSup_iff
theorem nfpFamily_le_iff [Small.{u} ι] {a b} : nfpFamily f a ≤ b ↔ ∀ l, List.foldr f a l ≤ b :=
Ordinal.iSup_le_iff
theorem nfpFamily_le {a b} : (∀ l, List.foldr f a l ≤ b) → nfpFamily f a ≤ b :=
Ordinal.iSup_le
theorem nfpFamily_monotone [Small.{u} ι] (hf : ∀ i, Monotone (f i)) : Monotone (nfpFamily f) :=
fun _ _ h ↦ nfpFamily_le <| fun l ↦ (List.foldr_monotone hf l h).trans (foldr_le_nfpFamily _ _ l)
theorem apply_lt_nfpFamily [Small.{u} ι] (H : ∀ i, IsNormal (f i)) {a b}
(hb : b < nfpFamily f a) (i) : f i b < nfpFamily f a :=
let ⟨l, hl⟩ := lt_nfpFamily_iff.1 hb
lt_nfpFamily_iff.2 ⟨i::l, (H i).strictMono hl⟩
theorem apply_lt_nfpFamily_iff [Nonempty ι] [Small.{u} ι] (H : ∀ i, IsNormal (f i)) {a b} :
(∀ i, f i b < nfpFamily f a) ↔ b < nfpFamily f a := by
refine ⟨fun h ↦ ?_, apply_lt_nfpFamily H⟩
let ⟨l, hl⟩ := lt_nfpFamily_iff.1 (h (Classical.arbitrary ι))
exact lt_nfpFamily_iff.2 <| ⟨l, (H _).strictMono.le_apply.trans_lt hl⟩
theorem nfpFamily_le_apply [Nonempty ι] [Small.{u} ι] (H : ∀ i, IsNormal (f i)) {a b} :
(∃ i, nfpFamily f a ≤ f i b) ↔ nfpFamily f a ≤ b := by
contrapose!; exact apply_lt_nfpFamily_iff H
theorem nfpFamily_le_fp (H : ∀ i, Monotone (f i)) {a b} (ab : a ≤ b) (h : ∀ i, f i b ≤ b) :
nfpFamily f a ≤ b := by
apply Ordinal.iSup_le fun l ↦ ?_
induction l generalizing a with
| nil => exact ab
| cons i l IH => exact (H i (IH ab)).trans (h i)
theorem nfpFamily_fp [Small.{u} ι] {i} (H : IsNormal (f i)) (a) :
f i (nfpFamily f a) = nfpFamily f a := by
rw [nfpFamily, H.map_iSup (bddAbove_of_small _)]
apply le_antisymm <;> refine Ordinal.iSup_le fun l => ?_
· exact Ordinal.le_iSup _ (i::l)
· exact H.strictMono.le_apply.trans (Ordinal.le_iSup _ _)
theorem apply_le_nfpFamily [Small.{u} ι] [hι : Nonempty ι] (H : ∀ i, IsNormal (f i)) {a b} :
(∀ i, f i b ≤ nfpFamily f a) ↔ b ≤ nfpFamily f a := by
refine ⟨fun h => ?_, fun h i => ?_⟩
· obtain ⟨i⟩ := hι
exact (H i).strictMono.le_apply.trans (h i)
· rw [← nfpFamily_fp (H i)]
exact (H i).monotone h
theorem nfpFamily_eq_self [Small.{u} ι] {a} (h : ∀ i, f i a = a) : nfpFamily f a = a := by
apply (Ordinal.iSup_le ?_).antisymm (le_nfpFamily f a)
intro l
rw [List.foldr_fixed' h l]
-- Todo: This is actually a special case of the fact the intersection of club sets is a club set.
/-- A generalization of the fixed point lemma for normal functions: any family of normal functions
has an unbounded set of common fixed points. -/
theorem not_bddAbove_fp_family [Small.{u} ι] (H : ∀ i, IsNormal (f i)) :
¬ BddAbove (⋂ i, Function.fixedPoints (f i)) := by
rw [not_bddAbove_iff]
refine fun a ↦ ⟨nfpFamily f (succ a), ?_, (lt_succ a).trans_le (le_nfpFamily f _)⟩
rintro _ ⟨i, rfl⟩
exact nfpFamily_fp (H i) _
/-- The derivative of a family of normal functions is the sequence of their common fixed points.
This is defined for all functions such that `Ordinal.derivFamily_zero`,
`Ordinal.derivFamily_succ`, and `Ordinal.derivFamily_limit` are satisfied. -/
def derivFamily (f : ι → Ordinal.{u} → Ordinal.{u}) (o : Ordinal.{u}) : Ordinal.{u} :=
limitRecOn o (nfpFamily f 0) (fun _ IH => nfpFamily f (succ IH))
fun a _ g => ⨆ b : Set.Iio a, g _ b.2
@[simp]
theorem derivFamily_zero (f : ι → Ordinal → Ordinal) :
derivFamily f 0 = nfpFamily f 0 :=
limitRecOn_zero ..
@[simp]
theorem derivFamily_add_one (f : ι → Ordinal → Ordinal) (o) :
derivFamily f (o + 1) = nfpFamily f (derivFamily f o + 1) :=
limitRecOn_succ ..
-- TODO: deprecate
theorem derivFamily_succ (f : ι → Ordinal → Ordinal) (o) :
derivFamily f (succ o) = nfpFamily f (succ (derivFamily f o)) :=
derivFamily_add_one f o
theorem derivFamily_limit (f : ι → Ordinal → Ordinal) {o} :
IsSuccLimit o → derivFamily f o = ⨆ b : Set.Iio o, derivFamily f b :=
limitRecOn_limit _ _ _ _
theorem isNormal_derivFamily [Small.{u} ι] (f : ι → Ordinal.{u} → Ordinal.{u}) :
IsNormal (derivFamily f) := by
refine IsNormal.of_succ_lt (fun o ↦ ?_) @fun o h ↦ ?_
· rw [derivFamily_succ, ← succ_le_iff]
exact le_nfpFamily _ _
· rw [derivFamily_limit _ h, Set.image_eq_range]
have := h.nonempty_Iio.to_subtype
exact isLUB_ciSup (bddAbove_of_small _)
theorem derivFamily_strictMono [Small.{u} ι] (f : ι → Ordinal.{u} → Ordinal.{u}) :
StrictMono (derivFamily f) :=
(isNormal_derivFamily f).strictMono
theorem derivFamily_fp [Small.{u} ι] {i} (H : IsNormal (f i)) (o : Ordinal) :
f i (derivFamily f o) = derivFamily f o := by
induction o using limitRecOn with
| zero =>
rw [derivFamily_zero]
exact nfpFamily_fp H 0
| succ =>
rw [derivFamily_succ]
exact nfpFamily_fp H _
| limit o l IH =>
have := l.nonempty_Iio.to_subtype
rw [derivFamily_limit _ l, H.map_iSup (bddAbove_of_small _)]
refine eq_of_forall_ge_iff fun c => ?_
rw [Ordinal.iSup_le_iff, Ordinal.iSup_le_iff]
refine forall_congr' fun a ↦ ?_
rw [IH _ a.2]
theorem le_iff_derivFamily [Small.{u} ι] (H : ∀ i, IsNormal (f i)) {a} :
(∀ i, f i a ≤ a) ↔ ∃ o, derivFamily f o = a :=
⟨fun ha => by
suffices ∀ (o), a ≤ derivFamily f o → ∃ o, derivFamily f o = a from
this a (isNormal_derivFamily _).strictMono.le_apply
intro o
induction o using limitRecOn with
| zero =>
intro h₁
refine ⟨0, le_antisymm ?_ h₁⟩
rw [derivFamily_zero]
exact nfpFamily_le_fp (fun i => (H i).monotone) (zero_le _) ha
| succ o IH =>
intro h₁
rcases le_or_gt a (derivFamily f o) with h | h
· exact IH h
refine ⟨succ o, le_antisymm ?_ h₁⟩
rw [derivFamily_succ]
exact nfpFamily_le_fp (fun i => (H i).monotone) (succ_le_of_lt h) ha
| limit o l IH =>
intro h₁
rcases eq_or_lt_of_le h₁ with h | h
· exact ⟨_, h.symm⟩
rw [derivFamily_limit _ l, ← not_le, Ordinal.iSup_le_iff, not_forall] at h
obtain ⟨o', h⟩ := h
exact IH o' o'.2 (le_of_not_ge h),
fun ⟨_, e⟩ i => e ▸ (derivFamily_fp (H i) _).le⟩
theorem fp_iff_derivFamily [Small.{u} ι] (H : ∀ i, IsNormal (f i)) {a} :
(∀ i, f i a = a) ↔ ∃ o, derivFamily f o = a :=
Iff.trans ⟨fun h i => le_of_eq (h i), fun h i => (H i).strictMono.le_apply.ge_iff_eq'.1 (h i)⟩
(le_iff_derivFamily H)
theorem mem_range_derivFamily [Small.{u} ι] (H : ∀ i, IsNormal (f i)) {a} :
a ∈ Set.range (derivFamily f) ↔ ∀ i, f i a = a :=
(fp_iff_derivFamily H).symm
/-- For a family of normal functions, `Ordinal.derivFamily` enumerates the common fixed points. -/
theorem derivFamily_eq_enumOrd [Small.{u} ι] (H : ∀ i, IsNormal (f i)) :
derivFamily f = enumOrd (⋂ i, Function.fixedPoints (f i)) := by
rw [eq_comm, eq_enumOrd _ (not_bddAbove_fp_family H)]
use (isNormal_derivFamily f).strictMono
rw [Set.range_eq_iff]
refine ⟨?_, fun a ha => ?_⟩
· rintro a S ⟨i, hi⟩
rw [← hi]
exact derivFamily_fp (H i) a
rw [Set.mem_iInter] at ha
rwa [← fp_iff_derivFamily H]
end
/-! ### Fixed points of a single function -/
section
variable {f : Ordinal.{u} → Ordinal.{u}}
/-- The next fixed point function, the least fixed point of the normal function `f`, at least `a`.
This is defined as `nfpFamily` applied to a family consisting only of `f`. -/
def nfp (f : Ordinal → Ordinal) : Ordinal → Ordinal :=
nfpFamily fun _ : Unit => f
theorem nfp_eq_nfpFamily (f : Ordinal → Ordinal) : nfp f = nfpFamily fun _ : Unit => f :=
rfl
theorem iSup_iterate_eq_nfp (f : Ordinal.{u} → Ordinal.{u}) (a : Ordinal.{u}) :
⨆ n : ℕ, f^[n] a = nfp f a := by
apply le_antisymm
· rw [Ordinal.iSup_le_iff]
intro n
rw [← List.length_replicate (n := n) (a := Unit.unit), ← List.foldr_const f a]
exact Ordinal.le_iSup _ _
· apply Ordinal.iSup_le
intro l
rw [List.foldr_const f a l]
exact Ordinal.le_iSup _ _
theorem iterate_le_nfp (f a n) : f^[n] a ≤ nfp f a := by
rw [← iSup_iterate_eq_nfp]
exact Ordinal.le_iSup (fun n ↦ f^[n] a) n
theorem le_nfp (f a) : a ≤ nfp f a :=
iterate_le_nfp f a 0
theorem lt_nfp_iff {a b} : a < nfp f b ↔ ∃ n, a < f^[n] b := by
rw [← iSup_iterate_eq_nfp]
exact Ordinal.lt_iSup_iff
theorem nfp_le_iff {a b} : nfp f a ≤ b ↔ ∀ n, f^[n] a ≤ b := by
rw [← iSup_iterate_eq_nfp]
exact Ordinal.iSup_le_iff
theorem nfp_le {a b} : (∀ n, f^[n] a ≤ b) → nfp f a ≤ b :=
nfp_le_iff.2
@[simp]
theorem nfp_id : nfp id = id := by
ext
simp_rw [← iSup_iterate_eq_nfp, iterate_id]
exact ciSup_const
theorem nfp_monotone (hf : Monotone f) : Monotone (nfp f) :=
nfpFamily_monotone fun _ => hf
theorem iterate_lt_nfp (hf : StrictMono f) {a} (h : a < f a) (n : ℕ) : f^[n] a < nfp f a := by
apply (hf.iterate n h).trans_le
rw [← iterate_succ_apply]
exact iterate_le_nfp ..
theorem apply_lt_nfp (H : IsNormal f) {a b} : f b < nfp f a ↔ b < nfp f a := by
unfold nfp
rw [← @apply_lt_nfpFamily_iff Unit (fun _ => f) _ _ (fun _ => H) a b]
exact ⟨fun h _ => h, fun h => h Unit.unit⟩
@[deprecated (since := "2025-12-25")]
alias IsNormal.apply_lt_nfp := apply_lt_nfp
theorem nfp_le_apply (H : IsNormal f) {a b} : nfp f a ≤ f b ↔ nfp f a ≤ b :=
le_iff_le_iff_lt_iff_lt.2 (apply_lt_nfp H)
@[deprecated (since := "2025-12-25")]
alias IsNormal.nfp_le_apply := nfp_le_apply
theorem nfp_le_fp (H : Monotone f) {a b} (ab : a ≤ b) (h : f b ≤ b) : nfp f a ≤ b :=
nfpFamily_le_fp (fun _ => H) ab fun _ => h
theorem nfp_fp (H : IsNormal f) : ∀ a, f (nfp f a) = nfp f a :=
@nfpFamily_fp Unit (fun _ => f) _ () H
@[deprecated (since := "2025-12-25")]
alias IsNormal.nfp_fp := nfp_fp
theorem apply_le_nfp (H : IsNormal f) {a b} : f b ≤ nfp f a ↔ b ≤ nfp f a :=
⟨H.strictMono.le_apply.trans, fun h => by simpa only [nfp_fp H] using H.monotone h⟩
@[deprecated (since := "2025-12-25")]
alias IsNormal.apply_le_nfp := apply_le_nfp
theorem nfp_eq_self {a} (h : f a = a) : nfp f a = a :=
nfpFamily_eq_self fun _ => h
/-- The fixed point lemma for normal functions: any normal function has an unbounded set of
fixed points. -/
theorem not_bddAbove_fp (H : IsNormal f) : ¬ BddAbove (Function.fixedPoints f) := by
convert not_bddAbove_fp_family fun _ : Unit => H
exact (Set.iInter_const _).symm
/-- The derivative of a normal function `f` is the sequence of fixed points of `f`.
This is defined as `Ordinal.derivFamily` applied to a trivial family consisting only of `f`. -/
def deriv (f : Ordinal → Ordinal) : Ordinal → Ordinal :=
derivFamily fun _ : Unit => f
theorem deriv_eq_derivFamily (f : Ordinal → Ordinal) : deriv f = derivFamily fun _ : Unit => f :=
rfl
@[simp]
theorem deriv_zero_right (f) : deriv f 0 = nfp f 0 :=
derivFamily_zero _
@[simp]
theorem deriv_add_one (f o) : deriv f (o + 1) = nfp f (deriv f o + 1) :=
derivFamily_succ _ _
-- TODO: deprecate
theorem deriv_succ (f o) : deriv f (succ o) = nfp f (succ (deriv f o)) :=
deriv_add_one ..
theorem deriv_limit (f) {o} : IsSuccLimit o → deriv f o = ⨆ a : {a // a < o}, deriv f a :=
derivFamily_limit _
theorem isNormal_deriv (f) : IsNormal (deriv f) :=
isNormal_derivFamily _
theorem deriv_strictMono (f) : StrictMono (deriv f) :=
derivFamily_strictMono _
theorem deriv_eq_id_of_nfp_eq_id (h : nfp f = id) : deriv f = id :=
((isNormal_deriv _).ext .id).2 (by simp [h])
@[deprecated (since := "2025-10-25")]
alias deriv_id_of_nfp_id := deriv_eq_id_of_nfp_eq_id
theorem deriv_fp (H : IsNormal f) : ∀ o, f (deriv f o) = deriv f o :=
derivFamily_fp (i := ⟨⟩) H
@[deprecated (since := "2025-10-25")]
alias IsNormal.deriv_fp := deriv_fp
theorem le_iff_deriv (H : IsNormal f) {a} : f a ≤ a ↔ ∃ o, deriv f o = a := by
unfold deriv
rw [← le_iff_derivFamily fun _ : Unit => H]
exact ⟨fun h _ => h, fun h => h Unit.unit⟩
@[deprecated (since := "2025-10-25")]
alias IsNormal.le_iff_deriv := le_iff_deriv
theorem mem_range_deriv (H : IsNormal f) {a} : a ∈ Set.range (deriv f) ↔ f a = a := by
rw [Set.mem_range, ← H.strictMono.le_apply.ge_iff_eq', le_iff_deriv H]
@[deprecated mem_range_deriv (since := "2025-10-25")]
theorem fp_iff_deriv (H : IsNormal f) {a} : f a = a ↔ ∃ o, deriv f o = a :=
(mem_range_deriv H).symm
@[deprecated mem_range_deriv (since := "2025-10-25")]
alias IsNormal.fp_iff_deriv := fp_iff_deriv
/-- `Ordinal.deriv` enumerates the fixed points of a normal function. -/
theorem deriv_eq_enumOrd (H : IsNormal f) : deriv f = enumOrd (Function.fixedPoints f) := by
convert derivFamily_eq_enumOrd fun _ : Unit => H
exact (Set.iInter_const _).symm
theorem nfp_zero_left (a) : nfp 0 a = a := by
rw [← iSup_iterate_eq_nfp]
apply (Ordinal.iSup_le ?_).antisymm (Ordinal.le_iSup _ 0)
intro n
cases n
· rfl
· rw [Function.iterate_succ']
simp
@[simp]
theorem nfp_zero : nfp 0 = id := by
ext
exact nfp_zero_left _
@[simp]
theorem deriv_zero : deriv 0 = id :=
deriv_eq_id_of_nfp_eq_id nfp_zero
theorem deriv_zero_left (a) : deriv 0 a = a := by
rw [deriv_zero, id_eq]
end
/-! ### Fixed points of addition -/
@[simp]
theorem nfp_add_zero (a) : nfp (a + ·) 0 = a * ω := by
simp_rw [← iSup_iterate_eq_nfp, ← iSup_mul_natCast]
congr; funext n
induction n with
| zero => rw [Nat.cast_zero, mul_zero, iterate_zero_apply]
| succ n hn => rw [iterate_succ_apply', Nat.add_comm, Nat.cast_add, Nat.cast_one, mul_one_add, hn]
theorem nfp_add_eq_mul_omega0 {a b} (hba : b ≤ a * ω) : nfp (a + ·) b = a * ω := by
apply le_antisymm (nfp_le_fp (isNormal_add_right a).monotone hba _)
· rw [← nfp_add_zero]
exact nfp_monotone (isNormal_add_right a).monotone (zero_le b)
· dsimp; rw [← mul_one_add, one_add_omega0]
theorem add_eq_right_iff_mul_omega0_le {a b : Ordinal} : a + b = b ↔ a * ω ≤ b := by
refine ⟨fun h => ?_, fun h => ?_⟩
· rw [← nfp_add_zero a, ← deriv_zero_right]
obtain ⟨c, hc⟩ := (mem_range_deriv (isNormal_add_right a)).2 h
rw [← hc]
exact (isNormal_deriv _).monotone (zero_le _)
· have := Ordinal.add_sub_cancel_of_le h
nth_rw 1 [← this]
rwa [← add_assoc, ← mul_one_add, one_add_omega0]
theorem add_le_right_iff_mul_omega0_le {a b : Ordinal} : a + b ≤ b ↔ a * ω ≤ b := by
rw [← add_eq_right_iff_mul_omega0_le]
exact (isNormal_add_right a).strictMono.le_apply.ge_iff_eq'
theorem deriv_add_eq_mul_omega0_add (a b : Ordinal.{u}) : deriv (a + ·) b = a * ω + b := by
revert b
rw [← funext_iff, IsNormal.ext (isNormal_deriv _) (isNormal_add_right _)]
refine ⟨?_, fun a h => ?_⟩
· rw [bot_eq_zero, deriv_zero_right, add_zero]
exact nfp_add_zero a
· rw [deriv_succ, h, add_succ]
exact nfp_eq_self (add_eq_right_iff_mul_omega0_le.2 (le_self_add.trans (le_succ _)))
/-! ### Fixed points of multiplication -/
@[simp]
theorem nfp_mul_one {a : Ordinal} (ha : 0 < a) : nfp (a * ·) 1 = a ^ ω := by
rw [← iSup_iterate_eq_nfp, ← iSup_pow_natCast ha]
simp
@[simp]
theorem nfp_mul_zero (a : Ordinal) : nfp (a * ·) 0 = 0 := by
rw [← nonpos_iff_eq_zero, nfp_le_iff]
simp
theorem nfp_mul_eq_opow_omega0 {a b : Ordinal} (hb : 0 < b) (hba : b ≤ a ^ ω) :
nfp (a * ·) b = a ^ ω := by
rcases eq_zero_or_pos a with ha | ha
· rw [ha, zero_opow omega0_ne_zero] at hba ⊢
simp_rw [nonpos_iff_eq_zero.1 hba, zero_mul]
exact nfp_zero_left 0
apply le_antisymm
· apply nfp_le_fp (isNormal_mul_right ha).monotone hba
rw [← opow_one_add, one_add_omega0]
rw [← nfp_mul_one ha]
exact nfp_monotone (isNormal_mul_right ha).monotone (one_le_iff_pos.2 hb)
theorem eq_zero_or_opow_omega0_le_of_mul_eq_right {a b : Ordinal} (hab : a * b = b) :
b = 0 ∨ a ^ ω ≤ b := by
rcases eq_zero_or_pos a with ha | ha
· rw [ha, zero_opow omega0_ne_zero]
exact Or.inr (zero_le b)
rw [or_iff_not_imp_left]
intro hb
rw [← nfp_mul_one ha]
rw [← Ne, ← one_le_iff_ne_zero] at hb
exact nfp_le_fp (isNormal_mul_right ha).monotone hb (le_of_eq hab)
theorem mul_eq_right_iff_opow_omega0_dvd {a b : Ordinal} : a * b = b ↔ a ^ ω ∣ b := by
rcases eq_zero_or_pos a with ha | ha
· rw [ha, zero_mul, zero_opow omega0_ne_zero, zero_dvd_iff]
exact eq_comm
refine ⟨fun hab => ?_, fun h => ?_⟩
· rw [dvd_iff_mod_eq_zero]
rw [← div_add_mod b (a ^ ω), mul_add, ← mul_assoc, ← opow_one_add, one_add_omega0,
add_left_cancel_iff] at hab
rcases eq_zero_or_opow_omega0_le_of_mul_eq_right hab with hab | hab
· exact hab
refine (not_lt_of_ge hab (mod_lt b (opow_ne_zero ω ?_))).elim
rwa [← pos_iff_ne_zero]
obtain ⟨c, hc⟩ := h
rw [hc, ← mul_assoc, ← opow_one_add, one_add_omega0]
theorem mul_le_right_iff_opow_omega0_dvd {a b : Ordinal} (ha : 0 < a) :
a * b ≤ b ↔ (a ^ ω) ∣ b := by
rw [← mul_eq_right_iff_opow_omega0_dvd]
exact (isNormal_mul_right ha).strictMono.le_apply.ge_iff_eq'
theorem nfp_mul_opow_omega0_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c)
(hca : c ≤ a ^ ω) : nfp (a * ·) (a ^ ω * b + c) = a ^ ω * succ b := by
apply le_antisymm
· apply nfp_le_fp (isNormal_mul_right ha).monotone
· rw [mul_succ]
gcongr
· dsimp only; rw [← mul_assoc, ← opow_one_add, one_add_omega0]
· obtain ⟨d, hd⟩ :=
mul_eq_right_iff_opow_omega0_dvd.1 (nfp_fp (isNormal_mul_right ha) (a ^ ω * b + c))
rw [hd]
apply mul_le_mul_right
have := le_nfp (a * ·) (a ^ ω * b + c)
rw [hd] at this
have := (add_lt_add_right hc (a ^ ω * b)).trans_le this
rw [add_zero, mul_lt_mul_iff_right₀ (opow_pos ω ha)] at this
rwa [succ_le_iff]
theorem deriv_mul_eq_opow_omega0_mul {a : Ordinal.{u}} (ha : 0 < a) (b) :
deriv (a * ·) b = a ^ ω * b := by
revert b
rw [← funext_iff,
IsNormal.ext (isNormal_deriv _) (isNormal_mul_right (opow_pos ω ha))]
refine ⟨?_, fun c h => ?_⟩
· rw [bot_eq_zero, deriv_zero_right, nfp_mul_zero, mul_zero]
· rw [deriv_succ, h]
exact nfp_mul_opow_omega0_add c ha zero_lt_one (one_le_iff_pos.2 (opow_pos _ ha))
end Ordinal