extrealScript.sml

1(* ------------------------------------------------------------------------- *)
2(* Extended Real Numbers - Advanced Theory                                   *)
3(*                                                                           *)
4(* Original Authors: Tarek Mhamdi, Osman Hasan, Sofiene Tahar (2013, 2015)   *)
5(* HVG Group, Concordia University, Montreal                                 *)
6(* ------------------------------------------------------------------------- *)
7(* Updated and further enriched by Chun Tian (2018 - 2025)                   *)
8(* ------------------------------------------------------------------------- *)
9
10Theory extreal
11Ancestors
12  combin pred_set pair prim_rec arithmetic topology real
13  real_sigma iterate real_topology seq lim transc metric list
14  rich_list cardinal nets extreal_base real_of_rat
15Libs
16  metisLib res_quanTools jrhUtils numLib tautLib pred_setLib
17  hurdUtils realLib
18
19fun METIS ths tm = prove(tm, METIS_TAC ths);
20val set_ss = std_ss ++ PRED_SET_ss;
21val T_TAC = rpt (Q.PAT_X_ASSUM ‘T’ K_TAC);
22val DISC_RW_KILL = DISCH_TAC >> ONCE_ASM_REWRITE_TAC [] >> POP_ASSUM K_TAC;
23
24val _ = intLib.deprecate_int ();
25val _ = ratLib.deprecate_rat ();
26
27(* ------------------------------------------------------------------------- *)
28(*   Transcendental Operations                                               *)
29(* ------------------------------------------------------------------------- *)
30
31Definition extreal_exp_def :
32   (extreal_exp (Normal x) = Normal (exp x)) /\
33   (extreal_exp PosInf = PosInf) /\
34   (extreal_exp NegInf = Normal 0)
35End
36
37(* old definition: (`ln 0` is not defined)
38val extreal_ln_def = Define
39  `(extreal_ln (Normal x) = Normal (ln x)) /\
40   (extreal_ln PosInf = PosInf)`;
41
42   new definition: (ln 0 = NegInf)
43 *)
44local
45  val thm = Q.prove (
46     `?f. (!x. 0 < x ==> f (Normal x) = Normal (ln x)) /\
47          (f (Normal 0) = NegInf) /\
48          (f PosInf = PosInf)`,
49      Q.EXISTS_TAC `\y. if (y = Normal 0) then NegInf
50                        else if (y = PosInf) then PosInf
51                        else if (?r. (y = Normal r) /\ r <> 0) then Normal (ln (real y))
52                        else ARB` \\
53      RW_TAC std_ss [extreal_not_infty, real_normal, REAL_LT_REFL]);
54in
55   (* |- (!x. 0 < x ==> extreal_ln (Normal x) = Normal (ln x)) /\
56         extreal_ln (Normal 0) = NegInf /\
57         extreal_ln PosInf = PosInf
58    *)
59   val extreal_ln_def = new_specification
60     ("extreal_ln_def", ["extreal_ln"], thm);
61end;
62
63Definition extreal_powr_def :
64    extreal_powr x a = extreal_exp (extreal_mul a (extreal_ln x))
65End
66
67(* removed `extreal_logr b NegInf = NegInf` *)
68Definition extreal_logr_def :
69   (extreal_logr b (Normal x) = Normal (logr b x)) /\
70   (extreal_logr b PosInf = PosInf)
71End
72
73Definition extreal_lg_def :
74    extreal_lg x = extreal_logr 2 x
75End
76
77Overload exp  = “extreal_exp”
78Overload powr = “extreal_powr”
79Overload logr = “extreal_logr”
80Overload lg   = “extreal_lg”
81Overload ln   = “extreal_ln”
82
83(***************************)
84(*      Log and Ln         *)
85(***************************)
86
87Theorem logr_not_infty:
88    !x b. (x <> NegInf /\ x <> PosInf) ==> logr b x <> NegInf /\ logr b x <> PosInf
89Proof
90    Cases >> RW_TAC std_ss [extreal_logr_def, extreal_not_infty]
91QED
92
93Theorem ln_not_neginf :
94    !x. 0 < x ==> ln x <> NegInf
95Proof
96    rpt STRIP_TAC
97 >> ‘0 <= x’ by PROVE_TAC [lt_imp_le]
98 >> ‘x <> NegInf’ by PROVE_TAC [pos_not_neginf]
99 >> Cases_on ‘x’
100 >> rfs [extreal_ln_def, extreal_of_num_def, extreal_lt_eq, extreal_le_eq]
101QED
102
103(* cf. transcTheory.LN_MUL
104   NOTE: this lemma also holds if ‘x = 0 /\ y <> PosInf’, etc.
105 *)
106Theorem ln_mul :
107    !x y. 0 < x /\ 0 < y ==> ln (x * y) = ln x + ln y
108Proof
109    rpt STRIP_TAC
110 >> ‘0 <= x /\ 0 <= y’ by PROVE_TAC [lt_imp_le]
111 >> ‘x <> NegInf /\ y <> NegInf’ by PROVE_TAC [pos_not_neginf]
112 >> Cases_on ‘x’ >> fs []
113 >- (rw [extreal_ln_def, mul_infty] \\
114    ‘ln y <> NegInf’ by PROVE_TAC [ln_not_neginf] \\
115     Q.ABBREV_TAC ‘x = ln y’ \\
116     Cases_on ‘x’ >> fs [extreal_add_def])
117 >> Cases_on ‘y’ >> fs []
118 >- fs [extreal_ln_def, mul_infty, extreal_of_num_def, extreal_lt_eq, extreal_le_eq,
119        le_infty, extreal_add_def]
120 >> fs [extreal_of_num_def, extreal_lt_eq, extreal_le_eq, extreal_mul_def]
121 >> ‘0 < r * r'’ by PROVE_TAC [REAL_LT_MUL]
122 >> rw [extreal_ln_def, extreal_add_def]
123 >> MATCH_MP_TAC LN_MUL >> art []
124QED
125
126(* cf. transcTheory.LN_1 *)
127Theorem ln_1 :
128    ln (1 :extreal) = 0
129Proof
130    rw [extreal_of_num_def, extreal_ln_def, LN_1]
131QED
132
133(* cf. transcTheory.LN_POS_LT *)
134Theorem ln_pos_lt :
135    !x. 1 < x ==> 0 < ln x
136Proof
137    rpt STRIP_TAC
138 >> ‘0 < x’ by METIS_TAC [lt_trans, lt_01]
139 >> ‘0 <= x’ by rw [lt_imp_le]
140 >> ‘x <> NegInf’ by rw [pos_not_neginf]
141 >> Cases_on ‘x’
142 >> fs [extreal_of_num_def, extreal_le_eq, extreal_lt_eq, le_infty,
143        extreal_ln_def, lt_infty, LN_POS_LT]
144QED
145
146(* cf. transcTheory.LN_POS *)
147Theorem ln_pos :
148    !x. 1 <= x ==> 0 <= ln x
149Proof
150    rpt STRIP_TAC
151 >> ‘x = 1 \/ 1 < x’ by PROVE_TAC [le_lt] >- rw [ln_1]
152 >> MATCH_MP_TAC lt_imp_le
153 >> MATCH_MP_TAC ln_pos_lt >> art []
154QED
155
156(* cf. transcTheory.LN_NEG_LT, changed: ‘0 <= x’ *)
157Theorem ln_neg_lt :
158    !x. 0 <= x /\ x < 1 ==> ln x < 0
159Proof
160    rpt STRIP_TAC
161 >> ‘x = 0 \/ 0 < x’ by PROVE_TAC [le_lt]
162 >- rw [extreal_of_num_def, extreal_ln_def, lt_infty]
163 >> ‘x <> NegInf’ by rw [pos_not_neginf]
164 >> Cases_on ‘x’
165 >> fs [extreal_of_num_def, extreal_le_eq, extreal_lt_eq, le_infty,
166        extreal_ln_def, lt_infty, LN_NEG_LT]
167QED
168
169(* cf. transcTheory.LN_NEG, changed: ‘0 <= x’ *)
170Theorem ln_neg :
171    !x. 0 <= x /\ x <= 1 ==> ln x <= 0
172Proof
173    rpt STRIP_TAC
174 >> ‘x = 1 \/ x < 1’ by PROVE_TAC [le_lt] >- rw [ln_1]
175 >> MATCH_MP_TAC lt_imp_le
176 >> MATCH_MP_TAC ln_neg_lt >> art []
177QED
178
179(* cf. transcTheory.LN_INV *)
180Theorem ln_inv :
181    !x. 0 < x ==> ln (inv x) = ~(ln x)
182Proof
183    rpt STRIP_TAC
184 >> ‘0 <= x’ by rw [le_lt]
185 >> ‘x <> NegInf’ by rw [pos_not_neginf]
186 >> Cases_on ‘x’ >> fs [extreal_ln_def, extreal_inv_def, extreal_ainv_def]
187 >> fs [extreal_of_num_def, extreal_lt_eq, extreal_le_eq]
188 >> ‘r <> 0’ by rw [REAL_LT_IMP_NE]
189 >> rw [extreal_inv_def, extreal_ln_def, extreal_ainv_def]
190 >> MATCH_MP_TAC LN_INV >> art []
191QED
192
193(***************************)
194(*      Exp and powr       *)
195(***************************)
196
197Theorem exp_pos :
198    !x :extreal. 0 <= exp x
199Proof
200    Q.X_GEN_TAC ‘x’ >> Cases_on `x`
201 >> RW_TAC real_ss [extreal_exp_def, le_infty, extreal_of_num_def,
202                    extreal_le_eq, EXP_POS_LE]
203QED
204
205(* cf. transcTheory.EXP_POS_LT *)
206Theorem exp_pos_lt :
207    !x. x <> NegInf ==> 0 < exp x
208Proof
209    rpt STRIP_TAC
210 >> Cases_on ‘x’ >> rw [extreal_exp_def]
211 >> rw [extreal_of_num_def, extreal_lt_eq, EXP_POS_LT]
212QED
213
214Theorem normal_exp :
215    !r. exp (Normal r) = Normal (exp r)
216Proof
217    RW_TAC std_ss [extreal_exp_def]
218QED
219
220Theorem exp_0[simp] :
221    exp 0 = (1 :extreal)
222Proof
223    rw [extreal_of_num_def, normal_exp, extreal_11, EXP_0]
224QED
225
226Theorem exp_add_lemma[local] :
227    !x y. x <> NegInf /\ y <> NegInf ==> exp (x + y) = exp x * exp y
228Proof
229    rpt STRIP_TAC
230 >> Cases_on ‘x’ >> fs []
231 >- (rw [extreal_exp_def] \\
232    ‘0 < exp y’ by PROVE_TAC [exp_pos_lt] \\
233     rw [mul_infty, add_infty, extreal_exp_def])
234 >> Cases_on ‘y’ >> fs []
235 >- (rw [add_infty, extreal_exp_def, mul_infty] \\
236    ‘0 < exp r’ by PROVE_TAC [EXP_POS_LT] \\
237     rw [extreal_mul_def] >> PROVE_TAC [REAL_LT_IMP_NE])
238 >> rw [extreal_add_def, extreal_mul_def, extreal_exp_def, EXP_ADD]
239QED
240
241Theorem exp_add_lemma'[local] :
242    !x y. x <> PosInf /\ y <> PosInf ==> exp (x + y) = exp x * exp y
243Proof
244    rpt STRIP_TAC
245 >> Cases_on ‘x’ >> fs []
246 >- (rw [extreal_exp_def, GSYM extreal_of_num_def] \\
247     rw [add_infty, extreal_exp_def])
248 >> Cases_on ‘y’ >> fs []
249 >- (rw [add_infty, extreal_exp_def, mul_infty, GSYM extreal_of_num_def])
250 >> rw [extreal_add_def, extreal_mul_def, extreal_exp_def, EXP_ADD]
251QED
252
253Theorem exp_add :
254    !x y. (x <> NegInf /\ y <> NegInf) \/ (x <> PosInf /\ y <> PosInf) ==>
255          exp (x + y) = exp x * exp y
256Proof
257    METIS_TAC [exp_add_lemma, exp_add_lemma']
258QED
259
260(* cf. transcTheory.EXP_NEG, with ‘x <> NegInf’ added *)
261Theorem exp_neg :
262    !x. x <> NegInf ==> exp (~x) = inv (exp(x))
263Proof
264    Q.X_GEN_TAC ‘x’
265 >> Cases_on ‘x’
266 >> rw [extreal_exp_def, extreal_ainv_def, extreal_inv_def]
267 >> ‘0 < exp r’ by rw [EXP_POS_LT]
268 >> ‘exp r <> 0’ by rw [REAL_LT_IMP_NE]
269 >> rw [extreal_inv_def, EXP_NEG]
270QED
271
272(* cf. transcTheory.EXP_LE_X_FULL *)
273Theorem exp_le_x :
274    !x :extreal. &1 + x <= exp x
275Proof
276    Q.X_GEN_TAC ‘x’
277 >> Cases_on ‘x’
278 >> rw [extreal_of_num_def, extreal_add_def, extreal_exp_def, le_infty,
279        extreal_le_eq, EXP_LE_X_FULL]
280QED
281
282Theorem exp_le_x' :
283    !x :extreal. &1 - x <= exp (-x)
284Proof
285    Q.X_GEN_TAC ‘x’
286 >> MP_TAC (Q.SPEC ‘-x’ exp_le_x)
287 >> Suff ‘1 - x = 1 + -x’ >- rw []
288 >> MATCH_MP_TAC extreal_sub_add
289 >> rw [extreal_of_num_def]
290QED
291
292(***************************)
293
294Theorem powr_pos :
295    !x a :extreal. 0 <= x powr a
296Proof
297    RW_TAC std_ss [extreal_powr_def, exp_pos]
298QED
299
300(* cf. transcTheory.RPOW_POS_LT *)
301Theorem powr_pos_lt :
302    !x a. 0 < x /\ 0 <= a /\ a <> PosInf ==> 0 < x powr a
303Proof
304    RW_TAC std_ss [extreal_powr_def]
305 >> MATCH_MP_TAC exp_pos_lt
306 >> ‘a <> NegInf’ by rw [pos_not_neginf]
307 >> ‘?r. 0 <= r /\ a = Normal r’
308      by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_le_eq]
309 >> POP_ORW
310 >> ‘ln x <> NegInf’ by PROVE_TAC [ln_not_neginf]
311 >> METIS_TAC [mul_not_infty]
312QED
313
314Theorem infty_powr :
315    !a. 0 < a ==> PosInf powr a = PosInf
316Proof
317    rw [extreal_powr_def, extreal_ln_def, mul_infty, extreal_exp_def]
318QED
319
320(* NOTE: ‘0 rpow a’ is not defined (see transcTheory.rpow_def) *)
321Theorem normal_powr :
322    !r a. 0 < r /\ 0 < a ==> (Normal r) powr (Normal a) = Normal (r powr a)
323Proof
324    RW_TAC real_ss [extreal_exp_def, extreal_mul_def, extreal_powr_def,
325                    extreal_ln_def, rpow_def]
326QED
327
328Theorem powr_0[simp] :
329    !x. x powr 0 = (1 :extreal)
330Proof
331    rw [extreal_powr_def, exp_0]
332QED
333
334(* cf. transc.ONE_RPOW, changed ‘0 < a’ to ‘0 <= a’ *)
335Theorem one_powr :
336    !a. 0 <= a ==> 1 powr a = 1
337Proof
338    rpt STRIP_TAC
339 >> Cases_on ‘a = 0’ >- rw []
340 >> ‘0 < a’ by rw [lt_le]
341 >> rw [extreal_powr_def, ln_1]
342QED
343
344(* only possible after the new definition of `ln` *)
345Theorem zero_rpow :
346    !x :extreal. 0 < x ==> 0 powr x = 0
347Proof
348    RW_TAC std_ss [extreal_of_num_def, extreal_powr_def, extreal_ln_def]
349 >> Cases_on `x`
350 >- METIS_TAC [lt_infty]
351 >- RW_TAC std_ss [extreal_mul_def, extreal_exp_def]
352 >> FULL_SIMP_TAC std_ss [extreal_mul_def, extreal_lt_eq]
353 >> `r <> 0` by PROVE_TAC [REAL_LT_LE]
354 >> ASM_SIMP_TAC std_ss [extreal_exp_def]
355QED
356
357Theorem powr_eq_0 :
358    !x a. 0 <= x /\ 0 < a /\ a <> PosInf ==> (x powr a = 0 <=> x = 0)
359Proof
360    rpt STRIP_TAC
361 >> reverse EQ_TAC >- rw [zero_rpow]
362 >> ‘0 <= a’ by rw [lt_imp_le]
363 >> ‘a <> NegInf’ by rw [pos_not_neginf]
364 >> DISCH_TAC
365 >> CCONTR_TAC
366 >> ‘0 < x’ by PROVE_TAC [le_lt]
367 >> ‘0 < x powr a’ by PROVE_TAC [powr_pos_lt]
368 >> METIS_TAC [lt_antisym]
369QED
370
371(* cf. transcTheory.RPOW_1, changed to ‘0 <= x’
372   NOTE: another way is to use extreal_powr_def and "exp_ln" (not available yet)
373 *)
374Theorem powr_1 :
375    !x. 0 <= x ==> x powr 1 = x
376Proof
377    rpt STRIP_TAC
378 >> Cases_on ‘x = PosInf’ >- rw [infty_powr]
379 >> Cases_on ‘x = 0’ >- rw [zero_rpow]
380 >> ‘0 < x’ by PROVE_TAC [le_lt]
381 >> ‘x <> NegInf’ by PROVE_TAC [pos_not_neginf]
382 >> ‘?r. 0 < r /\ x = Normal r’
383      by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
384 >> rw [extreal_of_num_def, normal_powr, RPOW_1]
385QED
386
387Theorem powr_infty :
388    !x. (1 < x ==> x powr PosInf = PosInf) /\
389        (x = 1 ==> x powr PosInf = 1) /\
390        (0 <= x /\ x < 1 ==> x powr PosInf = 0)
391Proof
392    RW_TAC std_ss [] (* 3 goals *)
393 >| [ (* goal 1 (of 3) *)
394      rw [extreal_powr_def] \\
395     ‘0 < ln x’ by PROVE_TAC [ln_pos_lt] \\
396      rw [mul_infty, extreal_exp_def],
397      (* goal 2 (of 3) *)
398      MATCH_MP_TAC one_powr \\
399      rw [extreal_of_num_def, le_infty],
400      (* goal 3 (of 3) *)
401      rw [extreal_powr_def] \\
402      Suff ‘ln x < 0’
403      >- (DISCH_TAC \\
404         ‘PosInf * ln x = NegInf’ by PROVE_TAC [mul_infty'] \\
405          rw [extreal_exp_def]) \\
406      MATCH_MP_TAC ln_neg_lt >> art [] ]
407QED
408
409(* cf. transcTheory.BASE_RPOW_LE *)
410Theorem powr_mono_eq :
411    !a b c. 0 <= a /\ 0 <= c /\ 0 < b /\ b <> PosInf ==> (a powr b <= c powr b <=> a <= c)
412Proof
413    rpt STRIP_TAC
414 >> ‘0 <= b’ by rw [lt_imp_le]
415 >> ‘a <> NegInf /\ b <> NegInf /\ c <> NegInf’ by rw [pos_not_neginf]
416 >> Cases_on ‘a = 0’ >- rw [zero_rpow, powr_pos]
417 >> Cases_on ‘c = 0’
418 >- (rw [zero_rpow, powr_pos] \\
419    ‘0 <= a powr b’ by rw [powr_pos] \\
420     EQ_TAC >> rw [] >| (* 2 subgoals *)
421     [ (* goal 1 (of 2) *)
422      ‘a powr b = 0’ by PROVE_TAC [le_antisym] \\
423       rfs [powr_eq_0],
424       (* goal 2 (of 2) *)
425       PROVE_TAC [le_antisym] ])
426 >> ‘0 < a /\ 0 < c’ by PROVE_TAC [le_lt]
427 >> Cases_on ‘a = PosInf’ >> rw [infty_powr, le_infty]
428 >- (EQ_TAC >> rw [infty_powr] \\
429     CCONTR_TAC \\
430    ‘?r. 0 < r /\ c = Normal r’
431       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq] \\
432    ‘?p. 0 < p /\ b = Normal p’
433       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq] \\
434     fs [normal_powr])
435 >> Cases_on ‘c = PosInf’ >> rw [infty_powr, le_infty]
436 >> ‘?A. 0 < A /\ a = Normal A’
437       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
438 >> ‘?B. 0 < B /\ b = Normal B’
439       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
440 >> ‘?C. 0 < C /\ c = Normal C’
441       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
442 >> rw [BASE_RPOW_LE, normal_powr, extreal_le_eq]
443QED
444
445(* cf. transcTheory.RPOW_LE *)
446Theorem powr_le_eq :
447    !a b c. 1 < a /\ a <> PosInf /\ 0 <= b /\ 0 <= c ==>
448           (a powr b <= a powr c <=> b <= c)
449Proof
450    rpt STRIP_TAC
451 >> ‘0 < a’ by PROVE_TAC [lt_trans, lt_01]
452 >> ‘0 <= a’ by PROVE_TAC [lt_imp_le]
453 >> ‘a <> NegInf /\ b <> NegInf /\ c <> NegInf’ by rw [pos_not_neginf]
454 >> Cases_on ‘b = 0’
455 >- (rw [powr_0] \\
456     Cases_on ‘c = 0’ >- rw [powr_0] \\
457     Cases_on ‘c = PosInf’
458     >- (rw [powr_infty, extreal_le_def, extreal_of_num_def]) \\
459    ‘0 < c’ by rw [lt_le] \\
460    ‘1 = 1 powr c’ by PROVE_TAC [one_powr] >> POP_ORW \\
461     rw [powr_mono_eq, lt_imp_le])
462 >> ‘0 < b’ by rw [lt_le]
463 >> Cases_on ‘c = 0’
464 >- (rw [powr_0] \\
465     Cases_on ‘b = PosInf’
466     >- (rw [powr_infty, extreal_le_def, extreal_of_num_def]) \\
467    ‘1 = 1 powr b’ by PROVE_TAC [one_powr] >> POP_ORW \\
468     rw [powr_mono_eq] \\
469     METIS_TAC [extreal_lt_def])
470 >> ‘0 < c’ by rw [lt_le]
471 >> Cases_on ‘b = PosInf’
472 >- (rw [powr_infty, extreal_le_def, extreal_of_num_def, le_infty] \\
473     Cases_on ‘c = PosInf’ >- rw [powr_infty] \\
474    ‘?A. 0 < A /\ a = Normal A’
475       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq] \\
476    ‘?C. 0 < C /\ c = Normal C’
477       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq] \\
478     rw [normal_powr])
479 >> Cases_on ‘c = PosInf’
480 >- rw [powr_infty, extreal_le_def, extreal_of_num_def, le_infty]
481 >> ‘?A. 0 < A /\ a = Normal A’
482       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
483 >> ‘?B. 0 < B /\ b = Normal B’
484       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
485 >> ‘?C. 0 < C /\ c = Normal C’
486       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
487 >> gs [RPOW_LE, normal_powr, extreal_of_num_def, extreal_le_eq, extreal_lt_eq]
488QED
489
490Theorem powr_ge_1 :
491    !a p. 1 <= a /\ 0 <= p ==> 1 <= a powr p
492Proof
493    rpt STRIP_TAC
494 >> Cases_on ‘p = 0’ >- rw [powr_0]
495 >> Cases_on ‘a = 1’ >- rw [one_powr]
496 >> ‘0 < p /\ 1 < a’ by rw [lt_le]
497 >> Cases_on ‘a = PosInf’ >- rw [infty_powr]
498 >> ‘1 = a powr 0’ by rw [] >> POP_ORW
499 >> rw [powr_le_eq]
500QED
501
502(* cf. transcTheory.RPOW_RPOW
503   changed: ‘0 <= a’, added: ‘b <> PosInf /\ c <> PosInf’ *)
504Theorem powr_powr :
505    !a b c. 0 <= a /\ 0 < b /\ 0 < c /\ b <> PosInf /\ c <> PosInf ==>
506           (a powr b) powr c = a powr (b * c)
507Proof
508    rpt STRIP_TAC
509 >> ‘a = 0 \/ 0 < a’ by PROVE_TAC [le_lt]
510 >- rw [zero_rpow, lt_mul]
511 >> ‘0 < b * c’ by rw [lt_mul]
512 (* applying infty_powr *)
513 >> Cases_on ‘a = PosInf’ >- rw [infty_powr]
514 (* applying normal_powr *)
515 >> ‘b <> 0 /\ c <> 0’ by rw [lt_imp_ne]
516 >> ‘0 <= b /\ 0 <= c’ by rw [lt_imp_le]
517 >> ‘a <> NegInf /\ b <> NegInf /\ c <> NegInf’ by rw [pos_not_neginf]
518 >> ‘?A. 0 < A /\ a = Normal A’
519      by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq, extreal_le_eq]
520 >> POP_ORW
521 >> ‘?B. 0 < B /\ b = Normal B’
522      by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq, extreal_le_eq]
523 >> POP_ORW
524 >> ‘?C. 0 < C /\ c = Normal C’
525      by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq, extreal_le_eq]
526 >> POP_ORW
527 >> ‘0 < B * C’ by rw [REAL_LT_MUL]
528 >> ‘0 < A powr B’ by rw [RPOW_POS_LT]
529 >> rw [extreal_mul_def, normal_powr, RPOW_RPOW]
530QED
531
532(* cf. transcTheory.RPOW_MUL *)
533Theorem mul_powr :
534    !x y a. 0 <= x /\ 0 <= y /\ 0 < a /\ a <> PosInf ==>
535           (x * y) powr a = x powr a * y powr a
536Proof
537    rpt STRIP_TAC
538 >> ‘x = 0 \/ 0 < x’ by PROVE_TAC [le_lt] >- rw [zero_rpow]
539 >> ‘y = 0 \/ 0 < y’ by PROVE_TAC [le_lt] >- rw [zero_rpow]
540 >> rw [extreal_powr_def, ln_mul]
541 >> ‘0 <= a’ by rw [le_lt]
542 >> ‘a <> NegInf’ by rw [pos_not_neginf]
543 >> ‘?r. 0 < r /\ a = Normal r’
544      by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
545 >> POP_ORW
546 >> rw [ln_not_neginf, add_ldistrib_normal]
547 >> MATCH_MP_TAC exp_add
548 >> DISJ1_TAC
549 >> METIS_TAC [mul_not_infty, ln_not_neginf, REAL_LT_IMP_LE]
550QED
551
552(* cf. transcTheory.RPOW_ADD *)
553Theorem powr_add :
554    !a b c. 0 <= a /\ 0 <= b /\ b <> PosInf /\ 0 <= c /\ c <> PosInf ==>
555            a powr (b + c) = a powr b * a powr c
556Proof
557    rpt STRIP_TAC
558 >> ‘a <> NegInf /\ b <> NegInf /\ c <> NegInf’ by rw [pos_not_neginf]
559 >> Cases_on ‘b = 0’ >- rw []
560 >> Cases_on ‘c = 0’ >- rw []
561 >> ‘0 < b /\ 0 < c’ by rw [lt_le]
562 >> ‘0 < b + c’ by rw [lt_add]
563 >> Cases_on ‘a = 0’ >- rw [zero_rpow]
564 >> ‘0 < a’ by rw [lt_le]
565 >> Cases_on ‘a = PosInf’
566 >- rw [infty_powr, extreal_mul_def]
567 >> ‘?A. 0 < A /\ a = Normal A’
568       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
569 >> ‘?B. 0 < B /\ b = Normal B’
570       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
571 >> ‘?C. 0 < C /\ c = Normal C’
572       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
573 >> ‘0 < B + C’ by rw [REAL_LT_ADD]
574 >> rw [normal_powr, extreal_add_def, extreal_mul_def, RPOW_ADD]
575QED
576
577Theorem sqrt_powr :
578    !x. 0 <= x ==> sqrt x = x powr (inv 2)
579Proof
580    rpt STRIP_TAC
581 >> ‘x <> NegInf’ by rw [pos_not_neginf]
582 >> ‘0 < inv 2’ by rw [inv_pos']
583 >> ‘x = 0 \/ 0 < x’ by PROVE_TAC [le_lt]
584 >- rw [sqrt_0, zero_rpow]
585 >> Cases_on ‘x’ >> fs [extreal_sqrt_def]
586 >- rw [infty_powr]
587 >> fs [extreal_of_num_def, extreal_lt_eq, extreal_le_eq, extreal_inv_eq]
588 >> ‘0 < inv (2 :real)’ by rw [REAL_INV_POS]
589 >> rw [normal_powr]
590 >> MATCH_MP_TAC SQRT_RPOW >> art []
591QED
592
593(* cf. transcTheory.RPOW_INV *)
594Theorem inv_powr :
595    !x p. 0 < x /\ 0 < p /\ p <> PosInf ==> (inv x) powr p = inv (x powr p)
596Proof
597    rw [extreal_powr_def, ln_inv]
598 >> ‘ln x <> NegInf’ by rw [ln_not_neginf]
599 >> ‘0 <= p’ by rw [le_lt]
600 >> ‘p <> NegInf’ by rw [pos_not_neginf]
601 >> Suff ‘inv (exp (p * ln x)) = exp (~(p * ln x))’ >- rw [mul_rneg]
602 >> ONCE_REWRITE_TAC [EQ_SYM_EQ]
603 >> MATCH_MP_TAC exp_neg
604 >> ‘?r. 0 <= r /\ p = Normal r’
605      by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_le_eq]
606 >> POP_ORW
607 >> METIS_TAC [mul_not_infty]
608QED
609
610(* cf. transcTheory.GEN_RPOW. *)
611Theorem gen_powr :
612    !a n. 0 <= a ==> (a pow n = a powr (&n :extreal))
613Proof
614    rpt STRIP_TAC
615 >> Cases_on `n = 0` >- rw []
616 >> Cases_on `a`
617 >- METIS_TAC [lt_imp_le, le_not_infty]
618 >- (`(0 :real) < &n` by RW_TAC real_ss [] \\
619     `(0 :extreal) < &n` by METIS_TAC [extreal_of_num_def, extreal_lt_eq] \\
620     ASM_SIMP_TAC std_ss [extreal_pow_def, extreal_powr_def, extreal_ln_def,
621                          mul_infty, extreal_exp_def])
622 >> `(0 :real) < &n` by RW_TAC real_ss []
623 >> `(0 :extreal) < &n` by METIS_TAC [extreal_of_num_def, extreal_lt_eq]
624 >> FULL_SIMP_TAC std_ss [le_lt]
625 >- (`?b. &n = Normal (&n)`
626       by METIS_TAC [num_not_infty, extreal_cases, extreal_of_num_def] \\
627     POP_ORW \\
628     FULL_SIMP_TAC std_ss [extreal_pow_def, normal_powr, extreal_lt_eq,
629                           extreal_11, extreal_of_num_def] \\
630     MATCH_MP_TAC GEN_RPOW >> art [])
631 >> Q.PAT_X_ASSUM `0 = Normal r` (ONCE_REWRITE_TAC o wrap o SYM)
632 >> ASM_SIMP_TAC std_ss [zero_rpow]
633 >> MATCH_MP_TAC zero_pow
634 >> RW_TAC arith_ss []
635QED
636
637(* cf. transcTheory.YOUNG_INEQUALITY, note that the extreal version supports
638      ‘0 <= a /\ 0 <= b’ instead of ‘0 < a /\ 0 < b’ in the real case.
639
640   NOTE: ‘p <> PosInf /\ q <> PosInf’ (thus also ‘0 < p /\ 0 < q’) cannot be
641         removed in general, for there may be ‘PosInf / PosInf’ at RHS.
642 *)
643Theorem young_inequality :
644    !a b p q. 0 <= a /\ 0 <= b /\ 0 < p /\ 0 < q /\ p <> PosInf /\ q <> PosInf /\
645              inv(p) + inv(q) = 1
646          ==> a * b <= a powr p / p + b powr q / q
647Proof
648    rpt STRIP_TAC
649 >> ‘p <> 0 /\ q <> 0’ by PROVE_TAC [lt_imp_ne]
650 >> ‘a = 0 \/ 0 < a’ by METIS_TAC [le_lt]
651 >- (rw [zero_rpow, zero_div] \\
652     Cases_on ‘q’ >> fs [lt_infty] \\
653     MATCH_MP_TAC le_div \\
654     reverse CONJ_TAC >- fs [extreal_of_num_def, extreal_lt_eq] \\
655     REWRITE_TAC [powr_pos])
656 >> ‘b = 0 \/ 0 < b’ by METIS_TAC [le_lt]
657 >- (rw [zero_rpow, zero_div] \\
658     Cases_on ‘p’ >> fs [lt_infty] \\
659     MATCH_MP_TAC le_div \\
660     reverse CONJ_TAC >- fs [extreal_of_num_def, extreal_lt_eq] \\
661     REWRITE_TAC [powr_pos])
662 >> Cases_on ‘a’ >- fs [lt_infty]
663 >- (rw [mul_infty, infty_powr] \\
664     Know ‘PosInf / p = PosInf’
665     >- (Cases_on ‘p’ >> fs [lt_infty, extreal_of_num_def, extreal_lt_eq] \\
666         rw [infty_div]) >> Rewr' \\
667     MATCH_MP_TAC le_addr_imp \\
668     Cases_on ‘q’ >> fs [lt_infty] \\
669     MATCH_MP_TAC le_div \\
670     reverse CONJ_TAC >- fs [extreal_of_num_def, extreal_lt_eq] \\
671     REWRITE_TAC [powr_pos])
672 >> rename1 ‘0 < Normal A’
673 >> Cases_on ‘b’ >- fs [lt_infty]
674 >- (rw [mul_infty, infty_powr] \\
675     Know ‘PosInf / q = PosInf’
676     >- (Cases_on ‘q’ >> fs [lt_infty, extreal_of_num_def, extreal_lt_eq] \\
677         rw [infty_div]) >> Rewr' \\
678     MATCH_MP_TAC le_addl_imp \\
679     Cases_on ‘p’ >> fs [lt_infty] \\
680     MATCH_MP_TAC le_div \\
681     reverse CONJ_TAC >- fs [extreal_of_num_def, extreal_lt_eq] \\
682     REWRITE_TAC [powr_pos])
683 >> rename1 ‘0 < Normal B’
684 >> ‘p <> NegInf’ by PROVE_TAC [pos_not_neginf, lt_imp_le]
685 >> ‘q <> NegInf’ by PROVE_TAC [pos_not_neginf, lt_imp_le]
686 >> ‘?P. p = Normal P’ by METIS_TAC [extreal_cases]
687 >> POP_ASSUM (FULL_SIMP_TAC std_ss o wrap)
688 >> ‘?Q. q = Normal Q’ by METIS_TAC [extreal_cases]
689 >> POP_ASSUM (FULL_SIMP_TAC std_ss o wrap)
690 >> fs [extreal_not_infty, extreal_of_num_def, extreal_lt_eq, extreal_le_eq,
691        extreal_inv_eq, extreal_add_def]
692 >> rw [extreal_mul_def, normal_powr, extreal_div_eq, extreal_add_def,
693        extreal_le_eq]
694 >> MATCH_MP_TAC YOUNG_INEQUALITY >> art []
695QED
696
697(* NOTE: improved ‘p = 1 ==> q = PosInf’ to ‘p = 1 <=> q = PosInf’, etc. *)
698Theorem conjugate_properties :
699    !p q. 0 < p /\ 0 < q /\ inv(p) + inv(q) = 1 ==>
700          1 <= p /\ 1 <= q /\ (p = 1 <=> q = PosInf) /\ (q = 1 <=> p = PosInf)
701Proof
702    rpt GEN_TAC >> STRIP_TAC
703 >> ‘0 <= inv p /\ 0 <= inv q’ by PROVE_TAC [le_inv]
704 >> rpt CONJ_TAC
705 >| [ (* goal 1 (of 4) *)
706      Know ‘1 <= p <=> inv p <= inv 1’
707      >- (MATCH_MP_TAC (GSYM inv_le_antimono) >> art [lt_01]) >> Rewr' \\
708      rw [inv_one] \\
709      SPOSE_NOT_THEN (ASSUME_TAC o (REWRITE_RULE [GSYM extreal_lt_def])) \\
710      Know ‘1 < inv p <=> 1 + inv q < inv p + inv q’
711      >- (ONCE_REWRITE_TAC [EQ_SYM_EQ] \\
712          MATCH_MP_TAC lt_radd \\
713         ‘q <> 0’ by PROVE_TAC [lt_imp_ne] \\
714          METIS_TAC [inv_not_infty]) \\
715      DISCH_THEN (rfs o wrap) \\
716      Know ‘1 + inv q < 1 + 0 <=> inv q < 0’
717      >- (MATCH_MP_TAC lt_ladd >> rw [extreal_of_num_def]) \\
718      PURE_REWRITE_TAC [add_rzero] \\
719      DISCH_THEN (fs o wrap) \\
720      METIS_TAC [let_antisym],
721      (* goal 2 (of 4) *)
722      Know ‘1 <= q <=> inv q <= inv 1’
723      >- (MATCH_MP_TAC (GSYM inv_le_antimono) >> art [lt_01]) >> Rewr' \\
724      rw [inv_one] \\
725      SPOSE_NOT_THEN (ASSUME_TAC o (REWRITE_RULE [GSYM extreal_lt_def])) \\
726      Know ‘1 < inv q <=> inv p + 1 < inv p + inv q’
727      >- (ONCE_REWRITE_TAC [EQ_SYM_EQ] \\
728          MATCH_MP_TAC lt_ladd \\
729         ‘p <> 0’ by PROVE_TAC [lt_imp_ne] \\
730          METIS_TAC [inv_not_infty]) \\
731      DISCH_THEN (rfs o wrap) \\
732      Know ‘inv p + 1 < 0 + 1 <=> inv p < 0’
733      >- (MATCH_MP_TAC lt_radd >> rw [extreal_of_num_def]) \\
734      PURE_REWRITE_TAC [add_lzero] \\
735      DISCH_THEN (fs o wrap) \\
736      METIS_TAC [let_antisym],
737      (* goal 3 (of 4) *)
738      reverse EQ_TAC >- (DISCH_THEN (fn th => fs [inv_infty, th]) \\
739                         Suff ‘inv p = inv 1’ >- PROVE_TAC [inv_inj, lt_01] \\
740                         rw [inv_one]) \\
741      DISCH_THEN (fn th => fs [inv_one, th]) \\
742     ‘q <> 0’ by PROVE_TAC [lt_imp_ne] \\
743      Cases_on ‘q’ \\
744      fs [lt_infty, extreal_of_num_def, extreal_lt_eq, extreal_le_eq, extreal_inv_def,
745          extreal_add_def] \\
746      METIS_TAC [REAL_ADD_RID_UNIQ, REAL_INV_POS, REAL_LT_IMP_NE],
747      (* goal 4 (of 4) *)
748      reverse EQ_TAC >- (DISCH_THEN (fn th => fs [inv_infty, th]) \\
749                         Suff ‘inv q = inv 1’ >- PROVE_TAC [inv_inj, lt_01] \\
750                         rw [inv_one]) \\
751      DISCH_THEN (fn th => fs [inv_one, th]) \\
752     ‘p <> 0’ by PROVE_TAC [lt_imp_ne] \\
753      Cases_on ‘p’ \\
754      fs [lt_infty, extreal_of_num_def, extreal_lt_eq, extreal_le_eq, extreal_inv_def,
755          extreal_add_def] \\
756      METIS_TAC [REAL_ADD_LID_UNIQ, REAL_INV_POS, REAL_LT_IMP_NE] ]
757QED
758
759Definition ext_mono_increasing_def :
760    ext_mono_increasing f = (!m n:num. m <= n ==> f m <= f n)
761End
762
763Theorem ext_mono_increasing_suc:   !f. ext_mono_increasing f <=> !n. f n <= f (SUC n)
764Proof
765    RW_TAC std_ss [ext_mono_increasing_def]
766 >> EQ_TAC >> RW_TAC real_ss []
767 >> Know `?d. n = m + d` >- PROVE_TAC [LESS_EQ_EXISTS]
768 >> RW_TAC std_ss []
769 >> Induct_on `d` >- RW_TAC std_ss [add_rzero, le_refl]
770 >> RW_TAC std_ss []
771 >> Q.PAT_X_ASSUM `!n. f n <= f (SUC n)` (MP_TAC o Q.SPEC `m + d`)
772 >> METIS_TAC [le_trans, ADD_CLAUSES, LESS_EQ_ADD]
773QED
774
775Definition ext_mono_decreasing_def :
776    ext_mono_decreasing f = (!m n:num. m <= n ==> f n <= f m)
777End
778
779Theorem ext_mono_decreasing_suc:   !f. ext_mono_decreasing f <=> !n. f (SUC n) <= f n
780Proof
781    RW_TAC std_ss [ext_mono_decreasing_def]
782 >> EQ_TAC >> RW_TAC real_ss []
783 >> Know `?d. n = m + d` >- PROVE_TAC [LESS_EQ_EXISTS]
784 >> RW_TAC std_ss []
785 >> Induct_on `d` >- RW_TAC std_ss [add_rzero,le_refl]
786 >> RW_TAC std_ss []
787 >> Q.PAT_X_ASSUM `!n. f (SUC n) <= f n` (MP_TAC o Q.SPEC `m + d`)
788 >> METIS_TAC [le_trans, ADD_CLAUSES, LESS_EQ_ADD]
789QED
790
791Overload mono_increasing = “ext_mono_increasing”
792Overload mono_decreasing = “ext_mono_decreasing”
793
794Theorem mono_increasing_imp_ext :
795    !f. mono_increasing f ==> mono_increasing (Normal o f)
796Proof
797    RW_TAC std_ss [extreal_le_eq, mono_increasing_def, ext_mono_increasing_def]
798QED
799
800Theorem mono_decreasing_imp_ext :
801    !f. mono_decreasing f ==> mono_decreasing (Normal o f)
802Proof
803    RW_TAC std_ss [extreal_le_eq, mono_decreasing_def, ext_mono_decreasing_def]
804QED
805
806Theorem EXTREAL_ARCH_POW2 : (* was: EXTREAL_ARCH_POW *)
807    !x. x <> PosInf ==> ?n. x < 2 pow n
808Proof
809    Cases
810 >> RW_TAC std_ss [lt_infty, extreal_lt_eq, REAL_ARCH_POW2, extreal_pow_def,
811                   extreal_of_num_def]
812QED
813
814Theorem EXTREAL_ARCH_POW2_INV : (* was: EXTREAL_ARCH_POW_INV *)
815    !e. 0 < e ==> ?n. Normal ((1 / 2) pow n) < e
816Proof
817    Cases >- RW_TAC std_ss [lt_infty]
818 >- METIS_TAC [lt_infty,extreal_not_infty]
819 >> RW_TAC std_ss [extreal_of_num_def,extreal_lt_eq]
820 >> MP_TAC (Q.SPEC `1 / 2` SEQ_POWER)
821 >> RW_TAC std_ss [abs, REAL_HALF_BETWEEN, REAL_LT_IMP_LE, SEQ]
822 >> POP_ASSUM (MP_TAC o Q.SPEC `r`)
823 >> RW_TAC std_ss [REAL_SUB_RZERO, REAL_POW_LT,
824                   REAL_HALF_BETWEEN,REAL_LT_IMP_LE,GREATER_EQ]
825 >> PROVE_TAC [LESS_EQ_REFL]
826QED
827
828Theorem le_epsilon :
829    !x y. (!e. 0 < e /\ e <> PosInf ==> x <= y + e) ==> x <= y
830Proof
831    NTAC 2 Cases
832 >> RW_TAC std_ss [le_infty]
833 >| [ (* goal 1 *)
834      Q.EXISTS_TAC `1` \\
835      RW_TAC std_ss [lt_01, extreal_of_num_def, extreal_not_infty, extreal_add_def],
836      (* goal 2 *)
837      Q.EXISTS_TAC `1` \\
838      RW_TAC std_ss [lt_01, extreal_of_num_def, extreal_not_infty, extreal_add_def],
839      (* goal 3 *)
840      Q.EXISTS_TAC `1` \\
841      RW_TAC std_ss [lt_01, extreal_of_num_def, extreal_not_infty, extreal_add_def,
842                     extreal_le_def],
843      (* goal 4 *)
844     `!e. 0 < e ==> Normal r <= Normal r' + Normal e`
845         by (RW_TAC std_ss [] \\
846             Q.PAT_X_ASSUM `!e. P e` MATCH_MP_TAC \\
847             METIS_TAC [extreal_not_infty, extreal_of_num_def, extreal_lt_eq]) \\
848     `!e. 0 < e ==> Normal r <= Normal (r' + e)`
849         by (RW_TAC real_ss [extreal_le_def, REAL_LT_IMP_LE, REAL_LE_ADD] \\
850            `Normal r <= Normal r' + Normal e` by METIS_TAC [REAL_LT_IMP_LE] \\
851            `Normal r' + Normal e = Normal (r' + e)`
852                  by METIS_TAC [extreal_add_def, REAL_LT_IMP_LE] \\
853             FULL_SIMP_TAC std_ss [] \\
854             METIS_TAC [REAL_LE_ADD, extreal_le_def, REAL_LT_IMP_LE]) \\
855     `!e. 0 < e ==> r <= r' + e`
856       by METIS_TAC [extreal_le_def, REAL_LT_IMP_LE, REAL_LE_ADD, extreal_add_def,
857                     REAL_LE_ADD] \\
858     `!e. 0 < e ==>  r <= r' + e` by METIS_TAC [extreal_le_def] \\
859      METIS_TAC [REAL_LE_EPSILON, extreal_le_def] ]
860QED
861
862Theorem le_mul_epsilon:
863    !x y:extreal. (!z. 0 <= z /\ z < 1 ==> z * x <= y) ==> x <= y
864Proof
865    ASSUME_TAC half_between
866 >> `1 / 2 <> 0` by METIS_TAC [lt_imp_ne]
867 >> rpt Cases >> RW_TAC std_ss [le_infty]
868 >| [ (* goal 1 (of 4) *)
869      Q.EXISTS_TAC `1 / 2` \\
870      RW_TAC real_ss [extreal_mul_def, extreal_of_num_def, extreal_div_eq, extreal_cases],
871      (* goal 2 (of 4) *)
872      Q.EXISTS_TAC `1 / 2` \\
873      RW_TAC real_ss [extreal_mul_def, extreal_of_num_def, extreal_div_eq, extreal_cases,
874                      le_infty, extreal_not_infty],
875      (* goal 3 (of 4) *)
876      Q.EXISTS_TAC `1 / 2` \\
877      RW_TAC real_ss [extreal_mul_def, extreal_of_num_def, extreal_div_eq, extreal_cases,
878                      le_infty, extreal_not_infty],
879      (* goal 4 (of 4) *)
880     `!z. 0 <= z /\ z < 1 <=> ?z1. 0 <= z1 /\ z1 < 1 /\ (z = Normal z1)`
881         by (RW_TAC std_ss [] \\
882             EQ_TAC
883             >- (RW_TAC std_ss [] \\
884                 Cases_on `z` >|
885                 [ METIS_TAC [extreal_of_num_def, le_infty, extreal_not_infty],
886                   METIS_TAC [extreal_of_num_def, lt_infty, extreal_not_infty],
887                   METIS_TAC [extreal_le_def, extreal_lt_eq, extreal_of_num_def] ]) \\
888             METIS_TAC [extreal_lt_eq, extreal_le_def, extreal_of_num_def]) \\
889      RW_TAC std_ss [] \\
890     `!z1. 0 <= z1 /\ z1 < 1 ==> Normal (z1) * Normal r <= Normal r'`
891         by METIS_TAC [extreal_lt_eq, extreal_le_def, extreal_of_num_def] \\
892     `!z1. 0 <= z1 /\ z1 < 1 ==> Normal (z1 * r) <= Normal r'`
893         by METIS_TAC [extreal_mul_def] \\
894      Suff `r <= r'` >- METIS_TAC [extreal_le_def] \\
895      MATCH_MP_TAC REAL_LE_MUL_EPSILON \\
896      METIS_TAC [extreal_le_def, REAL_LT_LE] ]
897QED
898
899(***************************************************)
900(*   SUM over Finite Set (reworked by Chun Tian)   *)
901(***************************************************)
902
903(* Some lemmas about ITSET, (\e acc. f e + acc) and b:extreal *)
904
905val absorption =         #1 (EQ_IMP_RULE (SPEC_ALL ABSORPTION));
906val delete_non_element = #1 (EQ_IMP_RULE (SPEC_ALL DELETE_NON_ELEMENT));
907
908local
909val tactics =
910   GEN_TAC >> DISCH_TAC >> rpt GEN_TAC >> DISCH_TAC
911 >> completeInduct_on `CARD s`
912 >> POP_ASSUM (ASSUME_TAC o (SIMP_RULE bool_ss [GSYM RIGHT_FORALL_IMP_THM, AND_IMP_INTRO]))
913 >> GEN_TAC >> SIMP_TAC bool_ss [ITSET_INSERT]
914 >> rpt STRIP_TAC
915 >> Q.ABBREV_TAC `t = REST (x INSERT s)`
916 >> Q.ABBREV_TAC `y = CHOICE (x INSERT s)`
917 >> `~(y IN t)` by PROVE_TAC [CHOICE_NOT_IN_REST]
918 >> Cases_on `x IN s` >| (* 2 sub-goals here *)
919  [ (* goal 1 (of 2) *)
920    FULL_SIMP_TAC bool_ss [absorption] \\
921    Cases_on `x = y` >| (* 2 sub-goals here *)
922    [ (* goal 1.1 (of 2), x = y, no extreal property used *)
923      POP_ASSUM SUBST_ALL_TAC \\ (* all `x` disappeared *)
924      Suff `t = s DELETE y` >- SRW_TAC [][] \\
925     `s = y INSERT t` by PROVE_TAC [NOT_IN_EMPTY, CHOICE_INSERT_REST] \\
926      SRW_TAC [][DELETE_INSERT, delete_non_element],
927      (* goal 1.2 (of 2), x <> y *)
928     `s = y INSERT t` by PROVE_TAC [NOT_IN_EMPTY, CHOICE_INSERT_REST] \\
929     `x IN t` by PROVE_TAC [IN_INSERT] \\
930      Q.ABBREV_TAC `u = t DELETE x` \\
931     `t = x INSERT u` by SRW_TAC [][INSERT_DELETE, Abbr`u`] \\
932     `~(x IN u)` by PROVE_TAC [IN_DELETE] \\
933     `s = x INSERT (y INSERT u)` by simp[INSERT_COMM] \\
934      POP_ASSUM SUBST_ALL_TAC \\ (* all `s` disappeared *)
935      FULL_SIMP_TAC bool_ss [FINITE_INSERT, CARD_INSERT, DELETE_INSERT,IN_INSERT] \\
936      (* now we start using properties of extreal *)
937     `f x + b <> li /\ f y + b <> li` by METIS_TAC [add_not_infty] \\
938      Q.PAT_X_ASSUM `!s' x' b'. (CARD s' < SUC (SUC (CARD u)) /\ FINITE s') /\ X ==> Y`
939        (ASSUME_TAC o (Q.SPEC `u`)) \\
940      FULL_SIMP_TAC arith_ss [] \\
941     `!z. (z = x) \/ z IN u ==> f z <> li` by METIS_TAC [] \\
942     `!z. (z = y) \/ z IN u ==> f z <> li` by METIS_TAC [] \\
943      rpt STRIP_TAC \\
944      Q.PAT_ASSUM `!x' b'. FINITE u /\ X ==> Y` (MP_TAC o (Q.SPECL [`x`, `f y + b`])) \\
945      Q.PAT_ASSUM `!x' b'. FINITE u /\ X ==> Y` (MP_TAC o (Q.SPECL [`y`, `f x + b`])) \\
946      Q.PAT_X_ASSUM `!x' b'. FINITE u /\ X ==> Y` K_TAC \\
947      rpt STRIP_TAC >> RES_TAC \\
948      ASM_SIMP_TAC std_ss [delete_non_element] \\
949      METIS_TAC [add_assoc, add_comm, add_not_infty] ],
950    (* goal 2 (of 2), ~(x IN s) *)
951    ASM_SIMP_TAC bool_ss [delete_non_element] \\
952   `x INSERT s = y INSERT t` by PROVE_TAC [NOT_EMPTY_INSERT, CHOICE_INSERT_REST] \\
953    Cases_on `x = y` >| (* 2 sub-goals here *)
954    [ (* goal 2.1 (of 2), no extreal property used *)
955      POP_ASSUM SUBST_ALL_TAC \\ (* all `x` disappeared *)
956      Suff `t = s` THEN1 SRW_TAC [][] \\
957      FULL_SIMP_TAC bool_ss [EXTENSION, IN_INSERT] >> PROVE_TAC [],
958      (* goal 2.2 (of 2), ~(x = y) *)
959     `x IN t /\ y IN s` by PROVE_TAC [IN_INSERT] \\
960      Q.ABBREV_TAC `u = s DELETE y` \\
961     `~(y IN u)` by PROVE_TAC [IN_DELETE] \\
962     `s = y INSERT u` by SRW_TAC [][INSERT_DELETE, Abbr`u`] \\
963      POP_ASSUM SUBST_ALL_TAC \\ (* all `s` disappeared *)
964      FULL_SIMP_TAC bool_ss [IN_INSERT, FINITE_INSERT, CARD_INSERT,
965                             DELETE_INSERT, delete_non_element] \\
966     `t = x INSERT u` by
967          (FULL_SIMP_TAC bool_ss [EXTENSION, IN_INSERT] THEN PROVE_TAC []) \\
968      ASM_REWRITE_TAC [] \\
969      (* now we start using properties of extreal *)
970     `f x + b <> li /\ f y + b <> li` by METIS_TAC [add_not_infty] \\
971      Q.PAT_X_ASSUM `!s x' b'. (CARD s < SUC (CARD u) /\ FINITE s') /\ X ==> Y`
972        (ASSUME_TAC o (Q.SPEC `u`)) \\
973      FULL_SIMP_TAC arith_ss [] \\
974     `!z. (z = x) \/ z IN u ==> f z <> li` by METIS_TAC [] \\
975     `!z. (z = y) \/ z IN u ==> f z <> li` by METIS_TAC [] \\
976      Q.PAT_ASSUM `!x' b'. FINITE u /\ X ==> Y` (MP_TAC o (Q.SPECL [`x`, `f y + b`])) \\
977      Q.PAT_ASSUM `!x' b'. FINITE u /\ X ==> Y` (MP_TAC o (Q.SPECL [`y`, `f x + b`])) \\
978      Q.PAT_X_ASSUM `!x' b'. FINITE u /\ X ==> Y` K_TAC \\
979      rpt STRIP_TAC >> RES_TAC \\
980      ASM_SIMP_TAC std_ss [delete_non_element] \\
981      METIS_TAC [add_assoc, add_comm, add_not_infty] ] ];
982
983Theorem lem[local]:
984  !li.
985     li = PosInf ==>
986     !f s. FINITE s ==>
987           !x b. (!z. z IN (x INSERT s) ==> f z <> li) /\ b <> li ==>
988                 ITSET (\e acc. f e + acc) (x INSERT s) b =
989                 ITSET (\e acc. f e + acc) (s DELETE x)
990                       ((\e acc. f e + acc) x b)
991Proof tactics
992QED
993
994val lem' = Q.prove (
995   `!li. (li = NegInf) ==>
996        !f s. FINITE s ==>
997              !x b. (!z. z IN (x INSERT s) ==> f z <> li) /\ b <> li ==>
998                    (ITSET (\e acc. f e + acc) (x INSERT s) b =
999                     ITSET (\e acc. f e + acc) (s DELETE x) ((\e acc. f e + acc) x b))`,
1000    tactics);
1001
1002in
1003  (* |- !f s.
1004         FINITE s ==>
1005         !x b.
1006             (!z. z IN x INSERT s ==> f z <> PosInf) /\ b <> PosInf ==>
1007             (ITSET (\e acc. f e + acc) (x INSERT s) b =
1008              ITSET (\e acc. f e + acc) (s DELETE x)
1009                ((\e acc. f e + acc) x b))
1010   *)
1011  val lemma1  = REWRITE_RULE [] (Q.SPEC `PosInf` lem);
1012
1013  (* |- !f s.
1014         FINITE s ==>
1015         !x b.
1016             (!z. z IN x INSERT s ==> f z <> NegInf) /\ b <> NegInf ==>
1017             (ITSET (\e acc. f e + acc) (x INSERT s) b =
1018              ITSET (\e acc. f e + acc) (s DELETE x)
1019                ((\e acc. f e + acc) x b))
1020   *)
1021  val lemma1' = REWRITE_RULE [] (Q.SPEC `NegInf` lem');
1022end;
1023
1024(* lemma2 is independent of lemma1 *)
1025local val tactics =
1026   (rpt GEN_TAC >> STRIP_TAC
1027 >> Induct_on `CARD s`
1028 >- METIS_TAC [CARD_EQ_0, ITSET_EMPTY]
1029 >> POP_ASSUM (ASSUME_TAC o
1030               (SIMP_RULE bool_ss [GSYM RIGHT_FORALL_IMP_THM, AND_IMP_INTRO]))
1031 >> RW_TAC std_ss []
1032 >> `0 < CARD s` by METIS_TAC [prim_recTheory.LESS_0]
1033 >> `CARD s <> 0` by RW_TAC real_ss [REAL_LT_NZ]
1034 >> `s <> {}` by METIS_TAC [CARD_EQ_0]
1035 >> `?x t. (s = x INSERT t) /\ x NOTIN t` by METIS_TAC [SET_CASES]
1036 >> FULL_SIMP_TAC std_ss [ITSET_INSERT, FINITE_INSERT]
1037 >> RW_TAC std_ss [REST_DEF]
1038 >> Q.ABBREV_TAC `y = CHOICE (x INSERT t)`
1039 >> Q.ABBREV_TAC `u = x INSERT t`
1040 >> `y IN u` by PROVE_TAC [CHOICE_DEF]
1041 >> `CARD (u DELETE y) = v` by METIS_TAC [CARD_DELETE, FINITE_INSERT, SUC_SUB1]
1042 >> METIS_TAC [add_not_infty, FINITE_INSERT, FINITE_DELETE, IN_DELETE])
1043in
1044  val lemma2  = Q.prove (
1045     `!f s. (!x. x IN s ==> f x <> PosInf) /\ FINITE s ==>
1046            !b. b <> PosInf ==> ITSET (\e acc. f e + acc) s b <> PosInf`, tactics);
1047
1048  val lemma2' = Q.prove (
1049     `!f s. (!x. x IN s ==> f x <> NegInf) /\ FINITE s ==>
1050            !b. b <> NegInf ==> ITSET (\e acc. f e + acc) s b <> NegInf`, tactics);
1051end;
1052
1053(** lemma3 depends on both lemma1 and lemma2 *)
1054Theorem lemma3[local]:
1055    !b f x s. (!y. y IN (x INSERT s) ==> f y <> PosInf) /\ b <> PosInf /\ FINITE s ==>
1056              (ITSET (\e acc. f e + acc) (x INSERT s) b =
1057               (\e acc. f e + acc) x (ITSET (\e acc. f e + acc) (s DELETE x) b))
1058Proof
1059  (* proof *)
1060    Suff `!f s. FINITE s ==>
1061                !x b. (!y. y IN (x INSERT s) ==> f y <> PosInf) /\ b <> PosInf ==>
1062                      (ITSET (\e acc. f e + acc) (x INSERT s) b =
1063                       (\e acc. f e + acc) x (ITSET (\e acc. f e + acc) (s DELETE x) b))`
1064 >- METIS_TAC []
1065 >> rpt STRIP_TAC
1066 >> IMP_RES_TAC lemma1 >> ASM_REWRITE_TAC []
1067 >> Suff `!s. FINITE s ==>
1068              !x b. (!y. y IN (x INSERT s) ==> f y <> PosInf) /\ b <> PosInf ==>
1069                   (ITSET (\e acc. f e + acc) s (f x + b) =
1070                    f x + (ITSET (\e acc. f e + acc) s b))`
1071 >- (rpt STRIP_TAC \\
1072     Q.ABBREV_TAC `t = s DELETE x` \\
1073     `FINITE t` by METIS_TAC [FINITE_DELETE] \\
1074     BETA_TAC \\
1075     Q.PAT_X_ASSUM `!s. FINITE s ==> X` (MP_TAC o Q.SPEC `t`) >> RW_TAC std_ss [] \\
1076     POP_ASSUM (MP_TAC o SPEC_ALL) >> RW_TAC std_ss [] \\
1077     Suff `!y. y IN (x INSERT t) ==> f y <> PosInf` >- PROVE_TAC [] \\
1078     GEN_TAC >> STRIP_TAC \\
1079     Q.UNABBREV_TAC `t` \\
1080     Cases_on `y = x` >- (POP_ASSUM SUBST_ALL_TAC >> PROVE_TAC [IN_INSERT]) \\
1081     FULL_SIMP_TAC std_ss [IN_INSERT] \\
1082     PROVE_TAC [DELETE_SUBSET, SUBSET_DEF])
1083 >> KILL_TAC (* remove all assumptions *)
1084 >> HO_MATCH_MP_TAC FINITE_INDUCT
1085 >> CONJ_TAC
1086 >- SIMP_TAC bool_ss [ITSET_THM, FINITE_EMPTY]
1087 >> rpt STRIP_TAC
1088 >> `f x + b <> PosInf` by PROVE_TAC [IN_INSERT, add_not_infty]
1089 >> `!z. z IN (e INSERT s) ==> f z <> PosInf` by PROVE_TAC [IN_INSERT]
1090 >> `!x. x IN s ==> f x <> PosInf` by PROVE_TAC [IN_INSERT]
1091 >> `!y. y IN (x INSERT s) ==> f y <> PosInf` by PROVE_TAC [IN_INSERT, INSERT_COMM]
1092 >> ASM_SIMP_TAC bool_ss [lemma1, delete_non_element]
1093 >> `ITSET (\e acc. f e + acc) s b <> PosInf` by METIS_TAC [lemma2]
1094 >> Q.ABBREV_TAC `t = ITSET (\e acc. f e + acc) s b`
1095 >> Q.PAT_X_ASSUM `!x b. b <> PosInf => X` K_TAC
1096 >> METIS_TAC [add_assoc, add_comm, IN_INSERT]
1097QED
1098
1099(** lemma3' depends on lemma1' and lemma2' (proof is the same as lemma3) *)
1100Theorem lemma3'[local]:
1101    !b f x s. (!y. y IN (x INSERT s) ==> f y <> NegInf) /\ b <> NegInf /\ FINITE s ==>
1102              (ITSET (\e acc. f e + acc) (x INSERT s) b =
1103               (\e acc. f e + acc) x (ITSET (\e acc. f e + acc) (s DELETE x) b))
1104Proof
1105 (* proof *)
1106    Suff `!f s. FINITE s ==>
1107                !x b. (!y. y IN (x INSERT s) ==> f y <> NegInf) /\ b <> NegInf ==>
1108                      (ITSET (\e acc. f e + acc) (x INSERT s) b =
1109                       (\e acc. f e + acc) x (ITSET (\e acc. f e + acc) (s DELETE x) b))`
1110 >- METIS_TAC []
1111 >> rpt STRIP_TAC
1112 >> IMP_RES_TAC lemma1' >> ASM_REWRITE_TAC []
1113 >> Suff `!s. FINITE s ==>
1114              !x b. (!y. y IN (x INSERT s) ==> f y <> NegInf) /\ b <> NegInf ==>
1115                   (ITSET (\e acc. f e + acc) s (f x + b) =
1116                    f x + (ITSET (\e acc. f e + acc) s b))`
1117 >- (rpt STRIP_TAC \\
1118     Q.ABBREV_TAC `t = s DELETE x` \\
1119     `FINITE t` by METIS_TAC [FINITE_DELETE] \\
1120     BETA_TAC \\
1121     Q.PAT_X_ASSUM `!s. FINITE s ==> X` (MP_TAC o Q.SPEC `t`) >> RW_TAC std_ss [] \\
1122     POP_ASSUM (MP_TAC o SPEC_ALL) >> RW_TAC std_ss [] \\
1123     Suff `!y. y IN (x INSERT t) ==> f y <> NegInf` >- PROVE_TAC [] \\
1124     GEN_TAC >> STRIP_TAC \\
1125     Q.UNABBREV_TAC `t` \\
1126     Cases_on `y = x` >- (POP_ASSUM SUBST_ALL_TAC >> PROVE_TAC [IN_INSERT]) \\
1127     FULL_SIMP_TAC std_ss [IN_INSERT] \\
1128     PROVE_TAC [DELETE_SUBSET, SUBSET_DEF])
1129 >> KILL_TAC (* remove all assumptions *)
1130 >> HO_MATCH_MP_TAC FINITE_INDUCT
1131 >> CONJ_TAC
1132 >- SIMP_TAC bool_ss [ITSET_THM, FINITE_EMPTY]
1133 >> rpt STRIP_TAC
1134 >> `f x + b <> NegInf` by PROVE_TAC [IN_INSERT, add_not_infty]
1135 >> `!z. z IN (e INSERT s) ==> f z <> NegInf` by PROVE_TAC [IN_INSERT]
1136 >> `!x. x IN s ==> f x <> NegInf` by PROVE_TAC [IN_INSERT]
1137 >> `!y. y IN (x INSERT s) ==> f y <> NegInf` by PROVE_TAC [IN_INSERT, INSERT_COMM]
1138 >> ASM_SIMP_TAC bool_ss [lemma1', delete_non_element]
1139 >> `ITSET (\e acc. f e + acc) s b <> NegInf` by METIS_TAC [lemma2']
1140 >> Q.ABBREV_TAC `t = ITSET (\e acc. f e + acc) s b`
1141 >> Q.PAT_X_ASSUM `!x b. b <> NegInf => X` K_TAC
1142 >> METIS_TAC [add_assoc, add_comm, IN_INSERT]
1143QED
1144
1145(* NOTE: EXTREAL_SUM_IMAGE is not defined if there're mixing of PosInfs and NegInfs
1146   in the summation, since ``PosInf + NegInf`` is not defined. *)
1147
1148Definition EXTREAL_SUM_IMAGE_DEF[nocompute]:
1149  EXTREAL_SUM_IMAGE f s = ITSET (\e acc. f e + acc) s (0 :extreal)
1150End
1151
1152(* Now theorems about EXTREAL_SUM_IMAGE itself *)
1153Theorem EXTREAL_SUM_IMAGE_EMPTY[simp] :
1154    !f. EXTREAL_SUM_IMAGE f {} = 0
1155Proof
1156    SRW_TAC [][ITSET_THM, EXTREAL_SUM_IMAGE_DEF]
1157QED
1158
1159(* This is provable by (old) EXTREAL_SUM_IMAGE_THM but using original definition is much
1160   easier, because CHOICE and REST from singleton can be easily eliminated.
1161 *)
1162Theorem EXTREAL_SUM_IMAGE_SING[simp] :
1163    !f e. EXTREAL_SUM_IMAGE f {e} = f e
1164Proof
1165    SRW_TAC [][EXTREAL_SUM_IMAGE_DEF, ITSET_THM, add_rzero]
1166QED
1167
1168(* This new theorem provides a "complete" picture for EXTREAL_SUM_IMAGE. *)
1169Theorem EXTREAL_SUM_IMAGE_THM:
1170    !f. (EXTREAL_SUM_IMAGE f {} = 0) /\
1171        (!e. EXTREAL_SUM_IMAGE f {e} = f e) /\
1172        (!e s. FINITE s /\ ((!x. x IN (e INSERT s) ==> f x <> PosInf) \/
1173                            (!x. x IN (e INSERT s) ==> f x <> NegInf)) ==>
1174              (EXTREAL_SUM_IMAGE f (e INSERT s) =
1175               f e + EXTREAL_SUM_IMAGE f (s DELETE e)))
1176Proof
1177  let val thm  = SIMP_RULE std_ss [num_not_infty] (Q.SPEC `0` lemma3);
1178      val thm' = SIMP_RULE std_ss [num_not_infty] (Q.SPEC `0` lemma3');
1179  in
1180    rpt STRIP_TAC >- REWRITE_TAC [EXTREAL_SUM_IMAGE_EMPTY]
1181                  >- REWRITE_TAC [EXTREAL_SUM_IMAGE_SING]
1182    >> SIMP_TAC (srw_ss()) [EXTREAL_SUM_IMAGE_DEF]
1183    >| [ METIS_TAC [thm], METIS_TAC [thm'] ]
1184  end
1185QED
1186
1187(* A weaker but practical version in which all values from function f is restricted *)
1188Theorem EXTREAL_SUM_IMAGE_INSERT:
1189    !f. (!x. f x <> PosInf) \/ (!x. f x <> NegInf) ==>
1190        !e s. FINITE s ==>
1191              (EXTREAL_SUM_IMAGE f (e INSERT s) =
1192               f e + EXTREAL_SUM_IMAGE f (s DELETE e))
1193Proof
1194    PROVE_TAC [EXTREAL_SUM_IMAGE_THM]
1195QED
1196
1197(* |- (!x. x IN s ==> f x <> NegInf) /\ FINITE s ==>
1198      ITSET (\e acc. f e + acc) s 0 <> NegInf
1199 *)
1200Theorem EXTREAL_SUM_IMAGE_NOT_NEGINF_lemma[local] = lemma2'
1201     |> SIMP_RULE bool_ss [GSYM RIGHT_FORALL_IMP_THM, AND_IMP_INTRO]
1202     |> Q.SPECL [`f`, `s`, `0`]
1203     |> SIMP_RULE std_ss [num_not_infty]
1204
1205Theorem EXTREAL_SUM_IMAGE_NOT_NEGINF:
1206    !f s. FINITE s /\ (!x. x IN s ==> f x <> NegInf) ==>
1207          EXTREAL_SUM_IMAGE f s <> NegInf
1208Proof
1209    rpt GEN_TAC >> STRIP_TAC
1210 >> REWRITE_TAC [EXTREAL_SUM_IMAGE_DEF]
1211 >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_NOT_NEGINF_lemma >> art []
1212QED
1213
1214(* |- (!x. x IN s ==> f x <> PosInf) /\ FINITE s ==>
1215      ITSET (\e acc. f e + acc) s 0 <> PosInf
1216 *)
1217Theorem EXTREAL_SUM_IMAGE_NOT_POSINF_lemma[local] = lemma2
1218     |> SIMP_RULE bool_ss [GSYM RIGHT_FORALL_IMP_THM, AND_IMP_INTRO]
1219     |> Q.SPECL [`f`, `s`, `0`]
1220     |> SIMP_RULE std_ss [num_not_infty]
1221
1222Theorem EXTREAL_SUM_IMAGE_NOT_POSINF:
1223    !f s. FINITE s /\ (!x. x IN s ==> f x <> PosInf) ==>
1224          EXTREAL_SUM_IMAGE f s <> PosInf
1225Proof
1226    rpt GEN_TAC >> STRIP_TAC
1227 >> REWRITE_TAC [EXTREAL_SUM_IMAGE_DEF]
1228 >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_NOT_POSINF_lemma >> art []
1229QED
1230
1231Theorem EXTREAL_SUM_IMAGE_NOT_INFTY:
1232    !f s. (FINITE s /\ (!x. x IN s ==> f x <> NegInf) ==>
1233           EXTREAL_SUM_IMAGE f s <> NegInf) /\
1234          (FINITE s /\ (!x. x IN s ==> f x <> PosInf) ==>
1235           EXTREAL_SUM_IMAGE f s <> PosInf)
1236Proof
1237    RW_TAC std_ss [EXTREAL_SUM_IMAGE_NOT_NEGINF, EXTREAL_SUM_IMAGE_NOT_POSINF]
1238QED
1239
1240Theorem EXTREAL_SUM_IMAGE_PROPERTY_NEG:
1241    !f s. FINITE s ==>
1242          !e. (!x. x IN e INSERT s ==> f x <> NegInf) ==>
1243              (EXTREAL_SUM_IMAGE f (e INSERT s) =
1244               f e + EXTREAL_SUM_IMAGE f (s DELETE e))
1245Proof
1246  RW_TAC std_ss [EXTREAL_SUM_IMAGE_THM]
1247QED
1248
1249Theorem EXTREAL_SUM_IMAGE_PROPERTY_POS:
1250    !f s. FINITE s ==>
1251          !e. (!x. x IN e INSERT s ==> f x <> PosInf) ==>
1252              (EXTREAL_SUM_IMAGE f (e INSERT s) =
1253               f e + EXTREAL_SUM_IMAGE f (s DELETE e))
1254Proof
1255  RW_TAC std_ss [EXTREAL_SUM_IMAGE_THM]
1256QED
1257
1258Theorem EXTREAL_SUM_IMAGE_PROPERTY:
1259    !f s. FINITE s  ==>
1260          !e. (!x. x IN e INSERT s ==> f x <> NegInf) \/
1261              (!x. x IN e INSERT s ==> f x <> PosInf) ==>
1262              (EXTREAL_SUM_IMAGE f (e INSERT s) =
1263               f e + EXTREAL_SUM_IMAGE f (s DELETE e))
1264Proof
1265    PROVE_TAC [EXTREAL_SUM_IMAGE_PROPERTY_NEG, EXTREAL_SUM_IMAGE_PROPERTY_POS]
1266QED
1267
1268Theorem EXTREAL_SUM_IMAGE_POS:
1269     !f s. FINITE s /\ (!x. x IN s ==> 0 <= f x) ==>
1270           0 <= EXTREAL_SUM_IMAGE f s
1271Proof
1272  Suff `!s. FINITE s ==> (\s. !f. (!x. x IN s ==> 0 <= f x) ==>
1273            0 <= EXTREAL_SUM_IMAGE f s) s`
1274  >- RW_TAC std_ss []
1275  >> MATCH_MP_TAC FINITE_INDUCT
1276  >> RW_TAC real_ss [EXTREAL_SUM_IMAGE_EMPTY,le_refl]
1277  >> `!x. x IN e INSERT s ==> f x <> NegInf`
1278        by METIS_TAC [lt_infty,extreal_of_num_def,extreal_not_infty,lte_trans]
1279  >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY,delete_non_element]
1280  >> METIS_TAC [le_add,IN_INSERT]
1281QED
1282
1283Theorem EXTREAL_SUM_IMAGE_NEG:
1284    !f s. FINITE s /\ (!x. x IN s ==> f x <= 0) ==> EXTREAL_SUM_IMAGE f s <= 0
1285Proof
1286    Suff `!s. FINITE s ==>
1287              (\s. !f. (!x. x IN s ==> f x <= 0) ==>
1288                   EXTREAL_SUM_IMAGE f s <= 0) s`
1289 >- RW_TAC std_ss []
1290 >> MATCH_MP_TAC FINITE_INDUCT
1291 >> RW_TAC real_ss [EXTREAL_SUM_IMAGE_EMPTY, le_refl]
1292 >> `!x. x IN e INSERT s ==> f x <> PosInf`
1293        by METIS_TAC [lt_infty, extreal_of_num_def, extreal_not_infty, let_trans]
1294 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY, delete_non_element]
1295 >> METIS_TAC [le_add_neg, IN_INSERT]
1296QED
1297
1298Theorem EXTREAL_SUM_IMAGE_SPOS:
1299    !f s. FINITE s /\ (~(s = {})) /\ (!x. x IN s ==> 0 < f x) ==>
1300          0 < EXTREAL_SUM_IMAGE f s
1301Proof
1302    Suff `!s. FINITE s ==> (\s. !f. s <> {} /\ (!x. x IN s ==> 0 < f x) ==>
1303                                    0 < EXTREAL_SUM_IMAGE f s) s`
1304 >- RW_TAC std_ss []
1305 >> MATCH_MP_TAC FINITE_INDUCT
1306 >> RW_TAC std_ss []
1307 >> `!x. x IN e INSERT s ==> f x <> NegInf`
1308        by METIS_TAC [IN_INSERT, lt_infty, lt_trans, lt_imp_le, extreal_of_num_def]
1309 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY, delete_non_element]
1310 >> Cases_on `s = {}`
1311 >- METIS_TAC [EXTREAL_SUM_IMAGE_EMPTY, add_rzero, IN_INSERT]
1312 >> METIS_TAC [lt_add, IN_INSERT]
1313QED
1314
1315Theorem EXTREAL_SUM_IMAGE_SNEG:
1316    !f s. FINITE s /\ (~(s = {})) /\ (!x. x IN s ==> f x < 0) ==>
1317          EXTREAL_SUM_IMAGE f s < 0
1318Proof
1319    Suff `!s. FINITE s ==> (\s. !f. s <> {} /\ (!x. x IN s ==> f x < 0) ==>
1320                                    EXTREAL_SUM_IMAGE f s < 0) s`
1321 >- RW_TAC std_ss []
1322 >> MATCH_MP_TAC FINITE_INDUCT
1323 >> RW_TAC std_ss []
1324 >> `!x. x IN e INSERT s ==> f x <> PosInf`
1325        by METIS_TAC [IN_INSERT, lt_infty, lt_trans, lt_imp_le, extreal_of_num_def]
1326 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY, delete_non_element]
1327 >> Cases_on `s = {}`
1328 >- METIS_TAC [EXTREAL_SUM_IMAGE_EMPTY, add_rzero, IN_INSERT]
1329 >> METIS_TAC [lt_add_neg, IN_INSERT]
1330QED
1331
1332Theorem EXTREAL_SUM_IMAGE_IF_ELIM:
1333    !s P f. FINITE s /\ (!x. x IN s ==> P x) /\
1334            ((!x. x IN s ==> f x <> NegInf) \/ !x. x IN s ==> f x <> PosInf)
1335        ==> (EXTREAL_SUM_IMAGE (\x. if P x then f x else 0) s = EXTREAL_SUM_IMAGE f s)
1336Proof
1337    Suff `!s. FINITE s ==>
1338             (\s. !P f. (!x. x IN s ==> P x) /\
1339                        ((!x. x IN s ==> f x <> NegInf) \/
1340                          !x. x IN s ==> f x <> PosInf) ==>
1341                        (EXTREAL_SUM_IMAGE (\x. if P x then f x else 0) s =
1342                         EXTREAL_SUM_IMAGE f s)) s`
1343 >- METIS_TAC []
1344 >> MATCH_MP_TAC FINITE_INDUCT
1345 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_EMPTY]
1346 >- (`!x. x IN e INSERT s ==> (\x. if P x then f x else 0) x <> NegInf`
1347        by METIS_TAC [extreal_of_num_def, lt_infty, lt_imp_ne] \\
1348     RW_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY] \\
1349     METIS_TAC [IN_INSERT, DELETE_NON_ELEMENT, lt_infty] )
1350 >> `!x. x IN (e INSERT s) ==> ((\x. if P x then f x else 0) x <> PosInf)`
1351        by METIS_TAC[extreal_of_num_def,lt_infty,lt_imp_ne]
1352 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY]
1353 >- METIS_TAC [IN_INSERT, DELETE_NON_ELEMENT]
1354 >> METIS_TAC [IN_INSERT]
1355QED
1356
1357Theorem EXTREAL_SUM_IMAGE_FINITE_SAME :
1358    !s. FINITE s ==> !f p. p IN s /\ (!q. q IN s ==> (f p = f q)) ==>
1359                          (EXTREAL_SUM_IMAGE f s = (&(CARD s)) * f p)
1360Proof
1361    Suff `!s. FINITE s ==>
1362             (\s. !f p. p IN s /\ (!q. q IN s ==> (f p = f q))
1363              ==> (EXTREAL_SUM_IMAGE f s = (&(CARD s)) * f p)) s`
1364 >- METIS_TAC []
1365 >> MATCH_MP_TAC FINITE_INDUCT
1366 >> RW_TAC real_ss [EXTREAL_SUM_IMAGE_EMPTY, CARD_EMPTY, mul_lzero, DELETE_NON_ELEMENT]
1367 >> Know ‘(!x. x IN e INSERT s ==> f x <> NegInf) \/
1368          (!x. x IN e INSERT s ==> f x <> PosInf)’
1369 >- (Cases_on ‘f p = NegInf’
1370     >- (DISJ2_TAC >> GEN_TAC >> STRIP_TAC \\
1371        ‘f x = NegInf’ by METIS_TAC [IN_INSERT] >> POP_ORW \\
1372         rw []) \\
1373     DISJ1_TAC >> GEN_TAC >> STRIP_TAC \\
1374     METIS_TAC [IN_INSERT])
1375 >> DISCH_THEN (ONCE_REWRITE_TAC o wrap o
1376      (MATCH_MP (MATCH_MP EXTREAL_SUM_IMAGE_PROPERTY (ASSUME “FINITE s”))))
1377 >> RW_TAC real_ss [DELETE_NON_ELEMENT]
1378 >> `f p = f e` by FULL_SIMP_TAC std_ss [IN_INSERT]
1379 >> FULL_SIMP_TAC std_ss [GSYM DELETE_NON_ELEMENT]
1380 >> RW_TAC std_ss [CARD_INSERT, ADD1, extreal_of_num_def, GSYM REAL_ADD, GSYM extreal_add_def]
1381 >> RW_TAC std_ss [Once add_comm_normal, GSYM extreal_of_num_def]
1382 >> `(&CARD s) <> NegInf /\ 1 <> NegInf /\ (&CARD s) <> PosInf /\
1383     1 <> PosInf /\ 0 <= (&CARD s) /\ 0 <= 1`
1384       by METIS_TAC [extreal_not_infty, extreal_of_num_def, le_num, le_01]
1385 >> RW_TAC std_ss [add_rdistrib, mul_lone]
1386 >> Suff `EXTREAL_SUM_IMAGE f s = &(CARD s) * f e` >- Rewr
1387 >> (MP_TAC o Q.SPECL [`s`]) SET_CASES >> RW_TAC std_ss []
1388 >- RW_TAC real_ss [EXTREAL_SUM_IMAGE_EMPTY, CARD_EMPTY, mul_lzero]
1389 >> `f e = f x` by FULL_SIMP_TAC std_ss [IN_INSERT]
1390 >> FULL_SIMP_TAC std_ss [] >> POP_ASSUM (K ALL_TAC)
1391 >> Q.PAT_X_ASSUM `!f p. b` MATCH_MP_TAC >> METIS_TAC [IN_INSERT]
1392QED
1393
1394Theorem EXTREAL_SUM_IMAGE_FINITE_CONST : (* was: extreal_sum_image_finite_corr *)
1395    !P. FINITE P ==>
1396        !f x. (!y. y IN P ==> (f y = x)) ==> (EXTREAL_SUM_IMAGE f P = (&(CARD P)) * x)
1397Proof
1398    rw []
1399 >> Cases_on ‘P = {}’ >> simp []
1400 >> ‘?m. m IN P’ by metis_tac [MEMBER_NOT_EMPTY]
1401 >> ‘x = f m’ by fs [] >> rw []
1402 >> irule EXTREAL_SUM_IMAGE_FINITE_SAME >> rw []
1403QED
1404
1405Theorem EXTREAL_SUM_IMAGE_ZERO:   !s. FINITE s ==> (EXTREAL_SUM_IMAGE (\x. 0) s = 0)
1406Proof
1407    RW_TAC std_ss []
1408 >> Suff `EXTREAL_SUM_IMAGE (\x. 0) s = &CARD s * 0`
1409 >- METIS_TAC [mul_rzero]
1410 >> (MATCH_MP_TAC o UNDISCH o Q.SPEC `s`) EXTREAL_SUM_IMAGE_FINITE_CONST
1411 >> RW_TAC std_ss [num_not_infty]
1412QED
1413
1414Theorem EXTREAL_SUM_IMAGE_0:
1415    !f s. FINITE s /\ (!x. x IN s ==> (f x = 0)) ==> (EXTREAL_SUM_IMAGE f s = 0)
1416Proof
1417    Suff `!s. FINITE s ==>
1418             (\s. !f. (!x. x IN s ==> (f x = 0)) ==> (EXTREAL_SUM_IMAGE f s = 0)) s`
1419 >- METIS_TAC []
1420 >> MATCH_MP_TAC FINITE_INDUCT
1421 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_EMPTY, DELETE_NON_ELEMENT]
1422 >> `!x. x IN (e INSERT s) ==> f x <> PosInf` by PROVE_TAC [num_not_infty]
1423 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY]
1424 >> METIS_TAC [IN_INSERT, add_lzero]
1425QED
1426
1427(* more antecedents added *)
1428Theorem EXTREAL_SUM_IMAGE_IN_IF:
1429    !s. FINITE s ==>
1430        !f. ((!x. x IN s ==> f x <> NegInf) \/
1431             (!x. x IN s ==> f x <> PosInf)) ==>
1432            (EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE (\x. if x IN s then f x else 0) s)
1433Proof
1434    Suff `!s. FINITE s ==>
1435              (\s. !f. ((!x. x IN s ==> f x <> NegInf) \/ (!x. x IN s ==> f x <> PosInf)) ==>
1436                       (EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE (\x. if x IN s then f x else 0) s)) s`
1437 >- RW_TAC std_ss []
1438 >> MATCH_MP_TAC FINITE_INDUCT
1439 >> RW_TAC real_ss [EXTREAL_SUM_IMAGE_EMPTY]
1440 >- (`!x. (\x. if x IN e INSERT s then f x else 0) x <> NegInf`
1441         by RW_TAC std_ss [extreal_not_infty, extreal_of_num_def]
1442     >> FULL_SIMP_TAC real_ss [EXTREAL_SUM_IMAGE_PROPERTY]
1443     >> `s DELETE e = s` by rw[GSYM DELETE_NON_ELEMENT]
1444     >> `EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE (\x. if x IN s then f x else 0) s`
1445         by METIS_TAC [IN_INSERT]
1446     >> Q.PAT_X_ASSUM `!x:'a. x IN e INSERT s ==> f x <> NegInf` K_TAC
1447     >> FULL_SIMP_TAC real_ss [IN_INSERT])
1448 >> `!x. (\x. if x IN e INSERT s then f x else 0) x <> PosInf`
1449         by RW_TAC std_ss [extreal_not_infty, extreal_of_num_def]
1450 >> FULL_SIMP_TAC real_ss [EXTREAL_SUM_IMAGE_PROPERTY]
1451 >> `s DELETE e = s` by rw [GSYM DELETE_NON_ELEMENT]
1452 >> `EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE (\x. if x IN s then f x else 0) s`
1453         by METIS_TAC [IN_INSERT]
1454 >> Q.PAT_X_ASSUM `!x:'a. x IN e INSERT s ==> f x <> PosInf` K_TAC
1455 >> FULL_SIMP_TAC std_ss [IN_INSERT]
1456QED
1457
1458(* more antecedents added *)
1459Theorem EXTREAL_SUM_IMAGE_CMUL :
1460    !s. FINITE s ==>
1461        !f c. (!x. x IN s ==> f x <> NegInf) \/ (!x. x IN s ==> f x <> PosInf) ==>
1462              (EXTREAL_SUM_IMAGE (\x. Normal c * f x) s = Normal c * (EXTREAL_SUM_IMAGE f s))
1463Proof
1464    Suff `!f c s.
1465             FINITE s ==>
1466             (\s. (!x. x IN s ==> f x <> NegInf) \/ (!x. x IN s ==> f x <> PosInf) ==>
1467                  (EXTREAL_SUM_IMAGE (\x. Normal c * f x) s = Normal c * (EXTREAL_SUM_IMAGE f s))) s`
1468 >- METIS_TAC []
1469 >> STRIP_TAC >> STRIP_TAC >> MATCH_MP_TAC FINITE_INDUCT
1470 >> RW_TAC real_ss [EXTREAL_SUM_IMAGE_EMPTY,mul_rzero]
1471 >- ( Cases_on `0 <= c`
1472      >- (`!x. x IN e INSERT s ==> (\x. Normal c * f x) x <> NegInf` by METIS_TAC [mul_not_infty,IN_INSERT]
1473          >> FULL_SIMP_TAC real_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT]
1474          >> METIS_TAC [add_ldistrib_normal,EXTREAL_SUM_IMAGE_NOT_INFTY,IN_INSERT])
1475      >> `!x. x IN e INSERT s ==> (\x. Normal c * f x) x <> PosInf`
1476                by METIS_TAC [mul_not_infty,real_lt,REAL_LT_IMP_LE]
1477      >> FULL_SIMP_TAC real_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT]
1478      >> METIS_TAC [add_ldistrib_normal,EXTREAL_SUM_IMAGE_NOT_INFTY,IN_INSERT] )
1479 >> Cases_on `0 <= c`
1480 >- (`!x. x IN e INSERT s ==> (\x. Normal c * f x) x <> PosInf` by METIS_TAC [mul_not_infty] \\
1481     FULL_SIMP_TAC real_ss [EXTREAL_SUM_IMAGE_PROPERTY, DELETE_NON_ELEMENT] \\
1482     METIS_TAC [add_ldistrib_normal, EXTREAL_SUM_IMAGE_NOT_INFTY, IN_INSERT])
1483 >> `!x. x IN e INSERT s ==> (\x. Normal c * f x) x <> NegInf`
1484                by METIS_TAC [mul_not_infty, real_lt, REAL_LT_IMP_LE]
1485 >> FULL_SIMP_TAC real_ss [EXTREAL_SUM_IMAGE_PROPERTY, DELETE_NON_ELEMENT]
1486 >> METIS_TAC [add_ldistrib_normal, EXTREAL_SUM_IMAGE_NOT_INFTY, IN_INSERT]
1487QED
1488
1489Theorem EXTREAL_SUM_IMAGE_MINUS :
1490    !f s. FINITE s /\
1491         ((!x. x IN s ==> f x <> NegInf) \/ (!x. x IN s ==> f x <> PosInf)) ==>
1492          EXTREAL_SUM_IMAGE (\x. -f x) s = -EXTREAL_SUM_IMAGE f s
1493Proof
1494    rpt GEN_TAC >> DISCH_TAC
1495 >> simp [neg_minus1']
1496 >> irule EXTREAL_SUM_IMAGE_CMUL >> simp []
1497QED
1498
1499(* more antecedents added, cf. SUM_IMAGE_INJ_o *)
1500Theorem EXTREAL_SUM_IMAGE_IMAGE :
1501    !s. FINITE s ==>
1502        !f'. INJ f' s (IMAGE f' s) ==>
1503             !f. (!x. x IN (IMAGE f' s) ==> f x <> NegInf) \/
1504                 (!x. x IN (IMAGE f' s) ==> f x <> PosInf)
1505             ==> (EXTREAL_SUM_IMAGE f (IMAGE f' s) = EXTREAL_SUM_IMAGE (f o f') s)
1506Proof
1507     Suff `!s. FINITE s ==>
1508               (\s. !f'. INJ f' s (IMAGE f' s) ==>
1509                         !f. (!x. x IN (IMAGE f' s) ==> f x <> NegInf) \/
1510                             (!x. x IN (IMAGE f' s) ==> f x <> PosInf) ==>
1511                             (EXTREAL_SUM_IMAGE f (IMAGE f' s) =
1512                              EXTREAL_SUM_IMAGE (f o f') s)) s`
1513  >- METIS_TAC []
1514  >> MATCH_MP_TAC FINITE_INDUCT
1515  >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_EMPTY,IMAGE_EMPTY,IMAGE_INSERT,INJ_DEF]
1516  >- (`FINITE (IMAGE f' s)` by METIS_TAC [IMAGE_FINITE]
1517      >> `!x. x IN e INSERT s ==> (f o f') x <> NegInf` by METIS_TAC [o_DEF]
1518      >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY]
1519      >> `~ (f' e IN IMAGE f' s)`
1520        by (RW_TAC std_ss [IN_IMAGE] >> reverse (Cases_on `x IN s`)
1521            >- ASM_REWRITE_TAC [] >> METIS_TAC [IN_INSERT])
1522      >> `s DELETE e = s` by METIS_TAC [DELETE_NON_ELEMENT]
1523      >> `(IMAGE f' s) DELETE f' e = IMAGE f' s` by METIS_TAC [DELETE_NON_ELEMENT]
1524      >> ASM_REWRITE_TAC []
1525      >> `(!x. x IN s ==> f' x IN IMAGE f' s)` by METIS_TAC [IN_IMAGE]
1526      >> `(!x y. x IN s /\ y IN s ==> (f' x = f' y) ==> (x = y))` by METIS_TAC [IN_INSERT]
1527      >> `(!x. x IN IMAGE f' s ==> f x <> NegInf)` by METIS_TAC [IN_INSERT]
1528      >> FULL_SIMP_TAC std_ss [])
1529  >> `FINITE (IMAGE f' s)` by METIS_TAC [IMAGE_FINITE]
1530  >> `!x. x IN e INSERT s ==> (f o f') x <> PosInf` by METIS_TAC [o_DEF]
1531  >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY]
1532  >> `f' e NOTIN IMAGE f' s`
1533        by (RW_TAC std_ss [IN_IMAGE] >> reverse (Cases_on `x IN s`)
1534            >- ASM_REWRITE_TAC [] >> METIS_TAC [IN_INSERT])
1535  >> `s DELETE e = s` by METIS_TAC [DELETE_NON_ELEMENT]
1536  >> `(IMAGE f' s) DELETE f' e = IMAGE f' s` by METIS_TAC [DELETE_NON_ELEMENT]
1537  >> ASM_REWRITE_TAC []
1538  >> `(!x. x IN s ==> f' x IN IMAGE f' s)` by METIS_TAC [IN_IMAGE]
1539  >> `(!x y. x IN s /\ y IN s ==> (f' x = f' y) ==> (x = y))` by METIS_TAC [IN_INSERT]
1540  >> `(!x. x IN IMAGE f' s ==> f x <> PosInf)` by METIS_TAC [IN_INSERT]
1541  >> FULL_SIMP_TAC std_ss []
1542QED
1543
1544Theorem EXTREAL_SUM_IMAGE_PERMUTES :
1545    !s. FINITE s ==> !g. g PERMUTES s ==>
1546        !f. (!x. x IN (IMAGE g s) ==> f x <> NegInf) \/
1547            (!x. x IN (IMAGE g s) ==> f x <> PosInf) ==>
1548            (EXTREAL_SUM_IMAGE (f o g) s = EXTREAL_SUM_IMAGE f s)
1549Proof
1550    NTAC 5 STRIP_TAC >> DISCH_TAC
1551 >> `INJ g s s /\ SURJ g s s` by METIS_TAC [BIJ_DEF]
1552 >> `IMAGE g s = s` by SRW_TAC[][GSYM IMAGE_SURJ]
1553 >> `s SUBSET univ(:'a)` by SRW_TAC[][SUBSET_UNIV]
1554 >> `INJ g s univ(:'a)` by METIS_TAC[INJ_SUBSET, SUBSET_REFL]
1555 >> Know `EXTREAL_SUM_IMAGE (f o g) s = EXTREAL_SUM_IMAGE f (IMAGE g s)`
1556 >- (MATCH_MP_TAC EQ_SYM \\
1557     irule EXTREAL_SUM_IMAGE_IMAGE >> rw [])
1558 >> SRW_TAC[][]
1559QED
1560
1561Theorem EXTREAL_SUM_IMAGE_DISJOINT_UNION : (* more antecedents added *)
1562    !s s'. FINITE s /\ FINITE s' /\ DISJOINT s s' ==>
1563           !f. (!x. x IN s UNION s' ==> f x <> NegInf) \/
1564               (!x. x IN s UNION s' ==> f x <> PosInf) ==>
1565               (EXTREAL_SUM_IMAGE f (s UNION s') =
1566                EXTREAL_SUM_IMAGE f s + EXTREAL_SUM_IMAGE f s')
1567Proof
1568  Suff `!s. FINITE s ==> (\s. !s'. FINITE s' ==>
1569            (\s'. DISJOINT s s' ==>
1570                  (!f. (!x. x IN s UNION s' ==> f x <> NegInf) \/
1571                       (!x. x IN s UNION s' ==> f x <> PosInf) ==>
1572                       (EXTREAL_SUM_IMAGE f (s UNION s') =
1573                        EXTREAL_SUM_IMAGE f s +
1574                        EXTREAL_SUM_IMAGE f s'))) s') s`
1575  >- METIS_TAC []
1576  >> MATCH_MP_TAC FINITE_INDUCT
1577  >> CONJ_TAC
1578  >- RW_TAC std_ss [DISJOINT_EMPTY, UNION_EMPTY, EXTREAL_SUM_IMAGE_EMPTY,add_lzero]
1579  >> rpt STRIP_TAC
1580  >> CONV_TAC (BETA_CONV) >> MATCH_MP_TAC FINITE_INDUCT
1581  >> CONJ_TAC
1582  >- RW_TAC std_ss [DISJOINT_EMPTY, UNION_EMPTY, EXTREAL_SUM_IMAGE_EMPTY,add_rzero]
1583  >> FULL_SIMP_TAC std_ss [DISJOINT_INSERT]
1584  >> ONCE_REWRITE_TAC [DISJOINT_SYM]
1585  >> RW_TAC std_ss [INSERT_UNION, DISJOINT_INSERT, IN_INSERT]
1586  >- ( FULL_SIMP_TAC std_ss [DISJOINT_SYM]
1587       >> ONCE_REWRITE_TAC [UNION_COMM] >> RW_TAC std_ss [INSERT_UNION]
1588       >> ONCE_REWRITE_TAC [UNION_COMM] >> ONCE_REWRITE_TAC [INSERT_COMM]
1589       >> `FINITE (e INSERT s UNION s')` by RW_TAC std_ss [FINITE_INSERT, FINITE_UNION]
1590       >> Q.ABBREV_TAC `Q = e INSERT s UNION s'`
1591       >> `!x. x IN e INSERT s ==> f x <> NegInf` by METIS_TAC [IN_UNION,IN_INSERT]
1592       >> `!x. x IN e' INSERT s' ==> f x <> NegInf` by METIS_TAC [IN_UNION,IN_INSERT]
1593       >> `!x. x IN e' INSERT Q ==> f x <> NegInf` by METIS_TAC [IN_UNION,IN_INSERT]
1594       >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT]
1595       >> Q.UNABBREV_TAC `Q`
1596       >> `~ (e' IN (e INSERT s UNION s'))`
1597              by (RW_TAC std_ss[IN_INSERT, IN_UNION] \\
1598                FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT])
1599       >> `!x. x IN e INSERT (s UNION s') ==> f x <> NegInf` by METIS_TAC [IN_UNION,IN_INSERT]
1600       >> `~(e IN (s UNION s'))` by METIS_TAC [IN_UNION,DELETE_NON_ELEMENT]
1601       >> FULL_SIMP_TAC std_ss [DELETE_NON_ELEMENT,EXTREAL_SUM_IMAGE_PROPERTY,FINITE_UNION]
1602       >> `EXTREAL_SUM_IMAGE f s <> NegInf` by METIS_TAC [EXTREAL_SUM_IMAGE_NOT_INFTY,IN_UNION]
1603       >> `EXTREAL_SUM_IMAGE f s' <> NegInf` by METIS_TAC [EXTREAL_SUM_IMAGE_NOT_INFTY,IN_UNION,IN_INSERT]
1604       >> FULL_SIMP_TAC std_ss [IN_INSERT]
1605       >> RW_TAC std_ss [add_assoc]
1606       >> `f e' + (f e + EXTREAL_SUM_IMAGE f s + EXTREAL_SUM_IMAGE f s') =
1607          (f e + (EXTREAL_SUM_IMAGE f s + EXTREAL_SUM_IMAGE f s')) + f e'`
1608              by METIS_TAC [add_comm,add_not_infty,add_assoc,IN_INSERT]
1609       >> POP_ORW
1610       >> RW_TAC std_ss [add_assoc]
1611       >> METIS_TAC [add_not_infty,add_comm,add_assoc] )
1612  >> FULL_SIMP_TAC std_ss [DISJOINT_SYM]
1613  >> ONCE_REWRITE_TAC [UNION_COMM] >> RW_TAC std_ss [INSERT_UNION]
1614  >> ONCE_REWRITE_TAC [UNION_COMM] >> ONCE_REWRITE_TAC [INSERT_COMM]
1615  >> `FINITE (e INSERT s UNION s')` by RW_TAC std_ss [FINITE_INSERT, FINITE_UNION]
1616  >> Q.ABBREV_TAC `Q = e INSERT s UNION s'`
1617  >> `!x. x IN e INSERT s ==> f x <> PosInf` by METIS_TAC [IN_UNION,IN_INSERT]
1618  >> `!x. x IN e' INSERT s' ==> f x <> PosInf` by METIS_TAC [IN_UNION,IN_INSERT]
1619  >> `!x. x IN e' INSERT Q ==> f x <> PosInf` by METIS_TAC [IN_UNION,IN_INSERT]
1620  >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT]
1621  >> Q.UNABBREV_TAC `Q`
1622  >> `~ (e' IN (e INSERT s UNION s'))`
1623      by (RW_TAC std_ss [IN_INSERT, IN_UNION] \\
1624          FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT])
1625  >> `!x. x IN e INSERT (s UNION s') ==> f x <> PosInf` by METIS_TAC [IN_UNION,IN_INSERT]
1626  >> `~(e IN (s UNION s'))` by METIS_TAC [IN_UNION,DELETE_NON_ELEMENT]
1627  >> FULL_SIMP_TAC std_ss [DELETE_NON_ELEMENT,EXTREAL_SUM_IMAGE_PROPERTY,FINITE_UNION]
1628  >> `EXTREAL_SUM_IMAGE f s <> PosInf` by METIS_TAC [EXTREAL_SUM_IMAGE_NOT_INFTY,IN_UNION]
1629  >> `EXTREAL_SUM_IMAGE f s' <> PosInf` by METIS_TAC [EXTREAL_SUM_IMAGE_NOT_INFTY,IN_UNION,IN_INSERT]
1630  >> FULL_SIMP_TAC std_ss [IN_INSERT]
1631  >> RW_TAC std_ss [add_assoc]
1632  >> `f e' + (f e + EXTREAL_SUM_IMAGE f s + EXTREAL_SUM_IMAGE f s') =
1633       (f e + (EXTREAL_SUM_IMAGE f s + EXTREAL_SUM_IMAGE f s')) + f e'`
1634              by METIS_TAC [add_comm,add_not_infty,add_assoc,IN_INSERT]
1635  >> POP_ORW
1636  >> RW_TAC std_ss [add_assoc]
1637  >> METIS_TAC [add_not_infty, add_comm, add_assoc]
1638QED
1639
1640Theorem EXTREAL_SUM_IMAGE_EQ_CARD :
1641    !s. FINITE s ==>
1642       (EXTREAL_SUM_IMAGE (\x. if x IN s then 1 else 0) s = &(CARD s))
1643Proof
1644    Suff `!s. FINITE s ==>
1645             (\s. EXTREAL_SUM_IMAGE (\x. if x IN s then 1 else 0) s = (&(CARD s))) s`
1646 >- METIS_TAC []
1647 >> MATCH_MP_TAC FINITE_INDUCT
1648 >> RW_TAC real_ss [EXTREAL_SUM_IMAGE_EMPTY, CARD_EMPTY, IN_INSERT]
1649 >> `!x. (\x. if (x = e) \/ x IN s then 1 else 0) x <> NegInf`
1650      by RW_TAC real_ss [extreal_of_num_def,extreal_not_infty]
1651 >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY, DELETE_NON_ELEMENT]
1652 >> (MP_TAC o Q.SPECL [`s`]) CARD_INSERT
1653 >> `~(e IN s)` by METIS_TAC [DELETE_NON_ELEMENT]
1654 >> RW_TAC std_ss [ADD1,extreal_of_num_def, GSYM REAL_ADD, GSYM extreal_add_eq]
1655 >> RW_TAC std_ss [GSYM extreal_of_num_def]
1656 >> Suff `EXTREAL_SUM_IMAGE (\x. (if (x = e) \/ x IN s then 1 else 0)) s =
1657          EXTREAL_SUM_IMAGE (\x. (if x IN s then 1 else 0)) s`
1658 >- METIS_TAC [EXTREAL_SUM_IMAGE_NOT_INFTY, add_comm, extreal_not_infty,
1659               extreal_of_num_def]
1660 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_IN_IF]
1661QED
1662
1663Theorem EXTREAL_SUM_IMAGE_INV_CARD_EQ_1:
1664    !s. s <> {} /\ FINITE s ==>
1665        (EXTREAL_SUM_IMAGE (\x. if x IN s then inv (&(CARD s)) else 0) s = 1)
1666Proof
1667    rpt STRIP_TAC
1668 >> `(\x. if x IN s then inv (& (CARD s)) else 0) =
1669     (\x. inv (& (CARD s)) * (\x. if x IN s then 1 else 0) x)`
1670        by (RW_TAC std_ss [FUN_EQ_THM] >> RW_TAC real_ss [mul_rzero, mul_rone])
1671 >> POP_ORW
1672 >> `CARD s <> 0` by METIS_TAC [CARD_EQ_0]
1673 >> `inv (&CARD s) = Normal (inv (&CARD s))`
1674    by FULL_SIMP_TAC real_ss [extreal_inv_def, extreal_of_num_def]
1675 >> POP_ORW
1676 >> `!x. (\x. if x IN s then 1 else 0) x <> NegInf`
1677    by METIS_TAC [extreal_not_infty, extreal_of_num_def]
1678 >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_CMUL, EXTREAL_SUM_IMAGE_EQ_CARD]
1679 >> RW_TAC std_ss [extreal_of_num_def,extreal_mul_def]
1680 >> `&CARD s <> 0r` by FULL_SIMP_TAC real_ss [extreal_inv_def, extreal_of_num_def]
1681 >> METIS_TAC [REAL_MUL_LINV]
1682QED
1683
1684(* more antecedents added *)
1685Theorem EXTREAL_SUM_IMAGE_INTER_NONZERO:
1686    !s. FINITE s ==>
1687        !f. (!x. x IN s ==> f x <> NegInf) \/
1688            (!x. x IN s ==> f x <> PosInf) ==>
1689           (EXTREAL_SUM_IMAGE f (s INTER (\p. ~(f p = 0))) =
1690            EXTREAL_SUM_IMAGE f s)
1691Proof
1692 (* proof *)
1693    Suff `!s. FINITE s ==>
1694             (\s. !f. (!x. x IN s ==> f x <> NegInf) \/
1695                      (!x. x IN s ==> f x <> PosInf) ==>
1696                      (EXTREAL_SUM_IMAGE f (s INTER (\p. ~(f p = 0))) =
1697                       EXTREAL_SUM_IMAGE f s)) s`
1698 >- METIS_TAC []
1699 >> MATCH_MP_TAC FINITE_INDUCT
1700 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_EMPTY, INTER_EMPTY, INSERT_INTER]
1701 >- ( Cases_on `e IN (\p. f p <> 0)`
1702      >- (RW_TAC std_ss []
1703          >> `~(e IN (s INTER (\p. ~(f p = 0))))` by RW_TAC std_ss [IN_INTER]
1704          >> `!x. x IN (e INSERT s INTER (\p. f p <> 0)) ==> f x <> NegInf`
1705                by METIS_TAC [IN_INTER,IN_INSERT]
1706          >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY, DELETE_NON_ELEMENT,INTER_FINITE]
1707          >> FULL_SIMP_TAC std_ss [IN_INSERT])
1708      >> RW_TAC std_ss []
1709      >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY, DELETE_NON_ELEMENT]
1710      >> FULL_SIMP_TAC std_ss [IN_INSERT]
1711      >> FULL_SIMP_TAC std_ss [GSYM DELETE_NON_ELEMENT,add_lzero,IN_ABS] )
1712 >> Cases_on `e IN (\p. f p <> 0)`
1713 >- ( RW_TAC std_ss []
1714      >> `~(e IN (s INTER (\p. ~(f p = 0))))` by RW_TAC std_ss [IN_INTER]
1715      >> `!x. x IN (e INSERT s INTER (\p. f p <> 0)) ==> f x <> PosInf`
1716            by METIS_TAC [IN_INTER,IN_INSERT]
1717      >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY, DELETE_NON_ELEMENT,INTER_FINITE]
1718      >> FULL_SIMP_TAC std_ss [IN_INSERT] )
1719 >> RW_TAC std_ss []
1720 >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY, DELETE_NON_ELEMENT]
1721 >> FULL_SIMP_TAC std_ss [IN_INSERT]
1722 >> FULL_SIMP_TAC std_ss [GSYM DELETE_NON_ELEMENT, add_lzero, IN_ABS]
1723QED
1724
1725(* more antecedents added *)
1726Theorem EXTREAL_SUM_IMAGE_INTER_ELIM:
1727     !s. FINITE s ==>
1728         !f s'. ((!x. x IN s ==> f x <> NegInf) \/
1729                 (!x. x IN s ==> f x <> PosInf)) /\
1730                (!x. (~(x IN s')) ==> (f x = 0)) ==>
1731                (EXTREAL_SUM_IMAGE f (s INTER s') =
1732                 EXTREAL_SUM_IMAGE f s)
1733Proof
1734  Suff `!s. FINITE s ==>
1735        (\s. !f s'. ((!x. x IN s ==> f x <> NegInf) \/
1736                     (!x. x IN s ==> f x <> PosInf)) /\
1737                    (!x. (~(x IN s')) ==> (f x = 0)) ==>
1738                    (EXTREAL_SUM_IMAGE f (s INTER s') =
1739                     EXTREAL_SUM_IMAGE f s)) s`
1740  >- RW_TAC std_ss []
1741  >> MATCH_MP_TAC FINITE_INDUCT
1742  >> RW_TAC std_ss [INTER_EMPTY,INSERT_INTER]
1743  >- (FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT]
1744      >> Cases_on `e IN s'`
1745      >- (`~ (e IN (s INTER s'))` by (rw[IN_INTER] >> fs[DELETE_NON_ELEMENT])
1746          >> `!x. x IN e INSERT (s INTER s') ==> f x <> NegInf` by METIS_TAC [IN_INTER,IN_INSERT]
1747          >> FULL_SIMP_TAC std_ss [INTER_FINITE, EXTREAL_SUM_IMAGE_PROPERTY, DELETE_NON_ELEMENT]
1748          >> FULL_SIMP_TAC std_ss [IN_INSERT]
1749          >> METIS_TAC [IN_INTER,DELETE_NON_ELEMENT])
1750      >> FULL_SIMP_TAC std_ss [IN_INSERT]
1751      >> METIS_TAC [DELETE_NON_ELEMENT,add_lzero])
1752  >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT]
1753  >> Cases_on `e IN s'`
1754  >- (`~ (e IN (s INTER s'))` by (rw[IN_INTER] >> fs[DELETE_NON_ELEMENT])
1755      >> `!x. x IN e INSERT (s INTER s') ==> f x <> PosInf` by METIS_TAC [IN_INTER,IN_INSERT]
1756      >> FULL_SIMP_TAC std_ss [INTER_FINITE, EXTREAL_SUM_IMAGE_PROPERTY, DELETE_NON_ELEMENT]
1757      >> FULL_SIMP_TAC std_ss [IN_INSERT]
1758      >> METIS_TAC [IN_INTER,DELETE_NON_ELEMENT])
1759  >> FULL_SIMP_TAC std_ss [IN_INSERT]
1760  >> METIS_TAC [DELETE_NON_ELEMENT,add_lzero]
1761QED
1762
1763(* more antecedents added *)
1764Theorem EXTREAL_SUM_IMAGE_ZERO_DIFF:
1765    !s. FINITE s ==> !f t. ((!x. x IN s ==> f x <> NegInf) \/
1766                             (!x. x IN s ==> f x <> PosInf)) /\
1767                           (!x. x IN t ==> (f x = 0)) ==>
1768                           (EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE f (s DIFF t))
1769Proof
1770  RW_TAC std_ss []
1771  >> `s = (s DIFF t) UNION (s INTER t)` by (RW_TAC std_ss [EXTENSION, IN_INTER, IN_UNION, IN_DIFF]
1772                                            >> METIS_TAC [])
1773  >> `FINITE (s DIFF t) /\ FINITE (s INTER t)` by METIS_TAC [INTER_FINITE, FINITE_DIFF]
1774  >> `DISJOINT (s DIFF t) (s INTER t)` by (RW_TAC std_ss [DISJOINT_DEF, IN_INTER, NOT_IN_EMPTY,
1775                                           EXTENSION, IN_DIFF] >> METIS_TAC [])
1776  >> `EXTREAL_SUM_IMAGE f (s INTER t) = 0` by METIS_TAC [EXTREAL_SUM_IMAGE_0, IN_INTER]
1777  >> METIS_TAC [EXTREAL_SUM_IMAGE_DISJOINT_UNION, add_rzero]
1778QED
1779
1780(* more antecedents added *)
1781Theorem EXTREAL_SUM_IMAGE_MONO:
1782     !s. FINITE s ==>
1783           !f f'. ((!x. x IN s ==> f x <> NegInf /\ f' x <> NegInf) \/
1784                   (!x. x IN s ==> f x <> PosInf /\ f' x <> PosInf)) /\
1785                  (!x. x IN s ==> f x <= f' x) ==>
1786                  EXTREAL_SUM_IMAGE f s <= EXTREAL_SUM_IMAGE f' s
1787Proof
1788   Suff `!s. FINITE s ==>
1789             (\s. !f f'. ((!x. x IN s ==> f x <> NegInf /\ f' x <> NegInf) \/
1790                          (!x. x IN s ==> f x <> PosInf /\ f' x <> PosInf)) /\
1791                         (!x. x IN s ==> f x <= f' x) ==>
1792                         EXTREAL_SUM_IMAGE f s <= EXTREAL_SUM_IMAGE f' s) s`
1793   >- METIS_TAC []
1794   >> MATCH_MP_TAC FINITE_INDUCT
1795   >> RW_TAC real_ss [EXTREAL_SUM_IMAGE_EMPTY,le_refl]
1796   >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT, IN_INSERT,
1797                      DISJ_IMP_THM, FORALL_AND_THM]
1798   >> METIS_TAC [le_add2,EXTREAL_SUM_IMAGE_NOT_INFTY]
1799QED
1800
1801(* NOTE: There's no way to have better (and weaker) antecedents such as
1802  “(!x. x IN s ==> f x <= g x) /\ (?x. x IN s /\ f x < g x)” as in
1803   REAL_SUM_IMAGE_MONO_LT, because, if there exists x such that f x = g x = PosInf,
1804   then both sums become PosInf, making the conclusion impossible.
1805 *)
1806Theorem EXTREAL_SUM_IMAGE_MONO_LT :
1807    !f g s. FINITE s /\ s <> {} /\
1808            ((!x. x IN s ==> f x <> NegInf /\ g x <> NegInf) \/
1809             (!x. x IN s ==> f x <> PosInf /\ g x <> PosInf)) /\
1810            (!x. x IN s ==> f x < g x) ==>
1811            EXTREAL_SUM_IMAGE f s < EXTREAL_SUM_IMAGE g s
1812Proof
1813    Suff ‘!s. FINITE s ==>
1814              (\s. s <> {} ==>
1815                  !f g. ((!x. x IN s ==> f x <> NegInf /\ g x <> NegInf) \/
1816                          (!x. x IN s ==> f x <> PosInf /\ g x <> PosInf)) /\
1817                         (!x. x IN s ==> f x < g x) ==>
1818                          EXTREAL_SUM_IMAGE f s < EXTREAL_SUM_IMAGE g s) s’
1819 >- METIS_TAC []
1820 >> MATCH_MP_TAC FINITE_INDUCT
1821 >> RW_TAC real_ss [EXTREAL_SUM_IMAGE_EMPTY, le_refl, NOT_IN_EMPTY]
1822 >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY, DELETE_NON_ELEMENT, IN_INSERT,
1823                          DISJ_IMP_THM, FORALL_AND_THM]
1824 >| [ (* goal 1 (of 2) *)
1825      Cases_on ‘s = {}’ >> simp [EXTREAL_SUM_IMAGE_EMPTY] \\
1826      MATCH_MP_TAC lt_add2 >> art [] \\
1827      FIRST_X_ASSUM irule >> rw [],
1828      (* goal 2 (of 2) *)
1829      Cases_on ‘s = {}’ >> simp [EXTREAL_SUM_IMAGE_EMPTY] \\
1830      MATCH_MP_TAC lt_add2 >> art [] \\
1831      FIRST_X_ASSUM irule >> rw [] ]
1832QED
1833
1834Theorem EXTREAL_SUM_IMAGE_MONO_SET:
1835     !f s t. (FINITE s /\ FINITE t /\ s SUBSET t /\ (!x. x IN t ==> 0 <= f x)) ==>
1836             EXTREAL_SUM_IMAGE f s <= EXTREAL_SUM_IMAGE f t
1837Proof
1838  RW_TAC std_ss []
1839  >> `t = s UNION (t DIFF s)` by RW_TAC std_ss [UNION_DIFF]
1840  >> `FINITE (t DIFF s)` by RW_TAC std_ss [FINITE_DIFF]
1841  >> `DISJOINT s (t DIFF s)`
1842        by (`DISJOINT s (t DIFF s)`
1843                by (rw [DISJOINT_DEF,IN_DIFF,EXTENSION,GSPECIFICATION,NOT_IN_EMPTY,IN_INTER] \\
1844                    metis_tac[]) \\
1845            metis_tac[])
1846  >> `!x. x IN (s UNION (t DIFF s)) ==> f x <> NegInf`
1847        by METIS_TAC [extreal_of_num_def,extreal_not_infty,lt_infty,lte_trans]
1848  >> `EXTREAL_SUM_IMAGE f t = EXTREAL_SUM_IMAGE f s + EXTREAL_SUM_IMAGE f (t DIFF s)`
1849        by METIS_TAC [EXTREAL_SUM_IMAGE_DISJOINT_UNION]
1850  >> POP_ORW
1851  >> METIS_TAC [le_add2,le_refl,add_rzero,EXTREAL_SUM_IMAGE_POS,IN_DIFF]
1852QED
1853
1854(* more antecedents added *)
1855Theorem EXTREAL_SUM_IMAGE_EQ:
1856     !s. FINITE s ==>
1857           !f f'. ((!x. x IN s ==> f x <> NegInf /\ f' x <> NegInf) \/
1858                   (!x. x IN s ==> f x <> PosInf /\ f' x <> PosInf)) /\
1859                   (!x. x IN s ==> (f x = f' x)) ==>
1860                (EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE f' s)
1861Proof
1862  Suff `!s. FINITE s ==>
1863                (\s. !f f'. ((!x. x IN s ==> f x <> NegInf /\ f' x <> NegInf) \/
1864                   (!x. x IN s ==> f x <> PosInf /\ f' x <> PosInf)) /\ (!x. x IN s ==> (f x = f' x)) ==>
1865                (EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE f' s)) s`
1866  >- PROVE_TAC []
1867  >> MATCH_MP_TAC FINITE_INDUCT
1868  >> RW_TAC real_ss [EXTREAL_SUM_IMAGE_EMPTY]
1869  >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT, IN_INSERT,
1870                           DISJ_IMP_THM, FORALL_AND_THM]
1871  >> METIS_TAC []
1872QED
1873
1874(* ‘!n. 0 <= f n’ can be weakened but enough for now *)
1875Theorem EXTREAL_SUM_IMAGE_OFFSET :
1876    !f m n. m <= n /\ (!n. 0 <= f n) ==>
1877            EXTREAL_SUM_IMAGE f (count n) =
1878            EXTREAL_SUM_IMAGE f (count m) +
1879            EXTREAL_SUM_IMAGE (\i. f (i + m)) (count (n - m))
1880Proof
1881    rpt STRIP_TAC
1882 >> Q.ABBREV_TAC ‘h = \(i :num). i + m’
1883 >> ‘(\i. f (i + m)) = f o h’ by METIS_TAC [o_DEF] >> POP_ORW
1884 (* applying EXTREAL_SUM_IMAGE_IMAGE *)
1885 >> Know ‘EXTREAL_SUM_IMAGE (f o h) (count (n - m)) =
1886          EXTREAL_SUM_IMAGE f (IMAGE h (count (n - m)))’
1887 >- (ONCE_REWRITE_TAC [EQ_SYM_EQ] \\
1888     irule EXTREAL_SUM_IMAGE_IMAGE >> rw []
1889     >- (DISJ1_TAC >> Q.X_GEN_TAC ‘i’ >> rw [] \\
1890         METIS_TAC [pos_not_neginf]) \\
1891     rw [INJ_DEF, Abbr ‘h’]) >> Rewr'
1892 (* preparing for EXTREAL_SUM_IMAGE_DISJOINT_UNION *)
1893 >> Know ‘count n = count m UNION (IMAGE h (count (n - m)))’
1894 >- (rw [Once EXTENSION] >> EQ_TAC >> rw [Abbr ‘h’] \\
1895    ‘x < m \/ m <= x’ by rw [] >- art [] \\
1896     DISJ2_TAC >> Q.EXISTS_TAC ‘x - m’ >> rw [])
1897 >> Rewr'
1898 (* applying EXTREAL_SUM_IMAGE_DISJOINT_UNION *)
1899 >> irule EXTREAL_SUM_IMAGE_DISJOINT_UNION >> simp []
1900 >> reverse CONJ_TAC
1901 >- (DISJ1_TAC >> rw [] >> METIS_TAC [pos_not_neginf])
1902 >> rw [DISJOINT_ALT, Abbr ‘h’]
1903QED
1904
1905(* if the first N items of (g n) are all zero, we can ignore them in SIGMA *)
1906Theorem EXTREAL_SUM_IMAGE_EQ_SHIFT :
1907    !f g N. (!n. n < N ==> g n = 0) /\ (!n. 0 <= f n /\ f n = g (n + N)) ==>
1908            !n. EXTREAL_SUM_IMAGE f (count n) = EXTREAL_SUM_IMAGE g (count (n + N))
1909Proof
1910    rpt STRIP_TAC
1911 >> Know ‘EXTREAL_SUM_IMAGE g (count (n + N)) =
1912          EXTREAL_SUM_IMAGE g (count N) +
1913          EXTREAL_SUM_IMAGE (\i. g (i + N)) (count (n + N - N))’
1914 >- (MATCH_MP_TAC EXTREAL_SUM_IMAGE_OFFSET >> rw [] \\
1915    ‘n < N \/ N <= n’ by rw [] >- rw [] \\
1916    ‘n = n - N + N’ by rw [] >> POP_ORW >> METIS_TAC [])
1917 >> Rewr'
1918 >> Know ‘EXTREAL_SUM_IMAGE g (count N) = 0’
1919 >- (irule EXTREAL_SUM_IMAGE_0 >> rw [])
1920 >> Rewr'
1921 >> rw []
1922 >> irule EXTREAL_SUM_IMAGE_EQ >> rw []
1923 >> DISJ1_TAC >> rw []
1924 >> MATCH_MP_TAC pos_not_neginf
1925 >> Suff ‘g (N + x) = f x’ >- (Rewr' >> rw [])
1926 >> METIS_TAC [ADD_SYM]
1927QED
1928
1929Theorem EXTREAL_SUM_IMAGE_POS_MEM_LE:
1930    !f s. FINITE s /\ (!x. x IN s ==> 0 <= f x) ==>
1931         (!x. x IN s ==> f x <= EXTREAL_SUM_IMAGE f s)
1932Proof
1933  Suff `!s. FINITE s ==>
1934        (\s. !f. (!x. x IN s ==> 0 <= f x) ==>
1935            (!x. x IN s ==> f x <= EXTREAL_SUM_IMAGE f s)) s`
1936  >- RW_TAC std_ss []
1937  >> MATCH_MP_TAC FINITE_INDUCT
1938  >> RW_TAC std_ss [NOT_IN_EMPTY]
1939  >> `!x. x IN e INSERT s ==> f x <> NegInf` by METIS_TAC [lt_infty,lte_trans,num_not_infty]
1940  >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT]
1941  >> FULL_SIMP_TAC std_ss [IN_INSERT]
1942  >- METIS_TAC [EXTREAL_SUM_IMAGE_POS,le_add2,add_rzero,extreal_of_num_def,extreal_not_infty,le_refl]
1943  >> `f x <= EXTREAL_SUM_IMAGE f s` by FULL_SIMP_TAC std_ss [IN_INSERT]
1944  >> METIS_TAC [le_add2,add_lzero,extreal_of_num_def,extreal_not_infty]
1945QED
1946
1947Theorem EXTREAL_SUM_IMAGE_EQ_POSINF :
1948    !f s. FINITE s  /\ (!x. x IN s ==> 0 <= f x) /\
1949         (?i. i IN s /\ f i = PosInf) ==> EXTREAL_SUM_IMAGE f s = PosInf
1950Proof
1951    rpt STRIP_TAC
1952 >> ‘f i <= EXTREAL_SUM_IMAGE f s’ by PROVE_TAC [EXTREAL_SUM_IMAGE_POS_MEM_LE]
1953 >> gs [le_infty]
1954QED
1955
1956(* more antecedents added *)
1957Theorem EXTREAL_SUM_IMAGE_ADD:
1958    !s. FINITE s ==>
1959        !f f'. ((!x. x IN s ==> f x <> NegInf /\ f' x <> NegInf) \/
1960                (!x. x IN s ==> f x <> PosInf /\ f' x <> PosInf)) ==>
1961               (EXTREAL_SUM_IMAGE (\x. f x + f' x) s =
1962                EXTREAL_SUM_IMAGE f s + EXTREAL_SUM_IMAGE f' s)
1963Proof
1964  Suff `!s. FINITE s ==>
1965        (\s. !f f'. ((!x. x IN s ==> f x <> NegInf /\ f' x <> NegInf) \/
1966                   (!x. x IN s ==> f x <> PosInf /\ f' x <> PosInf)) ==>
1967                (EXTREAL_SUM_IMAGE (\x. f x + f' x) s =
1968                 EXTREAL_SUM_IMAGE f s + EXTREAL_SUM_IMAGE f' s)) s`
1969  >- RW_TAC std_ss []
1970  >> MATCH_MP_TAC FINITE_INDUCT
1971  >> RW_TAC real_ss [EXTREAL_SUM_IMAGE_EMPTY,add_lzero]
1972  >- (`!x. x IN e INSERT s ==> (\x. f x + f' x) x <> NegInf` by METIS_TAC [add_not_infty]
1973      >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT]
1974      >> `EXTREAL_SUM_IMAGE f s + (f' e + EXTREAL_SUM_IMAGE f' s) =
1975          f' e + (EXTREAL_SUM_IMAGE f' s + EXTREAL_SUM_IMAGE f s)`
1976           by METIS_TAC [add_comm,add_assoc,EXTREAL_SUM_IMAGE_NOT_INFTY,add_not_infty, IN_INSERT]
1977      >> `f e + EXTREAL_SUM_IMAGE f s + (f' e + EXTREAL_SUM_IMAGE f' s) =
1978          f e + (EXTREAL_SUM_IMAGE f s + (f' e + EXTREAL_SUM_IMAGE f' s))`
1979           by METIS_TAC [add_comm,add_assoc,EXTREAL_SUM_IMAGE_NOT_INFTY,add_not_infty, IN_INSERT]
1980      >> POP_ORW >> POP_ORW
1981      >> FULL_SIMP_TAC std_ss [IN_INSERT]
1982      >> METIS_TAC [add_comm,add_assoc,EXTREAL_SUM_IMAGE_NOT_INFTY,add_not_infty,IN_INSERT])
1983  >> `!x. x IN e INSERT s ==> (\x. f x + f' x) x <> PosInf` by METIS_TAC [add_not_infty]
1984  >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY,DELETE_NON_ELEMENT]
1985  >> `EXTREAL_SUM_IMAGE f s + (f' e + EXTREAL_SUM_IMAGE f' s) =
1986      f' e + (EXTREAL_SUM_IMAGE f' s + EXTREAL_SUM_IMAGE f s)`
1987         by METIS_TAC [add_comm,add_assoc,EXTREAL_SUM_IMAGE_NOT_INFTY,add_not_infty, IN_INSERT]
1988  >> `f e + EXTREAL_SUM_IMAGE f s + (f' e + EXTREAL_SUM_IMAGE f' s) =
1989      f e + (EXTREAL_SUM_IMAGE f s + (f' e + EXTREAL_SUM_IMAGE f' s))`
1990         by METIS_TAC [add_comm,add_assoc,EXTREAL_SUM_IMAGE_NOT_INFTY,add_not_infty, IN_INSERT]
1991  >> POP_ORW >> POP_ORW
1992  >> FULL_SIMP_TAC std_ss [IN_INSERT]
1993  >> METIS_TAC [add_comm,add_assoc,EXTREAL_SUM_IMAGE_NOT_INFTY,add_not_infty,IN_INSERT]
1994QED
1995
1996(* more antecedents added *)
1997Theorem EXTREAL_SUM_IMAGE_SUB:
1998    !s. FINITE s ==>
1999        !f f'. ((!x. x IN s ==> f x <> NegInf /\ f' x <> PosInf) \/
2000                (!x. x IN s ==> f x <> PosInf /\ f' x <> NegInf)) ==>
2001               (EXTREAL_SUM_IMAGE (\x. f x - f' x) s =
2002                EXTREAL_SUM_IMAGE f s - EXTREAL_SUM_IMAGE f' s)
2003Proof
2004  Suff `!s. FINITE s ==>
2005        (\s. !f f'. ((!x. x IN s ==> f x <> NegInf /\ f' x <> PosInf) \/
2006                   (!x. x IN s ==> f x <> PosInf /\ f' x <> NegInf)) ==>
2007                (EXTREAL_SUM_IMAGE (\x. f x - f' x) s =
2008                 EXTREAL_SUM_IMAGE f s - EXTREAL_SUM_IMAGE f' s)) s`
2009  >- RW_TAC std_ss []
2010  >> MATCH_MP_TAC FINITE_INDUCT
2011  >> RW_TAC real_ss [EXTREAL_SUM_IMAGE_EMPTY,sub_rzero]
2012  >- (`FINITE (e INSERT s)` by FULL_SIMP_TAC std_ss [FINITE_INSERT]
2013      >> (MP_TAC o Q.SPEC `(\x. f x - f' x)` o UNDISCH o Q.SPEC `e INSERT  s`) EXTREAL_SUM_IMAGE_IN_IF
2014      >> `!x. x IN e INSERT s ==> (\x. f x - f' x) x <> NegInf`
2015          by RW_TAC std_ss [sub_not_infty]
2016      >> `EXTREAL_SUM_IMAGE f (e INSERT s) <> NegInf` by METIS_TAC [IN_INSERT,EXTREAL_SUM_IMAGE_NOT_INFTY]
2017      >> `EXTREAL_SUM_IMAGE f' (e INSERT s) <> PosInf` by METIS_TAC [IN_INSERT,EXTREAL_SUM_IMAGE_NOT_INFTY]
2018      >> RW_TAC std_ss [extreal_sub_add]
2019      >> `-EXTREAL_SUM_IMAGE f' (e INSERT s) = Normal (-1) * EXTREAL_SUM_IMAGE f' (e INSERT s)`
2020            by METIS_TAC [neg_minus1,extreal_of_num_def,extreal_ainv_def]
2021      >> POP_ORW
2022      >> `Normal (-1) * EXTREAL_SUM_IMAGE f' (e INSERT s) =
2023          EXTREAL_SUM_IMAGE (\x. Normal (-1) * f' x) (e INSERT s)` by METIS_TAC [EXTREAL_SUM_IMAGE_CMUL]
2024      >> RW_TAC std_ss [GSYM extreal_ainv_def, GSYM extreal_of_num_def,GSYM neg_minus1]
2025      >> `(\x. if x IN e INSERT s then f x + -f' x else 0) =
2026          (\x. if x IN e INSERT s then (\x. f x + -f' x) x else 0)` by METIS_TAC []
2027      >> POP_ORW
2028      >> (MP_TAC o Q.SPEC `(\x. f x + -f' x)` o UNDISCH o Q.SPEC `e INSERT s ` o GSYM)
2029           EXTREAL_SUM_IMAGE_IN_IF
2030      >> RW_TAC std_ss []
2031      >> `!x. x IN e INSERT s ==> NegInf <> f x + -f' x` by METIS_TAC [extreal_sub_add]
2032      >> FULL_SIMP_TAC std_ss []
2033      >> `(\x. f x + -f' x) = (\x. f x + (\x. -f' x) x)` by METIS_TAC []
2034      >> POP_ORW
2035      >> (MATCH_MP_TAC o UNDISCH o Q.SPEC `e INSERT s`) EXTREAL_SUM_IMAGE_ADD
2036      >> DISJ1_TAC
2037      >> RW_TAC std_ss []
2038      >> Cases_on `f' x`
2039      >> METIS_TAC [extreal_ainv_def,extreal_not_infty])
2040  >> `FINITE (e INSERT s)` by FULL_SIMP_TAC std_ss [FINITE_INSERT]
2041  >> (MP_TAC o Q.SPEC `(\x. f x - f' x)` o UNDISCH o Q.SPEC `e INSERT  s`) EXTREAL_SUM_IMAGE_IN_IF
2042  >> `!x. x IN e INSERT s ==> (\x. f x - f' x) x <> PosInf`
2043        by RW_TAC std_ss [sub_not_infty]
2044  >> `EXTREAL_SUM_IMAGE f (e INSERT s) <> PosInf` by METIS_TAC [IN_INSERT,EXTREAL_SUM_IMAGE_NOT_INFTY]
2045  >> `EXTREAL_SUM_IMAGE f' (e INSERT s) <> NegInf` by METIS_TAC [IN_INSERT,EXTREAL_SUM_IMAGE_NOT_INFTY]
2046  >> RW_TAC std_ss [extreal_sub_add]
2047  >> `-EXTREAL_SUM_IMAGE f' (e INSERT s) = Normal (-1) * EXTREAL_SUM_IMAGE f' (e INSERT s)`
2048        by METIS_TAC [neg_minus1,extreal_of_num_def,extreal_ainv_def]
2049  >> POP_ORW
2050  >> `Normal (-1) * EXTREAL_SUM_IMAGE f' (e INSERT s) =
2051      EXTREAL_SUM_IMAGE (\x. Normal (-1) * f' x) (e INSERT s)` by METIS_TAC [EXTREAL_SUM_IMAGE_CMUL]
2052  >> RW_TAC std_ss [GSYM extreal_ainv_def, GSYM extreal_of_num_def,GSYM neg_minus1]
2053  >> `(\x. if x IN e INSERT s then f x + -f' x else 0) =
2054      (\x. if x IN e INSERT s then (\x. f x + -f' x) x else 0)` by METIS_TAC []
2055  >> POP_ORW
2056  >> (MP_TAC o Q.SPEC `(\x. f x + -f' x)` o UNDISCH o Q.SPEC `e INSERT s ` o GSYM) EXTREAL_SUM_IMAGE_IN_IF
2057  >> RW_TAC std_ss []
2058  >> `!x. x IN e INSERT s ==> PosInf <> f x + -f' x` by METIS_TAC [extreal_sub_add]
2059  >> FULL_SIMP_TAC std_ss []
2060  >> `(\x. f x + -f' x) = (\x. f x + (\x. -f' x) x)` by METIS_TAC []
2061  >> POP_ORW
2062  >> (MATCH_MP_TAC o UNDISCH o Q.SPEC `e INSERT s`) EXTREAL_SUM_IMAGE_ADD
2063  >> DISJ2_TAC
2064  >> RW_TAC std_ss []
2065  >> Cases_on `f' x`
2066  >> METIS_TAC [extreal_ainv_def,extreal_not_infty]
2067QED
2068
2069(* more antecedents added *)
2070Theorem EXTREAL_SUM_IMAGE_SUM_IMAGE:
2071    !s s' f. FINITE s /\ FINITE s' /\
2072             ((!x. x IN s CROSS s' ==> f (FST x) (SND x) <> NegInf) \/
2073              (!x. x IN s CROSS s' ==> f (FST x) (SND x) <> PosInf)) ==>
2074             (EXTREAL_SUM_IMAGE (\x. EXTREAL_SUM_IMAGE (f x) s') s =
2075              EXTREAL_SUM_IMAGE (\x. f (FST x) (SND x)) (s CROSS s'))
2076Proof
2077    Suff `!s. FINITE s ==>
2078             (\s. !s' f. FINITE s' /\
2079                       ((!x. x IN s CROSS s' ==> f (FST x) (SND x) <> NegInf) \/
2080                        (!x. x IN s CROSS s' ==> f (FST x) (SND x) <> PosInf)) ==>
2081                 (EXTREAL_SUM_IMAGE (\x. EXTREAL_SUM_IMAGE (f x) s') s =
2082                  EXTREAL_SUM_IMAGE (\x. f (FST x) (SND x)) (s CROSS s'))) s`
2083 >- METIS_TAC []
2084 >> MATCH_MP_TAC FINITE_INDUCT
2085 >> RW_TAC std_ss [CROSS_EMPTY, EXTREAL_SUM_IMAGE_EMPTY, DELETE_NON_ELEMENT] (* 2 subgoals *)
2086 >> `((e INSERT s) CROSS s') = (IMAGE (\x. (e,x)) s') UNION (s CROSS s')`
2087        by (RW_TAC std_ss [Once EXTENSION, IN_INSERT, IN_SING, IN_CROSS, IN_UNION, IN_IMAGE]
2088            >> Cases_on `x`
2089            >> RW_TAC std_ss [] >> FULL_SIMP_TAC std_ss [FST,SND, GSYM DELETE_NON_ELEMENT]
2090            >> METIS_TAC []) >> POP_ORW
2091 >> `DISJOINT (IMAGE (\x. (e,x)) s') (s CROSS s')`
2092        by (FULL_SIMP_TAC std_ss [GSYM DELETE_NON_ELEMENT, DISJOINT_DEF, Once EXTENSION,
2093                                  NOT_IN_EMPTY, IN_INTER, IN_CROSS, IN_SING, IN_IMAGE]
2094            >> STRIP_TAC >> Cases_on `x`
2095            >> RW_TAC std_ss [FST, SND]
2096            >> METIS_TAC [])
2097 >> `FINITE (IMAGE (\x. (e,x)) s')` by RW_TAC std_ss [IMAGE_FINITE]
2098 >> `FINITE (s CROSS s')` by RW_TAC std_ss [FINITE_CROSS]
2099 >> (MP_TAC o Q.SPEC `(\x. f (FST x) (SND x))` o UNDISCH o UNDISCH o UNDISCH o
2100       REWRITE_RULE [GSYM AND_IMP_INTRO] o
2101       Q.ISPECL [`IMAGE (\x. (e:'a,x)) (s':'b->bool)`,
2102                 `(s:'a->bool) CROSS (s':'b->bool)`]) EXTREAL_SUM_IMAGE_DISJOINT_UNION
2103 >| [ `(!x. x IN IMAGE (\x. (e,x)) s' UNION s CROSS s' ==> f (FST x) (SND x) <> NegInf)`
2104          by (FULL_SIMP_TAC std_ss [IN_IMAGE,IN_UNION, IN_INSERT, IN_CROSS]
2105              >> METIS_TAC [FST, SND]),
2106      `(!x. x IN IMAGE (\x. (e,x)) s' UNION s CROSS s' ==> f (FST x) (SND x) <> PosInf)`
2107          by (FULL_SIMP_TAC std_ss [IN_IMAGE, IN_UNION, IN_INSERT, IN_CROSS]
2108              >> METIS_TAC [FST, SND]) ]
2109 >> RW_TAC std_ss []
2110 >> `INJ (\x. (e,x)) s' (IMAGE (\x. (e,x)) s')` by RW_TAC std_ss [INJ_DEF, IN_IMAGE]
2111 >> (MP_TAC o Q.SPEC `(\x. f (FST x) (SND x))` o UNDISCH o Q.SPEC `(\x. (e,x))` o
2112       UNDISCH o Q.SPEC `s'` o
2113       INST_TYPE [``:'c``|->``:'a # 'b``] o INST_TYPE [``:'a``|->``:'b``] o
2114       INST_TYPE [``:'b``|->``:'c``]) EXTREAL_SUM_IMAGE_IMAGE
2115 >| [ `!x. x IN IMAGE (\x. (e,x)) s' ==> (\x. f (FST x) (SND x)) x <> NegInf`
2116          by FULL_SIMP_TAC std_ss [IN_IMAGE, IN_UNION, IN_INSERT, IN_CROSS],
2117      `!x. x IN IMAGE (\x. (e,x)) s' ==> (\x. f (FST x) (SND x)) x <> PosInf`
2118          by FULL_SIMP_TAC std_ss [IN_IMAGE, IN_UNION, IN_INSERT, IN_CROSS] ]
2119 >> RW_TAC std_ss [o_DEF]
2120 >| [ `!x. x IN e INSERT s ==> (\x. EXTREAL_SUM_IMAGE (f x) s') x <> NegInf`
2121        by METIS_TAC [EXTREAL_SUM_IMAGE_NOT_INFTY, IN_INSERT, IN_CROSS, FST, SND],
2122      `!x. x IN e INSERT s ==> (\x. EXTREAL_SUM_IMAGE (f x) s') x <> PosInf`
2123        by METIS_TAC [EXTREAL_SUM_IMAGE_NOT_INFTY, IN_INSERT, IN_CROSS, FST, SND] ]
2124 >> (MP_TAC o Q.SPEC `e` o UNDISCH o
2125       Q.SPECL [`(\x. EXTREAL_SUM_IMAGE (f x) s')`,`s`]) EXTREAL_SUM_IMAGE_PROPERTY
2126 >> RW_TAC std_ss []
2127 >> FULL_SIMP_TAC std_ss [IN_INSERT, IN_IMAGE, IN_UNION]
2128 >> METIS_TAC [FUN_EQ_THM]
2129QED
2130
2131Theorem EXTREAL_SUM_IMAGE_NORMAL:
2132    !f s. FINITE s ==> (EXTREAL_SUM_IMAGE (\x. Normal (f x)) s = Normal (SIGMA f s))
2133Proof
2134    Suff `!s. FINITE s ==>
2135             (\s. !f. EXTREAL_SUM_IMAGE (\x. Normal (f x)) s = Normal (SIGMA f s) ) s`
2136 >- RW_TAC std_ss []
2137 >> MATCH_MP_TAC FINITE_INDUCT
2138 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_EMPTY, REAL_SUM_IMAGE_THM, extreal_of_num_def,
2139                   REAL_SUM_IMAGE_THM, GSYM extreal_add_def]
2140 >> (MP_TAC o UNDISCH o Q.SPECL [`(\x. Normal (f x))`,`s`]) EXTREAL_SUM_IMAGE_PROPERTY
2141 >> FULL_SIMP_TAC std_ss [DELETE_NON_ELEMENT, extreal_not_infty]
2142QED
2143
2144(* more antecedents added *)
2145Theorem EXTREAL_SUM_IMAGE_IN_IF_ALT:
2146    !s f z. FINITE s /\ ((!x. x IN s ==> f x <> NegInf) \/
2147                         (!x. x IN s ==> f x <> PosInf)) ==>
2148           (EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE (\x. if x IN s then f x else z) s)
2149Proof
2150    Suff `!s. FINITE s ==>
2151             (\s. !f z. ((!x. x IN s ==> f x <> NegInf) \/ (!x. x IN s ==> f x <> PosInf)) ==>
2152                        (EXTREAL_SUM_IMAGE f s =
2153                         EXTREAL_SUM_IMAGE (\x. if x IN s then f x else z) s)) s`
2154 >- METIS_TAC []
2155 >> MATCH_MP_TAC FINITE_INDUCT
2156 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_EMPTY]
2157 >- (`!i. i IN e INSERT s ==> (\x. if x IN e INSERT s then f x else z) i <> NegInf`
2158       by RW_TAC std_ss []
2159     >> reverse (RW_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY]) (* 2 sub-goals here *)
2160     >> FULL_SIMP_TAC std_ss [IN_INSERT]                     (* 1 remains *)
2161     >> FULL_SIMP_TAC std_ss [DELETE_NON_ELEMENT]
2162     >> Suff `EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE (\x. if x IN e INSERT s then f x else z) s`
2163     >- RW_TAC std_ss [IN_INSERT]
2164     >> `EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE (\x. if x IN s then f x else z) s`
2165          by METIS_TAC [IN_INSERT]
2166     >> POP_ORW
2167     >> (MATCH_MP_TAC o UNDISCH o Q.SPEC `s`) EXTREAL_SUM_IMAGE_EQ
2168     >> RW_TAC std_ss [IN_INSERT])
2169 >> `!i. i IN e INSERT s ==> (\x. if x IN e INSERT s then f x else z) i <> PosInf` by RW_TAC std_ss []
2170 >> reverse (RW_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY])
2171 >- FULL_SIMP_TAC std_ss [IN_INSERT]
2172 >> FULL_SIMP_TAC std_ss [DELETE_NON_ELEMENT]
2173 >> Suff `EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE (\x. if x IN e INSERT s then f x else z) s`
2174 >- RW_TAC std_ss []
2175 >> `EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE (\x. if x IN s then f x else z) s`
2176       by METIS_TAC [IN_INSERT]
2177 >> POP_ORW
2178 >> (MATCH_MP_TAC o UNDISCH o Q.SPEC `s`) EXTREAL_SUM_IMAGE_EQ
2179 >> RW_TAC std_ss [IN_INSERT]
2180QED
2181
2182Theorem EXTREAL_SUM_IMAGE_CROSS_SYM :
2183    !f s1 s2. FINITE s1 /\ FINITE s2 /\
2184             ((!s. s IN (s1 CROSS s2) ==> f s <> NegInf) \/
2185              (!s. s IN (s1 CROSS s2) ==> f s <> PosInf)) ==>
2186             (EXTREAL_SUM_IMAGE (\(x,y). f (x,y)) (s1 CROSS s2) =
2187              EXTREAL_SUM_IMAGE (\(y,x). f (x,y)) (s2 CROSS s1))
2188Proof
2189    rpt GEN_TAC
2190 >> DISCH_TAC
2191 >> `s2 CROSS s1 = IMAGE (\a. (SND a, FST a)) (s1 CROSS s2)`
2192       by (RW_TAC std_ss [IN_IMAGE, IN_CROSS, EXTENSION] \\
2193           METIS_TAC [FST,SND,PAIR])
2194 >> POP_ORW
2195 >> `INJ (\a. (SND a, FST a)) (s1 CROSS s2) (IMAGE (\a. (SND a, FST a)) (s1 CROSS s2))`
2196       by (RW_TAC std_ss [INJ_DEF, IN_IMAGE, IN_CROSS] \\
2197           METIS_TAC [FST,SND,PAIR])
2198 >> Q.ABBREV_TAC ‘f' = \a. (SND a, FST a)’
2199 >> Q.ABBREV_TAC ‘g = \(y,x). f (x,y)’
2200 >> Know ‘(\(x,y). f (x,y)) = g o f'’
2201 >- (rw [Abbr ‘g’, Abbr ‘f'’, o_DEF, FUN_EQ_THM] \\
2202     Cases_on ‘x’ >> rw [])
2203 >> Rewr'
2204 >> ONCE_REWRITE_TAC [EQ_SYM_EQ]
2205 >> irule EXTREAL_SUM_IMAGE_IMAGE
2206 >> CONJ_TAC >- (MATCH_MP_TAC FINITE_CROSS >> rw [])
2207 >> rw [Abbr ‘g’]
2208 >| [ DISJ1_TAC, DISJ2_TAC ]
2209 >> Q.X_GEN_TAC ‘x’ >> Cases_on ‘x’ >> rw []
2210 >> FIRST_X_ASSUM MATCH_MP_TAC
2211 >> rename1 ‘(q,r) = f' y’ >> Cases_on ‘y’
2212 >> fs [Abbr ‘f'’]
2213QED
2214
2215Theorem EXTREAL_SUM_IMAGE_COUNT :
2216    !f. (!x. f x <> PosInf) \/ (!x. f x <> NegInf) ==>
2217        (EXTREAL_SUM_IMAGE f (count 2) = f 0 + f 1) /\
2218        (EXTREAL_SUM_IMAGE f (count 3) = f 0 + f 1 + f 2) /\
2219        (EXTREAL_SUM_IMAGE f (count 4) = f 0 + f 1 + f 2 + f 3) /\
2220        (EXTREAL_SUM_IMAGE f (count 5) = f 0 + f 1 + f 2 + f 3 + f 4)
2221Proof
2222    Q.X_GEN_TAC ‘f’
2223 >> DISCH_TAC
2224 >> `count 2 = {0;1} /\
2225     count 3 = {0;1;2} /\
2226     count 4 = {0;1;2;3} /\
2227     count 5 = {0;1;2;3;4}`
2228       by RW_TAC real_ss [EXTENSION, IN_COUNT, IN_INSERT, IN_SING]
2229 >> `{1:num} DELETE 0 = {1}` by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING]
2230 >> `{2:num} DELETE 1 = {2}` by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING]
2231 >> `{3:num} DELETE 2 = {3}` by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING]
2232 >> `{4:num} DELETE 3 = {4}` by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING]
2233 >> `{2:num; 3} DELETE 1 = {2;3}`
2234        by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING, IN_INSERT]
2235 >> `{3:num; 4} DELETE 2 = {3;4}`
2236        by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING, IN_INSERT]
2237 >> `{2:num; 3; 4} DELETE 1 = {2;3;4}`
2238        by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING, IN_INSERT]
2239 >> `{1:num; 2} DELETE 0 = {1;2}`
2240        by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING, IN_INSERT]
2241 >> `{1:num; 2; 3} DELETE 0 = {1;2;3}`
2242        by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING, IN_INSERT]
2243 >> `{1:num; 2; 3; 4} DELETE 0 = {1;2;3;4}`
2244        by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING, IN_INSERT]
2245 >> FULL_SIMP_TAC real_ss [FINITE_SING, FINITE_INSERT, EXTREAL_SUM_IMAGE_INSERT,
2246                           EXTREAL_SUM_IMAGE_SING, IN_INSERT, NOT_IN_EMPTY,
2247                           add_assoc, add_not_infty]
2248QED
2249
2250Overload SIGMA = ``EXTREAL_SUM_IMAGE``
2251
2252(* N-ARY SUMMATION *)
2253val _ = Unicode.unicode_version {u = UTF8.chr 0x2211, tmnm = "SIGMA"};
2254
2255Theorem NESTED_EXTREAL_SUM_IMAGE_REVERSE:
2256    !f s s'. FINITE s /\ FINITE s' /\
2257            (!x y. x IN s /\ y IN s' ==> f x y <> NegInf) ==>
2258            (EXTREAL_SUM_IMAGE (\x. EXTREAL_SUM_IMAGE (f x) s') s =
2259             EXTREAL_SUM_IMAGE (\x. EXTREAL_SUM_IMAGE (\y. f y x) s) s')
2260Proof
2261    rpt STRIP_TAC
2262 >> Know `SIGMA (\x. SIGMA (f x) s') s =
2263          SIGMA (\x. f (FST x) (SND x)) (s CROSS s')`
2264 >- (MATCH_MP_TAC EXTREAL_SUM_IMAGE_SUM_IMAGE \\
2265     ASM_REWRITE_TAC [IN_CROSS]) >> Rewr'
2266 >> Know `SIGMA (\x. SIGMA ((\x y. f y x) x) s) s' =
2267          SIGMA (\x. (\x y. f y x) (FST x) (SND x)) (s' CROSS s)`
2268 >- (MATCH_MP_TAC EXTREAL_SUM_IMAGE_SUM_IMAGE \\
2269     BETA_TAC >> ASM_REWRITE_TAC [IN_CROSS] >> PROVE_TAC [])
2270 >> BETA_TAC >> Rewr'
2271 >> Know `(s' CROSS s) = IMAGE (\x. (SND x, FST x)) (s CROSS s')`
2272 >- (RW_TAC std_ss [EXTENSION, IN_CROSS, IN_IMAGE] \\
2273     EQ_TAC >- (STRIP_TAC >> Q.EXISTS_TAC `(SND x, FST x)` >> RW_TAC std_ss [PAIR]) \\
2274     RW_TAC std_ss [] >> RW_TAC std_ss [FST, SND]) >> Rewr'
2275 >> `FINITE (s CROSS s')` by RW_TAC std_ss [FINITE_CROSS]
2276 >> `INJ (\x. (SND x,FST x)) (s CROSS s') (IMAGE (\x. (SND x,FST x)) (s CROSS s'))`
2277       by (RW_TAC std_ss [INJ_DEF, IN_IMAGE] >- METIS_TAC [] \\
2278           METIS_TAC [PAIR, PAIR_EQ])
2279 >> Know `SIGMA (\x. f (SND x) (FST x)) (IMAGE (\x. (SND x,FST x)) (s CROSS s')) =
2280          SIGMA ((\x. f (SND x) (FST x)) o (\x. (SND x,FST x))) (s CROSS s')`
2281 >- (irule EXTREAL_SUM_IMAGE_IMAGE >> art [] \\
2282     DISJ1_TAC >> RW_TAC std_ss [IN_IMAGE, IN_CROSS] \\
2283     RW_TAC std_ss [FST, SND])
2284 >> Rewr' >> RW_TAC std_ss [o_DEF]
2285QED
2286
2287Theorem EXTREAL_SUM_IMAGE_SUM_IMAGE_MONO:
2288   !(f :num -> num -> extreal) a b c d.
2289        (!m n. 0 <= f m n) /\ a <= c /\ b <= d ==>
2290        SIGMA (\i. SIGMA (f i) (count a)) (count b) <=
2291        SIGMA (\i. SIGMA (f i) (count c)) (count d)
2292Proof
2293    rpt STRIP_TAC >> MATCH_MP_TAC le_trans
2294 >> Q.EXISTS_TAC `SIGMA (\i. SIGMA (f i) (count a)) (count d)`
2295 >> CONJ_TAC
2296 >- (MATCH_MP_TAC EXTREAL_SUM_IMAGE_MONO_SET \\
2297     SIMP_TAC arith_ss [FINITE_COUNT] \\
2298     CONJ_TAC >- (MATCH_MP_TAC COUNT_MONO >> RW_TAC arith_ss []) \\
2299     GEN_TAC >> DISCH_TAC \\
2300     MATCH_MP_TAC EXTREAL_SUM_IMAGE_POS >> PROVE_TAC [FINITE_COUNT])
2301 >> irule EXTREAL_SUM_IMAGE_MONO
2302 >> SIMP_TAC arith_ss [FINITE_COUNT]
2303 >> CONJ_TAC
2304 >- (GEN_TAC >> DISCH_TAC \\
2305     MATCH_MP_TAC EXTREAL_SUM_IMAGE_MONO_SET \\
2306     SIMP_TAC arith_ss [FINITE_COUNT] \\
2307     CONJ_TAC >- (MATCH_MP_TAC COUNT_MONO >> RW_TAC arith_ss []) \\
2308     PROVE_TAC [])
2309 >> DISJ1_TAC >> GEN_TAC >> DISCH_TAC
2310 >> CONJ_TAC
2311 >- (MATCH_MP_TAC pos_not_neginf \\
2312     MATCH_MP_TAC EXTREAL_SUM_IMAGE_POS >> RW_TAC std_ss [FINITE_COUNT])
2313 >> MATCH_MP_TAC pos_not_neginf
2314 >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_POS
2315 >> RW_TAC std_ss [FINITE_COUNT]
2316QED
2317
2318Theorem EXTREAL_SUM_IMAGE_POW:
2319    !f s. FINITE s ==>
2320        ((!x. x IN s ==> f x <> NegInf) /\ (!x. x IN s ==> f x <> PosInf)) ==>
2321        ((EXTREAL_SUM_IMAGE f s) pow 2 =
2322          EXTREAL_SUM_IMAGE (\(i,j). f i * f j) (s CROSS s))
2323Proof
2324    rpt STRIP_TAC
2325 >> `(\(i,j). f i * f j) = (\x. (\i j. f i * f j) (FST x) (SND x))`
2326       by (RW_TAC std_ss [FUN_EQ_THM] \\
2327           Cases_on `x` >> RW_TAC std_ss []) >> POP_ORW
2328 >> (MP_TAC o Q.SPECL [`s`,`s`,`(\i j. f i * f j)`] o INST_TYPE [``:'b`` |-> ``:'a``])
2329       EXTREAL_SUM_IMAGE_SUM_IMAGE >> art []
2330 >> Know `((!x. x IN s CROSS s ==> (\i j. f i * f j) (FST x) (SND x) <> NegInf) \/
2331           (!x. x IN s CROSS s ==> (\i j. f i * f j) (FST x) (SND x) <> PosInf))`
2332 >- (RW_TAC std_ss [IN_CROSS] \\
2333     DISJ1_TAC >> RW_TAC std_ss [] \\
2334    `f (FST x) <> NegInf /\ f (SND x) <> NegInf` by PROVE_TAC [] \\
2335     METIS_TAC [mul_not_infty2])
2336 >> SIMP_TAC std_ss [] >> DISCH_TAC
2337 >> DISCH_THEN (ONCE_REWRITE_TAC o wrap o GSYM)
2338 >> Know `!x. x IN s ==> SIGMA (\j. f x * f j) s = f x * SIGMA f s`
2339 >- (rpt STRIP_TAC >> `?c. f x = Normal c` by PROVE_TAC [extreal_cases] >> art [] \\
2340     ASM_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_CMUL]) >> DISCH_TAC
2341 >> Know `SIGMA (\x. SIGMA (\j. f x * f j) s) s = SIGMA (\x. f x * (SIGMA f s)) s`
2342 >- (irule EXTREAL_SUM_IMAGE_EQ >> ASM_SIMP_TAC std_ss [] \\
2343     DISJ2_TAC >> GEN_TAC >> DISCH_TAC \\
2344    `f x <> PosInf /\ f x <> NegInf` by PROVE_TAC [] \\
2345     Suff `SIGMA f s <> PosInf /\ SIGMA f s <> NegInf` >- METIS_TAC [mul_not_infty2] \\
2346     ASM_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_NOT_INFTY]) >> Rewr'
2347 >> `SIGMA f s <> PosInf /\ SIGMA f s <> NegInf`
2348      by METIS_TAC [EXTREAL_SUM_IMAGE_NOT_INFTY]
2349 >> `?c. SIGMA f s = Normal c` by PROVE_TAC [extreal_cases] >> art []
2350 >> ONCE_REWRITE_TAC [mul_comm]
2351 >> Know `SIGMA (\x. Normal c * f x) s = Normal c * SIGMA f s`
2352 >- ASM_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_CMUL]
2353 >> Rewr' >> art [pow_2]
2354QED
2355
2356(* ------------------------------------------------------------------------- *)
2357(* Supremums and infimums (these are always defined on extended reals)       *)
2358(* ------------------------------------------------------------------------- *)
2359
2360Definition extreal_sup_def:
2361    extreal_sup p =
2362       if !x. (!y. p y ==> y <= x) ==> (x = PosInf) then PosInf
2363       else (if !x. p x ==> (x = NegInf) then NegInf
2364             else Normal (sup (\r. p (Normal r))))
2365End
2366
2367Definition extreal_inf_def:
2368    extreal_inf p = -extreal_sup (IMAGE numeric_negate p)
2369End
2370
2371Overload sup = ``extreal_sup``
2372Overload inf = ``extreal_inf``
2373
2374Theorem le_sup_imp :
2375    !p x. p x ==> x <= sup p
2376Proof
2377    RW_TAC std_ss [extreal_sup_def, le_infty, le_refl]
2378 >> FULL_SIMP_TAC std_ss []
2379 >> Cases_on `x` (* 3 subgoals *)
2380 >| [ (* goal 1 (of 3) *)
2381      RW_TAC std_ss [le_infty],
2382      (* goal 2 (of 3) *)
2383      rename1 ‘y <> PosInf’ \\
2384     `y < PosInf` by (Cases_on `y` >> RW_TAC std_ss [lt_infty]) \\
2385      METIS_TAC [let_trans, lt_refl],
2386      (* goal 3 (of 3) *)
2387      RW_TAC std_ss [extreal_le_def] \\
2388      MATCH_MP_TAC REAL_IMP_LE_SUP \\
2389      reverse CONJ_TAC >- (Q.EXISTS_TAC `r` >> RW_TAC real_ss []) \\
2390      rename1 ‘y <> PosInf’ \\
2391      Cases_on `y` >| (* 3 subgoals *)
2392      [ METIS_TAC [le_infty],
2393        RW_TAC std_ss [],
2394        rename1 ‘Normal z <> PosInf’ \\
2395        Q.EXISTS_TAC `z` \\
2396        RW_TAC std_ss [] \\
2397        METIS_TAC [extreal_le_def] ] ]
2398QED
2399
2400Theorem le_sup_imp':   !p x. x IN p ==> x <= sup p
2401Proof
2402    REWRITE_TAC [IN_APP]
2403 >> PROVE_TAC [le_sup_imp]
2404QED
2405
2406Theorem sup_le :
2407    !p x. sup p <= x <=> (!y. p y ==> y <= x)
2408Proof
2409    RW_TAC std_ss [extreal_sup_def, le_infty]
2410 >- (EQ_TAC >- RW_TAC std_ss [le_infty] >> METIS_TAC [])
2411 >> FULL_SIMP_TAC std_ss []
2412 >> Cases_on `x`
2413 >- METIS_TAC [le_infty, extreal_not_infty]
2414 >- METIS_TAC [le_infty]
2415 >> rename1 ‘y <> PosInf’
2416 >> Cases_on `y`
2417 >- METIS_TAC [le_infty]
2418 >- RW_TAC std_ss []
2419 >> RW_TAC std_ss [extreal_le_def]
2420 >> EQ_TAC
2421 >- (RW_TAC std_ss [] \\
2422     Cases_on `y` >| (* 3 subgoals *)
2423     [ (* goal 1 (of 2) *)
2424       METIS_TAC [le_infty],
2425       (* goal 2 (of 3) *)
2426       METIS_TAC [le_infty, extreal_not_infty],
2427       (* goal 3 (of 3) *)
2428       RW_TAC std_ss [extreal_le_def] \\
2429       MATCH_MP_TAC REAL_LE_TRANS \\
2430       Q.EXISTS_TAC `sup (\r. p (Normal r))` \\
2431       RW_TAC std_ss [] \\
2432       MATCH_MP_TAC REAL_IMP_LE_SUP \\
2433       rename1 ‘p (Normal z)’ \\
2434       reverse CONJ_TAC >- (Q.EXISTS_TAC `z` >> RW_TAC real_ss []) \\
2435       rename1 ‘!y. p y ==> y <= Normal u’ \\
2436       Q.EXISTS_TAC `u` \\
2437       RW_TAC std_ss [] \\
2438       METIS_TAC [extreal_le_def] ])
2439 >> RW_TAC std_ss []
2440 >> MATCH_MP_TAC REAL_IMP_SUP_LE
2441 >> reverse (RW_TAC std_ss [])
2442 >- METIS_TAC [extreal_le_def]
2443 >> rename1 ‘z <> NegInf’
2444 >> Cases_on `z`
2445 >- RW_TAC std_ss []
2446 >- METIS_TAC [le_infty, extreal_not_infty]
2447 >> METIS_TAC []
2448QED
2449
2450Theorem sup_le' : (* was: Sup_le_iff *)
2451    !p x. sup p <= x <=> (!y. y IN p ==> y <= x)
2452Proof
2453    METIS_TAC [sup_le, SPECIFICATION]
2454QED
2455
2456Theorem le_sup:   !p x. x <= sup p <=> (!y. (!z. p z ==> z <= y) ==> x <= y)
2457Proof
2458    RW_TAC std_ss [extreal_sup_def,le_infty]
2459 >- (EQ_TAC >- RW_TAC std_ss [le_infty] >> METIS_TAC [le_infty, le_refl])
2460 >> FULL_SIMP_TAC std_ss []
2461 >> Cases_on `x'` (* 3 subgoals *)
2462 >| [ METIS_TAC [le_infty],
2463      METIS_TAC [le_infty],
2464      Cases_on `x` >| (* 3 subgoals *)
2465      [ METIS_TAC [le_infty],
2466        METIS_TAC [le_infty, extreal_not_infty],
2467        RW_TAC std_ss [extreal_le_def] \\
2468        EQ_TAC
2469        >- (RW_TAC std_ss [] \\
2470            Cases_on `y` >|
2471            [ METIS_TAC [le_infty],
2472              METIS_TAC [le_infty],
2473              RW_TAC std_ss [extreal_le_def] \\
2474              MATCH_MP_TAC REAL_LE_TRANS \\
2475              Q.EXISTS_TAC `sup (\r. p (Normal r))` \\
2476              RW_TAC std_ss [] \\
2477              MATCH_MP_TAC REAL_IMP_SUP_LE \\
2478              RW_TAC std_ss []
2479              >- (Cases_on `x''` >| (* 3 gubgoals *)
2480                  [ RW_TAC std_ss [],
2481                    METIS_TAC [le_infty, extreal_not_infty],
2482                    METIS_TAC [] ]) \\
2483              METIS_TAC [extreal_le_def] ]) \\
2484        RW_TAC std_ss [extreal_le_def] \\
2485       (MP_TAC o Q.SPECL [`(\r. p (Normal r))`,`r'`]) REAL_LE_SUP \\
2486        MATCH_MP_TAC (PROVE [] ``x /\ (y ==> z) ==> (x ==> y) ==> z``) \\
2487        CONJ_TAC
2488        >- (RW_TAC std_ss []
2489            >- METIS_TAC [extreal_cases, le_infty, extreal_not_infty] \\
2490            METIS_TAC [extreal_le_def]) \\
2491            RW_TAC std_ss [] \\
2492            Q.PAT_X_ASSUM `!y. (!z. p z ==> z <= y) ==> Normal r' <= y`
2493                (MATCH_MP_TAC o REWRITE_RULE [extreal_le_def] o Q.SPEC `Normal y`) \\
2494            Cases >| (* 3 subgoals *)
2495            [ METIS_TAC [le_infty],
2496              METIS_TAC [le_infty, extreal_not_infty],
2497              METIS_TAC [extreal_le_def] ] ] ]
2498QED
2499
2500Theorem le_sup':   !p x. x <= sup p <=> !y. (!z. z IN p ==> z <= y) ==> x <= y
2501Proof
2502    REWRITE_TAC [IN_APP]
2503 >> REWRITE_TAC [le_sup]
2504QED
2505
2506Theorem le_sup_imp2:   !p z. (?x. x IN p) /\ (!x. x IN p ==> z <= x) ==> z <= sup p
2507Proof
2508    RW_TAC std_ss [le_sup']
2509 >> MATCH_MP_TAC le_trans >> Q.EXISTS_TAC `x`
2510 >> CONJ_TAC >> FIRST_X_ASSUM MATCH_MP_TAC >> art []
2511QED
2512
2513Theorem sup_eq:   !p x. (sup p = x) <=>
2514                     (!y. p y ==> y <= x) /\ !y. (!z. p z ==> z <= y) ==> x <= y
2515Proof
2516    METIS_TAC [le_antisym, le_sup, sup_le]
2517QED
2518
2519Theorem sup_eq':
2520    !p x. (sup p = x) <=>
2521          (!y. y IN p ==> y <= x) /\ !y. (!z. z IN p ==> z <= y) ==> x <= y
2522Proof
2523    REWRITE_TAC [IN_APP]
2524 >> METIS_TAC [le_antisym, le_sup, sup_le]
2525QED
2526
2527Theorem sup_const:   !x. sup (\y. y = x) = x
2528Proof
2529    RW_TAC real_ss [sup_eq, le_refl]
2530QED
2531
2532Theorem sup_sing :
2533    !a:extreal. sup {a} = a
2534Proof
2535    REWRITE_TAC [METIS [EXTENSION, IN_SING, IN_DEF] ``{a} = (\x. x = a)``]
2536 >> SIMP_TAC std_ss [sup_const]
2537QED
2538
2539Theorem sup_const_alt:   !p z. (?x. p x) /\ (!x. p x ==> (x = z)) ==> (sup p = z)
2540Proof
2541    RW_TAC std_ss [sup_eq,le_refl]
2542 >> POP_ASSUM MATCH_MP_TAC
2543 >> RW_TAC std_ss []
2544QED
2545
2546Theorem sup_const_alt' :
2547    !p z. (?x. x IN p) /\ (!x. x IN p ==> (x = z)) ==> (sup p = z)
2548Proof
2549    rw [IN_APP, sup_const_alt]
2550QED
2551
2552Theorem sup_const_over_set:   !s k. s <> {} ==> (sup (IMAGE (\x. k) s) = k)
2553Proof
2554    RW_TAC std_ss [sup_eq]
2555 >- (POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION]) \\
2556     RW_TAC std_ss [IN_IMAGE] >> RW_TAC std_ss [le_refl])
2557 >> POP_ASSUM MATCH_MP_TAC
2558 >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
2559 >> RW_TAC std_ss [IN_IMAGE]
2560 >> METIS_TAC [CHOICE_DEF]
2561QED
2562
2563Theorem sup_const_over_univ:   !k. sup (IMAGE (\x. k) UNIV) = k
2564Proof
2565    GEN_TAC >> MATCH_MP_TAC sup_const_over_set
2566 >> SET_TAC []
2567QED
2568
2569Theorem sup_num:   sup (\x. ?n :num. x = &n) = PosInf
2570Proof
2571    RW_TAC std_ss [GSYM le_infty,le_sup]
2572 >> Cases_on `y`
2573 >| [ POP_ASSUM (MP_TAC o Q.SPEC `0`) \\
2574      RW_TAC real_ss [le_infty, extreal_of_num_def, extreal_not_infty],
2575      RW_TAC std_ss [le_refl],
2576      RW_TAC std_ss [le_infty, extreal_not_infty] \\
2577      MP_TAC (Q.SPEC `r` REAL_BIGNUM) \\
2578      PURE_REWRITE_TAC [real_lt] \\
2579      STRIP_TAC \\
2580      Q.PAT_X_ASSUM `!z. P z` (MP_TAC o Q.SPEC `&n`) \\
2581      RW_TAC std_ss [extreal_of_num_def] >- METIS_TAC [] \\
2582      METIS_TAC [extreal_le_def] ]
2583QED
2584
2585Theorem sup_le_sup_imp:
2586    !p q. (!x. p x ==> ?y. q y /\ x <= y) ==> sup p <= sup q
2587Proof
2588    RW_TAC std_ss [sup_le]
2589 >> METIS_TAC [le_trans, le_sup_imp]
2590QED
2591
2592Theorem sup_le_sup_imp':
2593    !p q. (!x. x IN p ==> ?y. y IN q /\ x <= y) ==> sup p <= sup q
2594Proof
2595    REWRITE_TAC [IN_APP]
2596 >> PROVE_TAC [sup_le_sup_imp]
2597QED
2598
2599(* NOTE: The type variable :num has been generalized to alpha *)
2600Theorem sup_mono :
2601    !p q. (!n. p n <= q n) ==> sup (IMAGE p UNIV) <= sup (IMAGE q UNIV)
2602Proof
2603    rw [sup_le', le_sup']
2604 >> rename1 ‘p n <= z’
2605 >> Q_TAC (TRANS_TAC le_trans) ‘q n’ >> art []
2606 >> POP_ASSUM MATCH_MP_TAC
2607 >> Q.EXISTS_TAC ‘n’ >> rw []
2608QED
2609
2610(* This is more general than "sup_mono", as f <= g in arbitrary order *)
2611Theorem sup_mono_ext : (* was: SUP_mono *)
2612    !f g A B. (!n. n IN A ==> ?m. m IN B /\ f n <= g m) ==>
2613              sup {f n | n IN A} <= sup {g n | n IN B}
2614Proof
2615  RW_TAC std_ss [] THEN MATCH_MP_TAC sup_le_sup_imp THEN
2616  GEN_TAC THEN GEN_REWR_TAC LAND_CONV [GSYM SPECIFICATION] THEN
2617  RW_TAC std_ss [GSPECIFICATION] THEN FIRST_X_ASSUM (MP_TAC o Q.SPEC `n`) THEN
2618  RW_TAC std_ss [] THEN Q.EXISTS_TAC `g m` THEN
2619  GEN_REWR_TAC LAND_CONV [GSYM SPECIFICATION] THEN ASM_SET_TAC []
2620QED
2621
2622Theorem sup_mono_subset:   !p q. p SUBSET q ==> extreal_sup p <= extreal_sup q
2623Proof
2624    rpt STRIP_TAC
2625 >> MATCH_MP_TAC sup_le_sup_imp
2626 >> rpt STRIP_TAC
2627 >> Q.EXISTS_TAC `x`
2628 >> REWRITE_TAC [le_refl]
2629 >> PROVE_TAC [SUBSET_DEF, IN_APP]
2630QED
2631
2632Theorem inf_mono_subset:   !p q. p SUBSET q ==> extreal_inf q <= extreal_inf p
2633Proof
2634    rpt STRIP_TAC
2635 >> REWRITE_TAC [extreal_inf_def, le_neg]
2636 >> MATCH_MP_TAC sup_mono_subset
2637 >> PROVE_TAC [IMAGE_SUBSET]
2638QED
2639
2640Theorem sup_suc:   !f. (!m n. m <= n ==> f m <= f n) ==>
2641                    (sup (IMAGE (\n. f (SUC n)) UNIV) = sup (IMAGE f UNIV))
2642Proof
2643    RW_TAC std_ss [sup_eq, sup_le, le_sup]
2644 >- (POP_ASSUM MATCH_MP_TAC \\
2645     ONCE_REWRITE_TAC [GSYM SPECIFICATION] \\
2646     POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION]) \\
2647     RW_TAC std_ss [IN_IMAGE, IN_UNIV] \\
2648     METIS_TAC [])
2649 >> POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
2650 >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
2651 >> Cases_on `x`
2652 >- (MATCH_MP_TAC le_trans \\
2653     Q.EXISTS_TAC `f 1` \\
2654     RW_TAC std_ss [] \\
2655     POP_ASSUM MATCH_MP_TAC \\
2656     ONCE_REWRITE_TAC [GSYM SPECIFICATION] \\
2657     RW_TAC std_ss [IN_IMAGE, IN_UNIV] \\
2658    `SUC 0 = 1` by RW_TAC real_ss [] \\
2659     METIS_TAC [])
2660 >> POP_ASSUM MATCH_MP_TAC
2661 >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
2662 >> RW_TAC std_ss [IN_IMAGE, IN_UNIV]
2663 >> METIS_TAC []
2664QED
2665
2666Theorem sup_shift:
2667    !f :num -> extreal.
2668      (!m n. m <= n ==> f m <= f n) ==>
2669       !N. (sup (IMAGE (\n. f (n + N)) UNIV) = sup (IMAGE f UNIV))
2670Proof
2671    GEN_TAC >> DISCH_TAC
2672 >> Induct_on `N` >- RW_TAC arith_ss [ETA_THM]
2673 >> Know `(\n. f (n + SUC N)) = (\n. (\n. f (n + N)) (SUC n))`
2674 >- (FUN_EQ_TAC >> RW_TAC arith_ss [ADD_CLAUSES]) >> Rewr'
2675 >> POP_ASSUM (REWRITE_TAC o wrap o SYM)
2676 >> MATCH_MP_TAC sup_suc
2677 >> RW_TAC std_ss []
2678QED
2679
2680Theorem sup_seq :
2681    !f l. mono_increasing f ==>
2682         ((f --> l) <=> (sup (IMAGE (\n. Normal (f n)) UNIV) = Normal l))
2683Proof
2684     RW_TAC std_ss []
2685  >> EQ_TAC
2686  >- (RW_TAC std_ss [sup_eq]
2687      >- (POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
2688          >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
2689          >> RW_TAC std_ss [extreal_le_def]
2690          >> METIS_TAC [mono_increasing_suc, SEQ_MONO_LE, ADD1])
2691      >> `!n. Normal (f n) <= y`
2692            by (RW_TAC std_ss []
2693                >> POP_ASSUM MATCH_MP_TAC
2694                >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
2695                >> RW_TAC std_ss [IN_IMAGE, IN_UNIV]
2696                >> METIS_TAC [])
2697      >> Cases_on `y`
2698      >| [METIS_TAC [le_infty, extreal_not_infty],
2699          METIS_TAC [le_infty],
2700          METIS_TAC [SEQ_LE_IMP_LIM_LE,extreal_le_def]])
2701  >> RW_TAC std_ss [extreal_sup_def]
2702  >> `(\r. IMAGE (\n. Normal (f n)) UNIV (Normal r)) = IMAGE f UNIV`
2703       by (RW_TAC std_ss [EXTENSION, IN_ABS, IN_IMAGE, IN_UNIV]
2704           >> EQ_TAC
2705           >> (RW_TAC std_ss []
2706               >> POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
2707               >> RW_TAC std_ss [IN_IMAGE, IN_UNIV])
2708           >> RW_TAC std_ss []
2709           >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
2710           >> RW_TAC std_ss [IN_UNIV, IN_IMAGE]
2711           >> METIS_TAC [])
2712  >> POP_ORW
2713  >> FULL_SIMP_TAC std_ss []
2714  >> `!n. Normal (f n) <= x`
2715       by (RW_TAC std_ss []
2716           >> Q.PAT_X_ASSUM `!y. P` MATCH_MP_TAC
2717           >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
2718           >> RW_TAC std_ss [IN_UNIV,IN_IMAGE]
2719           >> METIS_TAC [])
2720  >> `x <> NegInf` by METIS_TAC [lt_infty,extreal_not_infty,lte_trans]
2721  >> `?z. x = Normal z` by METIS_TAC [extreal_cases]
2722  >> `!n. f n <= z` by FULL_SIMP_TAC std_ss [extreal_le_def]
2723  >> RW_TAC std_ss [SEQ]
2724  >> (MP_TAC o Q.ISPECL [`IMAGE (f:num->real) UNIV`,`e:real/2`]) SUP_EPSILON
2725  >> SIMP_TAC std_ss [REAL_LT_HALF1]
2726  >> `!y x z. IMAGE f UNIV x <=> x IN IMAGE f UNIV` by RW_TAC std_ss [IN_DEF]
2727  >> POP_ORW
2728  >> Know `(?z. !x. x IN IMAGE f UNIV ==> x <= z)`
2729  >- (Q.EXISTS_TAC `z`
2730      >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
2731      >> METIS_TAC [])
2732  >> `?x. x IN IMAGE f UNIV` by RW_TAC std_ss [IN_UNIV,IN_IMAGE]
2733  >> RW_TAC std_ss []
2734  >> `?x. x IN IMAGE f univ(:num) /\
2735          sup (IMAGE f univ(:num)) <= x + e / 2` by METIS_TAC []
2736  >> RW_TAC std_ss [GSYM ABS_BETWEEN, GREATER_EQ]
2737  >> FULL_SIMP_TAC std_ss [IN_IMAGE,IN_UNIV]
2738  >> rename1 ‘x2 = f x6’
2739  >> Q.EXISTS_TAC ‘x6’
2740  >> RW_TAC std_ss [REAL_LT_SUB_RADD]
2741  >- (MATCH_MP_TAC REAL_LET_TRANS >> Q.EXISTS_TAC ‘f x6 + e / 2’
2742      >> RW_TAC std_ss [] >> MATCH_MP_TAC REAL_LET_TRANS
2743      >> Q.EXISTS_TAC `f n + e / 2`
2744      >> reverse CONJ_TAC >- METIS_TAC [REAL_LET_ADD2,REAL_LT_HALF2,REAL_LE_REFL]
2745      >> RW_TAC std_ss [REAL_LE_RADD]
2746      >> METIS_TAC [mono_increasing_def])
2747   >> MATCH_MP_TAC REAL_LET_TRANS >> Q.EXISTS_TAC `sup (IMAGE f UNIV)`
2748   >> RW_TAC std_ss [REAL_LT_ADDR]
2749   >> Suff `!y. (\y. y IN IMAGE f UNIV) y ==> y <= sup (IMAGE f UNIV)`
2750   >- METIS_TAC [IN_IMAGE, IN_UNIV]
2751   >> SIMP_TAC std_ss [IN_DEF]
2752   >> MATCH_MP_TAC REAL_SUP_UBOUND_LE
2753   >> `!y x z. IMAGE f UNIV x <=> x IN IMAGE f UNIV` by RW_TAC std_ss [IN_DEF]
2754   >> POP_ORW
2755   >> RW_TAC std_ss [IN_IMAGE, IN_UNIV]
2756   >> Q.EXISTS_TAC `z'`
2757   >> RW_TAC std_ss []
2758QED
2759
2760Theorem sup_lt_infty:   !p. (sup p < PosInf) ==> (!x. p x ==> x < PosInf)
2761Proof
2762    METIS_TAC [le_sup_imp,let_trans]
2763QED
2764
2765Theorem sup_max:   !p z. p z /\ (!x. p x ==> x <= z) ==> (sup p = z)
2766Proof
2767    RW_TAC std_ss [sup_eq]
2768QED
2769
2770Theorem sup_add_mono :
2771    !f g. (!n. 0 <= f n) /\ (!n. f n <= f (SUC n)) /\
2772          (!n. 0 <= g n) /\ (!n. g n <= g (SUC n)) ==>
2773          sup (IMAGE (\n. f n + g n) UNIV) =
2774          sup (IMAGE f UNIV) + sup (IMAGE g UNIV)
2775Proof
2776    rw [sup_eq']
2777 >- (MATCH_MP_TAC le_add2 >> rw [le_sup'] \\
2778     POP_ASSUM MATCH_MP_TAC >> Q.EXISTS_TAC ‘n’ >> rw [])
2779 >> Cases_on ‘y = PosInf’ >- rw [le_infty]
2780 >> Cases_on ‘sup (IMAGE f UNIV) = 0’
2781 >- (rw [sup_le'] >> fs [sup_eq'] \\
2782    ‘!n. f n = 0’
2783       by METIS_TAC [EXTENSION, IN_IMAGE, IN_UNIV, SPECIFICATION, le_antisym] \\
2784     Q.PAT_X_ASSUM ‘!z. Q z ==> z <= y’ MATCH_MP_TAC \\
2785     RW_TAC std_ss [add_lzero] \\
2786     METIS_TAC [])
2787 >> Cases_on ‘sup (IMAGE g UNIV) = 0’
2788 >- (rw [sup_le'] >> fs [sup_eq'] \\
2789    ‘!n. g n = 0’
2790       by METIS_TAC [EXTENSION, IN_IMAGE, IN_UNIV, SPECIFICATION, le_antisym] \\
2791     Q.PAT_X_ASSUM ‘!z. Q z ==> z <= y’ MATCH_MP_TAC \\
2792     RW_TAC std_ss [add_rzero] \\
2793     METIS_TAC [])
2794 >> Know ‘!n. f n + g n <= y’
2795 >- (Q.X_GEN_TAC ‘n’ \\
2796     Q.PAT_X_ASSUM ‘!z. Q z ==> z <= y’ MATCH_MP_TAC \\
2797     Q.EXISTS_TAC ‘n’ >> rw [])
2798 >> DISCH_TAC
2799 >> ‘!n. f n <= f n + g n’ by METIS_TAC [add_rzero, le_add2, le_refl]
2800 >> ‘!n. g n <= f n + g n’ by METIS_TAC [add_lzero, le_add2, le_refl]
2801 >> ‘!n. f n <> PosInf’ by METIS_TAC [le_trans, lt_infty, let_trans]
2802 >> ‘!n. g n <> PosInf’ by METIS_TAC [le_trans, lt_infty, let_trans]
2803 >> ‘!n. f n <> NegInf’ by rw [pos_not_neginf]
2804 >> ‘!n. g n <> NegInf’ by rw [pos_not_neginf]
2805 >> MATCH_MP_TAC le_trans
2806 (* stage work *)
2807 >> Q.EXISTS_TAC ‘sup (IMAGE (\n. (sup (IMAGE f UNIV)) + g n) UNIV)’
2808 >> reverse (rw [sup_le'])
2809 >- (Suff ‘sup (IMAGE f UNIV) <= y - g n’ >- RW_TAC std_ss [le_sub_eq] \\
2810     rw [sup_le'] \\
2811     MATCH_MP_TAC le_sub_imp >> rw [] \\
2812     Cases_on ‘x <= n’
2813     >- (MATCH_MP_TAC le_trans \\
2814         Q.EXISTS_TAC ‘f n + g n’ \\
2815         CONJ_TAC
2816         >- METIS_TAC [le_radd, ext_mono_increasing_def, ext_mono_increasing_suc] \\
2817         Q.PAT_X_ASSUM ‘!z. Q z ==> z <= y’ MATCH_MP_TAC \\
2818         Q.EXISTS_TAC ‘n’ >> rw []) \\
2819     MATCH_MP_TAC le_trans \\
2820     Q.EXISTS_TAC ‘f x + g x’ \\
2821     CONJ_TAC
2822     >- METIS_TAC [le_ladd, ext_mono_increasing_def, ext_mono_increasing_suc,
2823                   le_refl, NOT_LEQ, le_trans] \\
2824     Q.PAT_X_ASSUM ‘!z. Q z ==> z <= y’ MATCH_MP_TAC \\
2825     Q.EXISTS_TAC ‘x’ >> rw [])
2826 >> Know ‘sup (IMAGE f UNIV) <> NegInf’
2827 >- (rw [sup_eq', le_infty] \\
2828     Q.EXISTS_TAC ‘f 0’ >> rw [] \\
2829     Q.EXISTS_TAC ‘0’ >> rw [])
2830 >> DISCH_TAC
2831 >> Know ‘sup (IMAGE g UNIV) <> NegInf’
2832 >- (rw [sup_eq', le_infty] \\
2833     Q.EXISTS_TAC ‘g 0’ >> rw [] \\
2834     Q.EXISTS_TAC ‘0’ >> rw [])
2835 >> DISCH_TAC
2836 >> Cases_on ‘sup (IMAGE f UNIV) = PosInf’
2837 >- (Know ‘sup (IMAGE (\n. sup (IMAGE f UNIV) + g n) UNIV) = PosInf’
2838     >- (POP_ORW \\
2839         qmatch_abbrev_tac ‘sup s = PosInf’ \\
2840         Suff ‘s = \y. y = PosInf’ >- rw [sup_const] \\
2841         rw [Abbr ‘s’, Once EXTENSION] \\
2842         EQ_TAC >> rw []
2843         >- (‘?r. g n = Normal r’ by METIS_TAC [extreal_cases] \\
2844             rw [extreal_add_def]) \\
2845         Q.EXISTS_TAC ‘0’ \\
2846        ‘?r. g 0 = Normal r’ by METIS_TAC [extreal_cases] \\
2847         rw [extreal_add_def]) >> Rewr' \\
2848     METIS_TAC [le_infty])
2849 >> RW_TAC std_ss [add_comm]
2850 >> Suff ‘sup (IMAGE g UNIV) <=
2851          sup (IMAGE (\n. g n + sup (IMAGE f UNIV)) UNIV) - sup (IMAGE f UNIV)’
2852 >- METIS_TAC [le_sub_eq, add_comm]
2853 >> rw [sup_le']
2854 >> MATCH_MP_TAC le_sub_imp
2855 >> rw [le_sup']
2856 >> POP_ASSUM MATCH_MP_TAC
2857 >> Q.EXISTS_TAC ‘x’ >> rw []
2858QED
2859
2860Theorem sup_sum_mono:
2861    !f s. FINITE s /\ (!i:num. i IN s ==> (!n. 0 <= f i n)) /\
2862          (!i:num. i IN s ==> (!n. f i n <= f i (SUC n))) ==>
2863          (sup (IMAGE (\n. SIGMA (\i:num. f i n) s) UNIV) =
2864           SIGMA (\i:num. sup (IMAGE (f i) UNIV)) s)
2865Proof
2866  Suff `!s. FINITE s ==> (\s. !f. (!i:num. i IN s ==> (!n. 0 <= f i n)) /\
2867                         (!i:num. i IN s ==> (!n. f i n <= f i (SUC n))) ==>
2868                      (sup (IMAGE (\n. SIGMA (\i:num. f i n) s) UNIV) =
2869                       SIGMA (\i:num. sup (IMAGE (f i) UNIV)) s)) s`
2870  >- RW_TAC std_ss []
2871  >> MATCH_MP_TAC FINITE_INDUCT
2872  >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_EMPTY,UNIV_NOT_EMPTY,sup_const_over_set]
2873  >> `s DELETE e = s` by METIS_TAC [DELETE_NON_ELEMENT]
2874  >> `!n. SIGMA (\i. f i n) (e INSERT s) =
2875          (\i. f i n) e + SIGMA (\i. f i n) (s DELETE e)`
2876        by (STRIP_TAC
2877            >> (MATCH_MP_TAC o Q.SPEC `e` o UNDISCH o Q.SPECL [`(\i. f i n)`,`s`] o
2878                INST_TYPE [alpha |-> ``:num``]) EXTREAL_SUM_IMAGE_PROPERTY
2879            >> METIS_TAC [IN_INSERT, le_infty, lt_infty, extreal_of_num_def,
2880                          extreal_not_infty])
2881  >> RW_TAC std_ss []
2882  >> `!n. !x. x IN e INSERT s ==> f x n <> NegInf`
2883        by METIS_TAC [IN_INSERT, le_infty, lt_infty, extreal_of_num_def,
2884                      extreal_not_infty]
2885  >> `sup (IMAGE (\n. f e n + (\n. SIGMA (\i. f i n) s) n) UNIV) =
2886      sup (IMAGE (f e) UNIV) + sup (IMAGE (\n. SIGMA (\i. f i n) s) UNIV)`
2887        by ((MATCH_MP_TAC o Q.SPECL [`f e`, `(\n. SIGMA (\i. f i n) s)`] o
2888             INST_TYPE [alpha |-> ``:num``]) sup_add_mono
2889            >> FULL_SIMP_TAC std_ss [IN_INSERT,EXTREAL_SUM_IMAGE_POS]
2890            >> RW_TAC std_ss []
2891            >> (MATCH_MP_TAC o UNDISCH o Q.SPEC `s` o INST_TYPE [alpha |-> ``:num``])
2892                  EXTREAL_SUM_IMAGE_MONO
2893            >> FULL_SIMP_TAC std_ss [IN_INSERT])
2894  >> FULL_SIMP_TAC std_ss []
2895  >> `!i. i IN e INSERT s ==> 0 <= (\i. sup (IMAGE (f i) univ(:num))) i`
2896      by (RW_TAC std_ss [le_sup]
2897          >> MATCH_MP_TAC le_trans
2898          >> Q.EXISTS_TAC `f i 0`
2899          >> FULL_SIMP_TAC std_ss []
2900          >> POP_ASSUM MATCH_MP_TAC
2901          >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
2902          >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
2903          >> METIS_TAC [])
2904  >> `!i. i IN e INSERT s ==> (\i. sup (IMAGE (f i) univ(:num))) i <> NegInf`
2905      by METIS_TAC [IN_INSERT,le_infty,lt_infty,extreal_of_num_def,extreal_not_infty]
2906  >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY]
2907  >> FULL_SIMP_TAC std_ss [IN_INSERT]
2908QED
2909
2910Theorem sup_le_mono:
2911    !f z. (!n. f n <= f (SUC n)) /\ z < sup (IMAGE f UNIV) ==> ?n. z <= f n
2912Proof
2913  RW_TAC std_ss []
2914  >> SPOSE_NOT_THEN ASSUME_TAC
2915  >> FULL_SIMP_TAC std_ss [GSYM extreal_lt_def]
2916  >> `!x. x IN (IMAGE f UNIV) ==> x <= z`
2917       by METIS_TAC [IN_IMAGE,IN_UNIV,lt_imp_le]
2918  >> METIS_TAC [sup_le,SPECIFICATION,extreal_lt_def]
2919QED
2920
2921Theorem sup_cmul_general :
2922    !f c J. 0 <= c /\ (J :'index set) <> {} ==>
2923            sup (IMAGE (\n. Normal c * f n) J) = Normal c * sup (IMAGE f J)
2924Proof
2925    RW_TAC std_ss []
2926 >> Cases_on ‘c = 0’ >- simp [sup_const_over_set, normal_0]
2927 >> ‘0 < c’ by PROVE_TAC [REAL_LT_LE]
2928 >> rw [sup_eq']
2929 >- (Cases_on ‘sup (IMAGE f J) = PosInf’
2930     >- simp [extreal_mul_def, le_infty] \\
2931     Cases_on ‘f n = NegInf’
2932     >- simp [extreal_mul_def, le_infty] \\
2933     MATCH_MP_TAC le_lmul_imp >> simp [extreal_of_num_def, extreal_le_eq] \\
2934     MATCH_MP_TAC le_sup_imp' >> simp [])
2935 >> Know ‘!n. n IN J ==> Normal c * f n <= y’
2936 >- (rw [] \\
2937     FIRST_X_ASSUM MATCH_MP_TAC \\
2938     Q.EXISTS_TAC ‘n’ >> simp [])
2939 >> DISCH_TAC
2940 >> Know ‘!n. n IN J ==> f n <= y / Normal c’
2941 >- (rpt STRIP_TAC \\
2942     Know ‘f n <= y / Normal c <=> f n * Normal c <= y’
2943     >- (SYM_TAC \\
2944         MATCH_MP_TAC le_rdiv >> art []) >> Rewr' \\
2945     ONCE_REWRITE_TAC [mul_comm] \\
2946     FIRST_X_ASSUM MATCH_MP_TAC >> art [])
2947 >> DISCH_TAC
2948 >> ONCE_REWRITE_TAC [mul_comm]
2949 >> Know ‘sup (IMAGE f J) * Normal c <= y <=>
2950          sup (IMAGE f J) <= y / Normal c’
2951 >- (MATCH_MP_TAC le_rdiv >> art [])
2952 >> Rewr'
2953 >> rw [sup_le']
2954 >> FIRST_X_ASSUM MATCH_MP_TAC >> art []
2955QED
2956
2957(* |- !f c.
2958        0 <= c ==>
2959        sup (IMAGE (\n. Normal c * f n) univ(:'a)) =
2960        Normal c * sup (IMAGE f univ(:'a))
2961 *)
2962Theorem sup_cmul =
2963        sup_cmul_general |> INST_TYPE [“:'index” |-> alpha]
2964                         |> Q.SPECL [‘f’, ‘c’, ‘UNIV’] |> SRULE [] |> GEN_ALL
2965
2966(* Another version of `sup_cmul`: f is positive, c can be PosInf *)
2967Theorem sup_cmult :
2968    !f c. 0 <= c /\ (!n. 0 <= f n) ==>
2969         (sup (IMAGE (\n. c * f n) UNIV) = c * sup (IMAGE f UNIV))
2970Proof
2971    rpt STRIP_TAC
2972 >> Cases_on `c <> PosInf`
2973 >- (IMP_RES_TAC pos_not_neginf \\
2974    `?r. c = Normal r` by PROVE_TAC [extreal_cases] >> art [] \\
2975     MATCH_MP_TAC sup_cmul \\
2976     REWRITE_TAC [GSYM extreal_le_eq, GSYM extreal_of_num_def] \\
2977     PROVE_TAC [])
2978 >> fs []
2979 >> Know `0 <= sup (IMAGE f univ(:'a))`
2980 >- (RW_TAC std_ss [le_sup', IN_IMAGE, IN_UNIV] \\
2981     MATCH_MP_TAC le_trans \\
2982     Q.EXISTS_TAC `f ARB` >> RW_TAC std_ss [] \\
2983     FIRST_X_ASSUM MATCH_MP_TAC >> PROVE_TAC [])
2984 >> DISCH_THEN (STRIP_ASSUME_TAC o (REWRITE_RULE [le_lt, Once DISJ_SYM]))
2985 >- (FIRST_ASSUM (REWRITE_TAC o wrap o SYM) >> REWRITE_TAC [mul_rzero] \\
2986     Know `!n. f n = 0`
2987     >- (POP_ASSUM (MP_TAC o SYM) \\
2988         RW_TAC std_ss [sup_eq', IN_IMAGE, IN_UNIV] \\
2989         RW_TAC std_ss [GSYM le_antisym] \\
2990         FIRST_X_ASSUM MATCH_MP_TAC >> Q.EXISTS_TAC `n` >> REWRITE_TAC []) >> Rewr' \\
2991     REWRITE_TAC [mul_rzero] \\
2992     MATCH_MP_TAC sup_const_over_set >> SET_TAC [])
2993 >> RW_TAC std_ss [mul_lposinf]
2994 >> Know `?n. 0 < f n`
2995 >- (CCONTR_TAC >> fs [] \\
2996     POP_ASSUM (ASSUME_TAC o (REWRITE_RULE [extreal_lt_def])) \\
2997    `!n. f n = 0` by PROVE_TAC [le_antisym] \\
2998    `f = \n. 0` by PROVE_TAC [] \\
2999     ASSUME_TAC (Q.SPEC `0` sup_const_over_univ) \\
3000    `(\x. 0) = f` by METIS_TAC [] >> fs [lt_refl]) >> STRIP_TAC
3001 >> RW_TAC std_ss [sup_eq', IN_IMAGE, IN_UNIV, le_infty]
3002 >> RW_TAC std_ss [GSYM le_antisym, Once le_infty]
3003 >> FIRST_X_ASSUM MATCH_MP_TAC
3004 >> Q.EXISTS_TAC `n`
3005 >> MATCH_MP_TAC EQ_SYM
3006 >> MATCH_MP_TAC mul_lposinf >> art []
3007QED
3008
3009Theorem sup_lt:   !P y. (?x. P x /\ y < x) <=> y < sup P
3010Proof
3011  RW_TAC std_ss []
3012  >> EQ_TAC >- METIS_TAC [le_sup_imp,lte_trans]
3013  >> RW_TAC std_ss []
3014  >> SPOSE_NOT_THEN STRIP_ASSUME_TAC
3015  >> METIS_TAC [sup_le,extreal_lt_def]
3016QED
3017
3018Theorem lt_sup : (* was: less_Sup_iff *)
3019    !a s. a < sup s <=> ?x. x IN s /\ a < x
3020Proof
3021    METIS_TAC [sup_lt, SPECIFICATION]
3022QED
3023
3024Theorem sup_lt':   !P y. (?x. x IN P /\ y < x) <=> y < sup P
3025Proof
3026    RW_TAC std_ss [IN_APP]
3027 >> REWRITE_TAC [sup_lt]
3028QED
3029
3030(* cf. realTheory.SUP_LT_EPSILON *)
3031Theorem sup_lt_epsilon :
3032    !P e. 0 < e /\ (?x. P x /\ x <> NegInf) /\ sup P <> PosInf ==>
3033          ?x. P x /\ sup P < x + e
3034Proof
3035    RW_TAC std_ss []
3036 >> Cases_on ‘e = PosInf’
3037 >- (Q.EXISTS_TAC ‘x’ >> RW_TAC std_ss [] \\
3038     METIS_TAC [extreal_add_def, lt_infty, extreal_cases])
3039 >> ‘e <> NegInf’ by METIS_TAC [le_sup_imp, lt_infty, lte_trans,
3040                                extreal_of_num_def, extreal_not_infty]
3041 >> ‘sup P <> NegInf’ by METIS_TAC [le_sup_imp, lt_infty, lte_trans]
3042 >> ‘sup P < sup P + e’
3043      by (Cases_on ‘sup P’ >> Cases_on ‘e’ \\
3044          RW_TAC std_ss [extreal_cases, extreal_add_def, extreal_lt_def,
3045                         extreal_le_def, GSYM real_lt] \\
3046          METIS_TAC [REAL_LT_ADDR, extreal_lt_def, extreal_le_def,
3047                     extreal_of_num_def, real_lt])
3048 >> ‘sup P - e < sup P’ by METIS_TAC [sub_lt_imp]
3049 >> ‘?x. P x /\ sup P - e < x’ by METIS_TAC [sup_lt]
3050 >> rename1 ‘P y’
3051 >> Q.EXISTS_TAC ‘y’
3052 >> RW_TAC std_ss []
3053 >> ‘y <> PosInf’ by METIS_TAC [le_sup_imp, let_trans, lt_infty]
3054 >> ‘?r. sup P = Normal r’ by METIS_TAC [extreal_cases]
3055 >> ‘?E. e = Normal E’ by METIS_TAC [extreal_cases]
3056 >> FULL_SIMP_TAC std_ss [extreal_sub_def]
3057 >> ‘y <> NegInf’ by METIS_TAC [lt_infty, extreal_not_infty, lt_trans]
3058 >> ‘?z. y = Normal z’ by METIS_TAC [extreal_cases]
3059 >> FULL_SIMP_TAC std_ss [extreal_add_def, extreal_lt_def, extreal_le_def,
3060                          GSYM real_lt, REAL_LT_SUB_RADD]
3061QED
3062
3063Theorem sup_lt_epsilon' :
3064    !P e. 0 < e /\ (?x. x IN P /\ x <> NegInf) /\ (sup P <> PosInf) ==>
3065          ?x. x IN P /\ sup P < x + e
3066Proof
3067    REWRITE_TAC [IN_APP, sup_lt_epsilon]
3068QED
3069
3070Theorem inf_le_imp:   !p x. p x ==> inf p <= x
3071Proof
3072  RW_TAC std_ss [extreal_inf_def,Once (GSYM le_neg),neg_neg,le_sup]
3073  >> POP_ASSUM MATCH_MP_TAC
3074  >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
3075  >> RW_TAC std_ss [IN_IMAGE]
3076  >> METIS_TAC [SPECIFICATION]
3077QED
3078
3079Theorem inf_le_imp':   !p x. x IN p ==> inf p <= x
3080Proof
3081    REWRITE_TAC [IN_APP]
3082 >> rpt STRIP_TAC
3083 >> MATCH_MP_TAC inf_le_imp >> art []
3084QED
3085
3086Theorem le_inf:
3087     !p x. x <= inf p <=> (!y. p y ==> x <= y)
3088Proof
3089  RW_TAC std_ss [extreal_inf_def,Once (GSYM le_neg),neg_neg,sup_le]
3090  >> EQ_TAC
3091  >- (RW_TAC std_ss []
3092      >> `-y IN (IMAGE numeric_negate p)`
3093           by (RW_TAC std_ss [IN_IMAGE]
3094               >> METIS_TAC [SPECIFICATION])
3095      >> METIS_TAC [le_neg,SPECIFICATION])
3096  >> RW_TAC std_ss []
3097  >> POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
3098  >> RW_TAC std_ss [IN_IMAGE]
3099  >> METIS_TAC [le_neg,SPECIFICATION]
3100QED
3101
3102Theorem le_inf' :
3103    !p x. x <= inf p <=> (!y. y IN p ==> x <= y)
3104Proof
3105    REWRITE_TAC [IN_APP, le_inf]
3106QED
3107
3108Theorem inf_le:
3109     !p x. (inf p <= x) <=> (!y. (!z. p z ==> y <= z) ==> y <= x)
3110Proof
3111  RW_TAC std_ss [extreal_inf_def,Once (GSYM le_neg),neg_neg,le_sup]
3112  >> EQ_TAC
3113  >- (RW_TAC std_ss []
3114      >> `!z. IMAGE numeric_negate p z ==> y <= -z`
3115            by (RW_TAC std_ss []
3116                >> POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
3117                >> RW_TAC std_ss [IN_IMAGE]
3118                >> METIS_TAC [neg_neg,SPECIFICATION])
3119      >> `!z. IMAGE numeric_negate p z ==> z <= -y`
3120           by METIS_TAC [le_neg,neg_neg]
3121      >> `(!z. IMAGE numeric_negate p z ==> z <= -y) ==> -x <= -y`
3122           by METIS_TAC []
3123      >> METIS_TAC [le_neg])
3124  >> RW_TAC std_ss []
3125  >> `!z. p z ==> -z <= y`
3126       by (RW_TAC std_ss []
3127           >> Q.PAT_X_ASSUM `!z. IMAGE numeric_negate p z ==> z <= y` MATCH_MP_TAC
3128           >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
3129           >> RW_TAC std_ss [IN_IMAGE]
3130           >> METIS_TAC [SPECIFICATION])
3131  >> `!z. p z ==> -y <= z` by METIS_TAC [le_neg,neg_neg]
3132  >> METIS_TAC [le_neg,neg_neg]
3133QED
3134
3135Theorem inf_le' :
3136    !p x. (extreal_inf p <= x) <=>
3137          (!y. (!z. z IN p ==> y <= z) ==> y <= x)
3138Proof
3139    REWRITE_TAC [IN_APP, inf_le]
3140QED
3141
3142Theorem inf_mono :
3143    !p q. (!n:num. p n <= q n) ==> inf (IMAGE p UNIV) <= inf (IMAGE q UNIV)
3144Proof
3145    rw [inf_le', le_inf']
3146 >> MATCH_MP_TAC le_trans
3147 >> Q.EXISTS_TAC `p x` >> art []
3148 >> POP_ASSUM MATCH_MP_TAC
3149 >> Q.EXISTS_TAC ‘x’ >> rw []
3150QED
3151
3152Theorem inf_eq:   !p x. (extreal_inf p = x) <=>
3153                       (!y. p y ==> x <= y) /\
3154                       (!y. (!z. p z ==> y <= z) ==> y <= x)
3155Proof
3156  METIS_TAC [le_antisym,inf_le,le_inf]
3157QED
3158
3159Theorem inf_eq' :
3160    !p x. (extreal_inf p = x) <=>
3161          (!y. y IN p ==> x <= y) /\
3162          (!y. (!z. z IN p ==> y <= z) ==> y <= x)
3163Proof
3164    REWRITE_TAC [IN_APP, inf_eq]
3165QED
3166
3167Theorem inf_const:   !x. extreal_inf (\y. y = x) = x
3168Proof
3169    RW_TAC real_ss [inf_eq, le_refl]
3170QED
3171
3172Theorem inf_sing :
3173    !a:extreal. inf {a} = a
3174Proof
3175    REWRITE_TAC [METIS [EXTENSION, IN_SING, IN_DEF] ``{a} = (\x. x = a)``]
3176 >> SIMP_TAC std_ss [inf_const]
3177QED
3178
3179Theorem inf_const_alt:   !p z. (?x. p x) /\ (!x. p x ==> (x = z)) ==> (inf p = z)
3180Proof
3181  RW_TAC std_ss [inf_eq,le_refl]
3182  >> POP_ASSUM MATCH_MP_TAC
3183  >> RW_TAC std_ss []
3184QED
3185
3186Theorem inf_const_alt' :
3187    !p z. (?x. x IN p) /\ (!x. x IN p ==> (x = z)) ==> (inf p = z)
3188Proof
3189    rw [IN_APP, inf_const_alt]
3190QED
3191
3192Theorem inf_const_over_set:   !s k. s <> {} ==> (inf (IMAGE (\x. k) s) = k)
3193Proof
3194  RW_TAC std_ss [inf_eq]
3195  >- (POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
3196      >> RW_TAC std_ss [IN_IMAGE] >> RW_TAC std_ss [le_refl])
3197  >> POP_ASSUM MATCH_MP_TAC
3198  >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
3199  >> RW_TAC std_ss [IN_IMAGE]
3200  >> METIS_TAC [CHOICE_DEF]
3201QED
3202
3203Theorem inf_suc:
3204     !f. (!m n. m <= n ==> f n <= f m) ==>
3205     (inf (IMAGE (\n. f (SUC n)) UNIV) = inf (IMAGE f UNIV))
3206Proof
3207  RW_TAC std_ss [inf_eq,inf_le,le_inf]
3208  >- (POP_ASSUM MATCH_MP_TAC
3209      >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
3210      >> POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
3211      >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
3212      >> METIS_TAC [])
3213  >> POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
3214  >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
3215  >> MATCH_MP_TAC le_trans
3216  >> Q.EXISTS_TAC `f (SUC x)`
3217  >> RW_TAC real_ss []
3218  >> POP_ASSUM MATCH_MP_TAC
3219  >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
3220  >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
3221  >> METIS_TAC []
3222QED
3223
3224Theorem inf_seq :
3225    !f l. mono_decreasing f ==>
3226         ((f --> l) <=> (inf (IMAGE (\n. Normal (f n)) UNIV) = Normal l))
3227Proof
3228     RW_TAC std_ss []
3229  >> EQ_TAC
3230  >- (RW_TAC std_ss [inf_eq]
3231      >- (POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
3232          >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
3233          >> RW_TAC std_ss [extreal_le_def]
3234          >> METIS_TAC [mono_decreasing_suc,SEQ_LE_MONO,ADD1])
3235      >> `!n. y <= Normal (f n)`
3236            by (RW_TAC std_ss []
3237                >> POP_ASSUM MATCH_MP_TAC
3238                >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
3239                >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
3240                >> METIS_TAC [])
3241      >> Cases_on `y`
3242      >| [METIS_TAC [le_infty],
3243          METIS_TAC [le_infty,extreal_not_infty],
3244          METIS_TAC [LE_SEQ_IMP_LE_LIM,extreal_le_def]])
3245  >> RW_TAC std_ss [extreal_inf_def,extreal_sup_def,extreal_ainv_def,extreal_not_infty]
3246  >> `(\r. IMAGE numeric_negate (IMAGE (\n. Normal (f n)) univ(:num)) (Normal r)) =
3247       IMAGE (\n. - f n) UNIV`
3248       by (RW_TAC std_ss [EXTENSION,IN_ABS,IN_IMAGE,IN_UNIV]
3249           >> EQ_TAC
3250           >- (RW_TAC std_ss []
3251               >> POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
3252               >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
3253               >> METIS_TAC [extreal_ainv_def,extreal_11])
3254           >> RW_TAC std_ss []
3255           >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
3256           >> RW_TAC std_ss [IN_UNIV,IN_IMAGE]
3257           >> METIS_TAC [extreal_ainv_def,extreal_11])
3258  >> POP_ORW
3259  >> FULL_SIMP_TAC std_ss []
3260  >> `!n. -Normal (f n) <= x`
3261       by (RW_TAC std_ss []
3262           >> Q.PAT_X_ASSUM `!y. P` MATCH_MP_TAC
3263           >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
3264           >> RW_TAC std_ss [IN_UNIV,IN_IMAGE]
3265           >> METIS_TAC [])
3266  >> `x <> NegInf` by METIS_TAC [lt_infty,extreal_not_infty,lte_trans]
3267  >> `?z. x = Normal z` by METIS_TAC [extreal_cases]
3268  >> `!n. -(f n) <= z` by METIS_TAC [extreal_le_def,extreal_ainv_def]
3269  >> Suff `(\n. -f n) --> sup (IMAGE (\n. -f n) univ(:num))`
3270  >- METIS_TAC [SEQ_NEG,REAL_NEG_NEG]
3271  >> `mono_increasing (\n. -f n)`
3272        by FULL_SIMP_TAC std_ss [mono_increasing_def,mono_decreasing_def,REAL_LE_NEG]
3273  >> Suff `?r. (\n. -f n) --> r`
3274  >- METIS_TAC [mono_increasing_converges_to_sup]
3275  >> RW_TAC std_ss [GSYM convergent]
3276  >> MATCH_MP_TAC SEQ_ICONV
3277  >> FULL_SIMP_TAC std_ss [GREATER_EQ,real_ge,mono_increasing_def]
3278  >> MATCH_MP_TAC SEQ_BOUNDED_2
3279  >> Q.EXISTS_TAC `-f 0`
3280  >> Q.EXISTS_TAC `z`
3281  >> RW_TAC std_ss []
3282QED
3283
3284Theorem inf_lt_infty:   !p. (NegInf < inf p) ==> (!x. p x ==> NegInf < x)
3285Proof
3286  METIS_TAC [inf_le_imp,lte_trans]
3287QED
3288
3289Theorem inf_min:   !p z. p z /\ (!x. p x ==> z <= x) ==> (inf p = z)
3290Proof
3291  RW_TAC std_ss [inf_eq]
3292QED
3293
3294Theorem inf_cminus:   !f c. Normal c - inf (IMAGE f UNIV) =
3295                         sup (IMAGE (\n. Normal c - f n) UNIV)
3296Proof
3297 (* new proof *)
3298  RW_TAC std_ss [sup_eq]
3299  >- (POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
3300      >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
3301      >> `inf (IMAGE f UNIV) <= f n`
3302           by (MATCH_MP_TAC inf_le_imp
3303               >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
3304               >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
3305               >> METIS_TAC [])
3306      >> METIS_TAC [le_lsub_imp])
3307  >> `!n. Normal c - f n <= y`
3308        by (RW_TAC std_ss []
3309            >> Q.PAT_ASSUM `!z. P` MATCH_MP_TAC
3310            >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
3311            >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
3312            >> METIS_TAC [])
3313  >> RW_TAC std_ss [extreal_inf_def,sub_rneg]
3314  >> Suff `sup (IMAGE numeric_negate (IMAGE f UNIV)) <= y - Normal c`
3315  >- METIS_TAC [le_sub_eq,extreal_not_infty,add_comm_normal]
3316  >> RW_TAC std_ss [sup_le]
3317  >> POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
3318  >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
3319  >> RW_TAC std_ss [le_sub_eq,extreal_not_infty,GSYM add_comm_normal]
3320  >> Cases_on `y = PosInf` >- RW_TAC std_ss [le_infty]
3321  >> `f x' <> NegInf` by METIS_TAC [extreal_sub_def,lt_infty,extreal_lt_def]
3322  >> METIS_TAC [extreal_not_infty,extreal_sub_add]
3323QED
3324
3325(* The "inf" of an empty set is PosInf, reasonable but quite unexpected *)
3326Theorem inf_empty:   inf EMPTY = PosInf
3327Proof
3328    RW_TAC std_ss [extreal_inf_def, extreal_sup_def, IMAGE_EMPTY,
3329                   REWRITE_RULE [IN_APP] NOT_IN_EMPTY, extreal_ainv_def]
3330QED
3331
3332(* The "sup" of an empty set is NegInf, reasonable but quite unexpected *)
3333Theorem sup_empty:   sup EMPTY = NegInf
3334Proof
3335    RW_TAC std_ss [extreal_sup_def, IMAGE_EMPTY,
3336                   REWRITE_RULE [IN_APP] NOT_IN_EMPTY, extreal_ainv_def]
3337 >> METIS_TAC [num_not_infty]
3338QED
3339
3340Theorem sup_univ:   sup univ(:extreal) = PosInf
3341Proof
3342    RW_TAC std_ss [sup_eq', IN_UNIV, GSYM le_infty]
3343QED
3344
3345Theorem inf_univ:   inf univ(:extreal) = NegInf
3346Proof
3347    RW_TAC std_ss [inf_eq', IN_UNIV, GSYM le_infty]
3348QED
3349
3350Theorem inf_lt:   !P y. (?x. P x /\ x < y) <=> extreal_inf P < y
3351Proof
3352    RW_TAC std_ss []
3353 >> EQ_TAC >- METIS_TAC [inf_le_imp, let_trans]
3354 >> RW_TAC std_ss []
3355 >> SPOSE_NOT_THEN STRIP_ASSUME_TAC
3356 >> METIS_TAC [le_inf,extreal_lt_def]
3357QED
3358
3359Theorem inf_lt' :
3360    !P y. (?x. x IN P /\ x < y) <=> extreal_inf P < y
3361Proof
3362    REWRITE_TAC [IN_APP, inf_lt]
3363QED
3364
3365(* dual version of sup_lt_epsilon *)
3366Theorem lt_inf_epsilon :
3367    !P e. 0 < e /\ (?x. P x /\ x <> PosInf) /\ inf P <> NegInf ==>
3368          ?x. P x /\ x < inf P + e
3369Proof
3370    RW_TAC std_ss []
3371 >> Cases_on `e = PosInf` (* ``inf P <> NegInf`` is necessary here *)
3372 >- (Q.EXISTS_TAC `x`
3373     >> RW_TAC std_ss []
3374     >> METIS_TAC [extreal_add_def,lt_infty,extreal_cases])
3375 >> `e <> NegInf` by METIS_TAC [le_sup_imp,lt_infty,lte_trans,
3376                                extreal_of_num_def,extreal_not_infty]
3377 >> `inf P <> PosInf` by METIS_TAC [inf_le_imp,lt_infty,let_trans]
3378 >> `inf P < inf P + e`
3379     by (Cases_on `inf P` \\
3380         Cases_on `e` \\
3381         RW_TAC std_ss [extreal_cases, extreal_add_def, extreal_lt_def,
3382                        extreal_le_def, GSYM real_lt] \\
3383         METIS_TAC [REAL_LT_ADDR, extreal_lt_def, extreal_le_def,
3384                    extreal_of_num_def, real_lt])
3385 >> `?x. P x /\ x < inf P + e` by METIS_TAC [inf_lt]
3386 >> Q.EXISTS_TAC `x'`
3387 >> RW_TAC std_ss []
3388QED
3389
3390Theorem lt_inf_epsilon' :
3391    !P e. 0 < e /\ (?x. x IN P /\ x <> PosInf) /\ inf P <> NegInf ==>
3392          ?x. x IN P /\ x < inf P + e
3393Proof
3394    REWRITE_TAC [IN_APP, lt_inf_epsilon]
3395QED
3396
3397Theorem inf_num :
3398    inf (\x. ?n :num. x = -&n) = NegInf
3399Proof
3400    rw [GSYM le_infty, inf_le]
3401 >> CCONTR_TAC
3402 >> fs [GSYM extreal_lt_def, GSYM lt_infty]
3403 >> STRIP_ASSUME_TAC (MATCH_MP (Q.SPEC ‘y’ SIMP_EXTREAL_ARCH_NEG)
3404                               (ASSUME “y <> NegInf”))
3405 >> Know ‘-&SUC n < y’
3406 >- (MATCH_MP_TAC lte_trans \\
3407     Q.EXISTS_TAC ‘-&n’ >> rw [extreal_of_num_def, extreal_ainv_def, extreal_lt_eq])
3408 >> DISCH_TAC
3409 >> Suff ‘y <= -&SUC n’ >- METIS_TAC [let_antisym]
3410 >> FIRST_X_ASSUM MATCH_MP_TAC
3411 >> Q.EXISTS_TAC ‘SUC n’ >> rw []
3412QED
3413
3414(* NOTE: This theorem doesn't hold in general, when ‘r = 0’ or ‘Normal r = PosInf’ *)
3415Theorem inf_cmul :
3416    !P r. 0 < r ==>
3417          inf {x * Normal r | 0 < x /\ P x} = Normal r * inf {x | 0 < x /\ P x}
3418Proof
3419    rw [inf_eq']
3420 >| [ (* goal 1 (of 2) *)
3421     ‘x * Normal r = Normal r * x’ by rw [mul_comm] >> POP_ORW \\
3422      MATCH_MP_TAC le_lmul_imp \\
3423      CONJ_TAC >- rw [REAL_LT_IMP_LE, extreal_of_num_def, extreal_le_eq] \\
3424      Cases_on ‘x = PosInf’ >- rw [le_infty] \\
3425      MATCH_MP_TAC le_epsilon >> rpt STRIP_TAC \\
3426      MATCH_MP_TAC lt_imp_le >> rw [GSYM inf_lt] \\
3427      Q.EXISTS_TAC ‘x’ >> art [] \\
3428      MATCH_MP_TAC lt_addr_imp >> art [] \\
3429      MATCH_MP_TAC pos_not_neginf \\
3430      MATCH_MP_TAC lt_imp_le >> art [],
3431      (* goal 2 (of 2) *)
3432      ONCE_REWRITE_TAC [mul_comm] \\
3433      Know ‘y <= inf {x | 0 < x /\ P x} * Normal r <=>
3434            y / Normal r <= inf {x | 0 < x /\ P x}’
3435      >- (MATCH_MP_TAC le_ldiv >> art []) >> Rewr' \\
3436      rw [le_inf] >> rename1 ‘P z’ \\
3437      Know ‘y / Normal r <= z <=> y <= z * Normal r’
3438      >- (ONCE_REWRITE_TAC [EQ_SYM_EQ] \\
3439          MATCH_MP_TAC le_ldiv >> art []) >> Rewr' \\
3440      FIRST_X_ASSUM MATCH_MP_TAC \\
3441      Q.EXISTS_TAC ‘z’ >> art [] ]
3442QED
3443
3444(* NOTE: This theorem is based on sup_cmul_general and extreal_inf_def *)
3445Theorem inf_cmul_general :
3446    !f c J.
3447        0 <= c /\ J <> {} ==>
3448        inf (IMAGE (\n. Normal c * f n) J) = Normal c * inf (IMAGE f J)
3449Proof
3450    rw [extreal_inf_def, IMAGE_IMAGE, o_DEF]
3451 >> Know ‘!n. -(Normal c * f n) = Normal c * -f n’
3452 >- (rw [neg_minus1', mul_assoc] \\
3453     AP_THM_TAC >> AP_TERM_TAC \\
3454     simp [Once mul_comm])
3455 >> Rewr'
3456 >> qabbrev_tac ‘g = \n. -f n’
3457 >> ‘!n. -f n = g n’ by rw [Abbr ‘g’] >> POP_ORW
3458 >> simp [sup_cmul_general]
3459 >> simp [neg_minus1', mul_assoc]
3460 >> AP_THM_TAC >> AP_TERM_TAC
3461 >> simp [Once mul_comm]
3462QED
3463
3464(* |- !f c.
3465        0 <= c ==>
3466        inf (IMAGE (\n. Normal c * f n) univ(:'a)) =
3467        Normal c * inf (IMAGE f univ(:'a))
3468 *)
3469Theorem inf_cmul' =
3470        inf_cmul_general |> INST_TYPE [“:'index” |-> alpha]
3471                         |> Q.SPECL [‘f’, ‘c’, ‘UNIV’] |> SRULE [] |> GEN_ALL
3472
3473Theorem sup_comm_ext :
3474    !(f :'a -> 'a -> extreal) A B.
3475        sup {sup {f i j | j IN A} | i IN B} =
3476        sup {sup {f i j | i IN B} | j IN A}
3477Proof
3478  RW_TAC std_ss [sup_eq] THENL
3479  [POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION]) THEN
3480   RW_TAC std_ss [GSPECIFICATION] THEN SIMP_TAC std_ss [sup_le] THEN
3481   GEN_TAC THEN GEN_REWR_TAC LAND_CONV [GSYM SPECIFICATION] THEN
3482   RW_TAC std_ss [GSPECIFICATION] THEN SIMP_TAC std_ss [le_sup] THEN
3483   GEN_TAC THEN
3484   DISCH_THEN (MP_TAC o Q.SPEC `sup {f (i:'a) (j:'a) | i IN B}`) THEN
3485   impl_tac >- (rw [] >> Q.EXISTS_TAC ‘j’ >> art []) \\
3486   RW_TAC std_ss [] THEN MATCH_MP_TAC le_trans THEN
3487   Q.EXISTS_TAC `sup {f i j | i IN B}` THEN ASM_REWRITE_TAC [le_sup] THEN
3488   GEN_TAC THEN DISCH_THEN MATCH_MP_TAC THEN
3489   ONCE_REWRITE_TAC [GSYM SPECIFICATION] \\
3490   rw [] >> Q.EXISTS_TAC ‘i’ >> art [],
3491   ALL_TAC] THEN
3492  SIMP_TAC std_ss [sup_le] THEN GEN_TAC THEN
3493  GEN_REWR_TAC LAND_CONV [GSYM SPECIFICATION] THEN
3494  RW_TAC std_ss [GSPECIFICATION] THEN SIMP_TAC std_ss [sup_le] THEN
3495  GEN_TAC THEN GEN_REWR_TAC LAND_CONV [GSYM SPECIFICATION] THEN
3496  RW_TAC std_ss [GSPECIFICATION] THEN
3497  FIRST_X_ASSUM (MP_TAC o Q.SPEC `sup {f (i:'a) (j:'a) | j IN A}`) THEN
3498  impl_tac >- (rw [] >> Q.EXISTS_TAC ‘i’ >> art []) \\
3499  RW_TAC std_ss [] THEN MATCH_MP_TAC le_trans THEN
3500  Q.EXISTS_TAC `sup {f i j | j IN A}` THEN ASM_SIMP_TAC std_ss [le_sup] THEN
3501  GEN_TAC THEN DISCH_THEN MATCH_MP_TAC THEN
3502  rw [] >> Q.EXISTS_TAC ‘j’ >> art []
3503QED
3504
3505Theorem sup_comm : (* was: SUP_commute *)
3506    !f. sup {sup {f i j | j IN univ(:num)} | i IN univ(:num)} =
3507        sup {sup {f i j | i IN univ(:num)} | j IN univ(:num)}
3508Proof
3509    rw [sup_comm_ext]
3510QED
3511
3512Theorem sup_close : (* was: Sup_ereal_close *)
3513    !e s. 0 < e /\ abs (sup s) <> PosInf /\ s <> {} ==>
3514          ?x. x IN s /\ sup s - e < x
3515Proof
3516  RW_TAC std_ss [] THEN
3517  `?r. sup s = Normal r` by METIS_TAC [extreal_cases, extreal_abs_def] THEN
3518  `e <> NegInf` by METIS_TAC [lt_infty, num_not_infty, lt_trans] THEN
3519  Q_TAC SUFF_TAC `Normal r - e < sup s` THENL
3520  [SIMP_TAC std_ss [lt_sup] THEN RW_TAC std_ss [],
3521   ASM_REWRITE_TAC [] THEN ASM_CASES_TAC ``e = PosInf`` THENL
3522   [ASM_REWRITE_TAC [extreal_sub_def, lt_infty], ALL_TAC] THEN
3523   `?k. e = Normal k` by METIS_TAC [extreal_cases] THEN
3524   ASM_SIMP_TAC std_ss [extreal_sub_def, extreal_lt_eq] THEN
3525   MATCH_MP_TAC (REAL_ARITH ``0 < k ==> a - k < a:real``) THEN
3526   ONCE_REWRITE_TAC [GSYM extreal_lt_eq] THEN
3527   METIS_TAC [extreal_of_num_def]]
3528QED
3529
3530(* This lemma find a countable monotonic sequence of element in any non-empty
3531   extreal sets, with the same limit point.
3532 *)
3533Theorem sup_countable_seq : (* was: Sup_countable_SUPR *)
3534    !A. A <> {} ==> ?f:num->extreal. IMAGE f UNIV SUBSET A /\
3535                      (sup A = sup {f n | n IN UNIV})
3536Proof
3537    RW_TAC std_ss []
3538 >> STRIP_ASSUME_TAC (Q.SPEC `sup A` extreal_cases) (* 3 subgoals *)
3539 >| [ (* goal 1 (of 3): NegInf *)
3540      POP_ASSUM (MP_TAC o REWRITE_RULE [sup_eq]) THEN RW_TAC std_ss [le_infty] THEN
3541     `A = {NegInf}` by ASM_SET_TAC [] THEN
3542      ASM_REWRITE_TAC [] THEN Q.EXISTS_TAC `(\n. NegInf)` THEN
3543      CONJ_TAC THENL [SET_TAC [], ALL_TAC] THEN SIMP_TAC std_ss [] THEN
3544      AP_TERM_TAC THEN SET_TAC [],
3545      (* goal 2 (of 3): PosInf *)
3546   FULL_SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY] THEN
3547   ASM_CASES_TAC ``PosInf IN A`` THENL
3548   [Q.EXISTS_TAC `(\x. PosInf)` THEN CONJ_TAC THENL [ASM_SET_TAC [], ALL_TAC] THEN
3549    SIMP_TAC std_ss [] THEN
3550    REWRITE_TAC [SET_RULE ``{PosInf | n IN univ(:num)} = {PosInf}``] THEN
3551    SIMP_TAC std_ss [sup_sing], ALL_TAC] THEN
3552   Q_TAC SUFF_TAC `?x. x IN A /\ 0 <= x` THENL
3553   [STRIP_TAC,
3554    UNDISCH_TAC ``sup A = PosInf`` THEN ONCE_REWRITE_TAC [MONO_NOT_EQ] THEN
3555    SIMP_TAC std_ss [sup_eq] THEN RW_TAC std_ss [lt_infty, GSYM extreal_lt_def] THEN
3556    Q.EXISTS_TAC `0` THEN SIMP_TAC std_ss [GSYM lt_infty, num_not_infty] THEN
3557    GEN_TAC THEN GEN_REWR_TAC LAND_CONV [GSYM SPECIFICATION] THEN DISCH_TAC THEN
3558    FIRST_X_ASSUM (MP_TAC o Q.SPEC `z`) THEN ASM_SIMP_TAC std_ss [le_lt]] THEN
3559   Q_TAC SUFF_TAC `!n. ?f. f IN A /\ x' + Normal (&n) <= f` THENL
3560   [DISCH_TAC,
3561    CCONTR_TAC THEN Q_TAC SUFF_TAC `?n. sup A <= x' + Normal (&n)` THENL
3562    [RW_TAC std_ss [GSYM extreal_lt_def] THEN
3563     `x' <> PosInf` by METIS_TAC [] THEN
3564     ASM_CASES_TAC ``x' = NegInf`` THENL
3565     [FULL_SIMP_TAC std_ss [extreal_add_def, lt_infty], ALL_TAC] THEN
3566     `?r. x' = Normal r` by METIS_TAC [extreal_cases] THEN
3567     ASM_SIMP_TAC std_ss [extreal_add_def, lt_infty],
3568     ALL_TAC] THEN
3569    SIMP_TAC std_ss [sup_le] THEN FULL_SIMP_TAC std_ss [GSYM extreal_lt_def] THEN
3570    Q.EXISTS_TAC `n` THEN
3571    GEN_TAC THEN GEN_REWR_TAC LAND_CONV [GSYM SPECIFICATION] THEN
3572    DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o Q.SPEC `y`) THEN ASM_REWRITE_TAC [] THEN
3573    SIMP_TAC std_ss [le_lt]] THEN
3574   Q_TAC SUFF_TAC `?f. !z. f z IN A /\ x' + Normal (&z) <= f z` THENL
3575   [STRIP_TAC, METIS_TAC []] THEN
3576   Q_TAC SUFF_TAC `sup {f n | n IN UNIV} = PosInf` THENL
3577   [DISCH_TAC THEN Q.EXISTS_TAC `f` THEN ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN
3578    ASM_REWRITE_TAC [] THEN ASM_SET_TAC [],
3579    ALL_TAC] THEN
3580   Q_TAC SUFF_TAC `!n. ?i. Normal (&n) <= f i` THENL
3581   [DISCH_TAC,
3582    GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `n`) THEN STRIP_TAC THEN
3583    Q.EXISTS_TAC `n` THEN MATCH_MP_TAC le_trans THEN
3584    Q.EXISTS_TAC `x' + Normal (&n)` THEN ASM_REWRITE_TAC [] THEN
3585    `x' <> PosInf` by METIS_TAC [] THEN
3586    `x' <> NegInf` by (METIS_TAC [lt_infty, lte_trans, num_not_infty]) THEN
3587    `?r. x' = Normal r` by (METIS_TAC [extreal_cases]) THEN
3588    ASM_SIMP_TAC std_ss [extreal_add_def, extreal_le_def] THEN
3589    MATCH_MP_TAC (REAL_ARITH ``0 <= b ==> a <= b + a:real``) THEN
3590    METIS_TAC [extreal_le_def, extreal_of_num_def]] THEN
3591   SIMP_TAC std_ss [sup_eq] THEN
3592   CONJ_TAC THENL [SIMP_TAC std_ss [le_infty], ALL_TAC] THEN
3593   RW_TAC std_ss [] THEN POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC [MONO_NOT_EQ] THEN
3594   RW_TAC std_ss [GSYM extreal_lt_def, GSYM lt_infty] THEN
3595   POP_ASSUM (MP_TAC o MATCH_MP SIMP_EXTREAL_ARCH) THEN STRIP_TAC THEN
3596   FIRST_X_ASSUM (MP_TAC o Q.SPEC `SUC n`) THEN STRIP_TAC THEN
3597   Q.EXISTS_TAC `f i` THEN CONJ_TAC THENL
3598   [ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN SIMP_TAC std_ss [GSPECIFICATION] THEN
3599    METIS_TAC [IN_UNIV], ALL_TAC] THEN
3600   MATCH_MP_TAC lte_trans THEN Q.EXISTS_TAC `Normal (&SUC n)` THEN
3601   ASM_REWRITE_TAC [] THEN MATCH_MP_TAC let_trans THEN Q.EXISTS_TAC `&n` THEN
3602   ASM_REWRITE_TAC [] THEN SIMP_TAC real_ss [extreal_of_num_def, extreal_lt_eq],
3603      (* goal 3 (of 3): Normal r *)
3604      Know `!n:num. ?x. x IN A /\ sup A < x + 1 / &(SUC n)`
3605      >- (GEN_TAC \\
3606          Know `?x. x IN A /\ sup A - 1 / &(SUC n) < x`
3607          >- (MATCH_MP_TAC sup_close \\
3608              ASM_SIMP_TAC std_ss [extreal_abs_def, lt_infty] \\
3609             `&(SUC n) = Normal &(SUC n)` by METIS_TAC [extreal_of_num_def] \\
3610             `SUC n <> 0` by RW_TAC arith_ss [] \\
3611             `(0 :real) < &(SUC n)` by METIS_TAC [REAL_NZ_IMP_LT] \\
3612              METIS_TAC [lt_div, lt_01]) >> RW_TAC std_ss [] \\
3613          Q.EXISTS_TAC `x` >> art [] \\
3614         `&(SUC n) = Normal &(SUC n)` by METIS_TAC [extreal_of_num_def] \\
3615         `&(SUC n) <> (0 :real)` by RW_TAC real_ss [] \\
3616         `(1 :extreal) / &SUC n = Normal (1 / &SUC n)`
3617            by METIS_TAC [extreal_of_num_def, extreal_div_eq] >> fs [] \\
3618         `Normal (1 / &SUC n) <> PosInf /\ Normal (1 / &SUC n) <> NegInf`
3619            by PROVE_TAC [extreal_not_infty] \\
3620          METIS_TAC [sub_lt_eq]) >> DISCH_TAC \\
3621      FULL_SIMP_TAC std_ss [SKOLEM_THM] \\
3622      Know `sup {f n | n IN univ(:num)} = sup A`
3623      >- (RW_TAC std_ss [sup_eq', GSPECIFICATION, IN_UNIV]
3624          >- (Q.PAT_X_ASSUM `sup A = _` (ONCE_REWRITE_TAC o wrap o SYM) \\
3625              MATCH_MP_TAC le_sup_imp >> METIS_TAC [IN_APP]) \\
3626          Q.PAT_X_ASSUM `sup A = _` (ONCE_REWRITE_TAC o wrap o SYM) \\
3627          MATCH_MP_TAC le_epsilon >> RW_TAC std_ss [] \\
3628         `e <> NegInf` by METIS_TAC [lt_trans, lt_infty] \\
3629         `?r. e = Normal r` by METIS_TAC [extreal_cases] \\
3630          ONCE_ASM_REWRITE_TAC [] \\
3631         `0 < r` by METIS_TAC [extreal_of_num_def, extreal_lt_eq] \\
3632         `?n. inv (&SUC n) < r` by METIS_TAC [REAL_ARCH_INV_SUC] \\
3633          MATCH_MP_TAC le_trans >> Q.EXISTS_TAC `f n + 1 / &SUC n` \\
3634          CONJ_TAC >- METIS_TAC [le_lt] \\
3635          MATCH_MP_TAC le_add2 \\
3636          CONJ_TAC >- (FIRST_X_ASSUM MATCH_MP_TAC \\
3637                       Q.EXISTS_TAC `n` >> REWRITE_TAC []) \\
3638         `&SUC n <> (0 :real)` by RW_TAC real_ss [] \\
3639          ASM_SIMP_TAC std_ss [extreal_of_num_def, extreal_div_eq,
3640                               extreal_le_eq, GSYM REAL_INV_1OVER] \\
3641          MATCH_MP_TAC REAL_LT_IMP_LE >> art []) >> DISCH_TAC \\
3642      Q.EXISTS_TAC `f` >> ASM_SET_TAC [] ]
3643QED
3644
3645Theorem sup_seq_countable_seq : (* was: SUPR_countable_SUPR *)
3646    !A g. A <> {} ==>
3647          ?f:num->extreal. IMAGE f UNIV SUBSET IMAGE g A /\
3648                    (sup {g n | n IN A} = sup {f n | n IN UNIV})
3649Proof
3650  RW_TAC std_ss [] THEN ASSUME_TAC sup_countable_seq THEN
3651  POP_ASSUM (MP_TAC o Q.SPEC `IMAGE g A`) THEN
3652  SIMP_TAC std_ss [GSYM IMAGE_DEF] THEN DISCH_THEN (MATCH_MP_TAC) THEN
3653  ASM_SET_TAC []
3654QED
3655
3656Theorem inf_countable_seq :
3657    !A. A <> {} ==> ?f. IMAGE f univ(:num) SUBSET A /\
3658                        inf A = inf {f n | n IN univ(:num)}
3659Proof
3660    rw [extreal_inf_def]
3661 >> qabbrev_tac ‘A' = IMAGE numeric_negate A’
3662 >> MP_TAC (Q.SPEC ‘A'’ sup_countable_seq)
3663 >> impl_tac >- rw [Once EXTENSION, Abbr ‘A'’]
3664 >> STRIP_TAC
3665 >> Q.EXISTS_TAC ‘\n. -f n’
3666 >> CONJ_TAC
3667 >- (Q.PAT_X_ASSUM ‘_ SUBSET A'’ MP_TAC \\
3668     rw [SUBSET_DEF] \\
3669     Know ‘f n IN A'’ >- (POP_ASSUM MATCH_MP_TAC >> Q.EXISTS_TAC ‘n’ >> rw []) \\
3670     rw [Abbr ‘A'’] >> fs [])
3671 >> POP_ORW
3672 >> AP_TERM_TAC
3673 >> rw [Once EXTENSION]
3674 >> EQ_TAC >> rw []
3675 >- (Q.EXISTS_TAC ‘-f n’ >> simp [] \\
3676     Q.EXISTS_TAC ‘n’ >> rw [])
3677 >> Q.EXISTS_TAC ‘n’ >> simp []
3678QED
3679
3680Theorem inf_seq_countable_inf :
3681    !A g. A <> {} ==>
3682          ?f:num->extreal. IMAGE f UNIV SUBSET IMAGE g A /\
3683                    (inf {g n | n IN A} = inf {f n | n IN UNIV})
3684Proof
3685  RW_TAC std_ss [] THEN ASSUME_TAC inf_countable_seq THEN
3686  POP_ASSUM (MP_TAC o Q.SPEC `IMAGE g A`) THEN
3687  SIMP_TAC std_ss [GSYM IMAGE_DEF] THEN DISCH_THEN (MATCH_MP_TAC) THEN
3688  ASM_SET_TAC []
3689QED
3690
3691(* ------------------------------------------------------------------------- *)
3692(*  Limit superior and limit inferior (limsup and liminf) [1, p.313] [4]     *)
3693(* ------------------------------------------------------------------------- *)
3694
3695(* for a sequence of function (u :num -> 'a -> extreal),
3696   use `ext_limsup (\n. u n x)` as "limsup u x" [1, p.63], etc.
3697
3698   cf. set_limsup_def and set_liminf_def (borelTheory)
3699 *)
3700Definition ext_limsup_def:
3701    ext_limsup (a :num -> extreal) = inf (IMAGE (\m. sup {a n | m <= n}) UNIV)
3702End
3703
3704Definition ext_liminf_def:
3705    ext_liminf (a :num -> extreal) = sup (IMAGE (\m. inf {a n | m <= n}) UNIV)
3706End
3707
3708Overload limsup = ``ext_limsup``
3709Overload liminf = ``ext_liminf``
3710
3711Theorem ext_liminf_le_limsup :
3712    !a. liminf a <= limsup a
3713Proof
3714    rw [ext_limsup_def, le_inf']
3715 >> rw [le_sup']
3716 >> rw [ext_liminf_def, sup_le']
3717 >> rw [inf_le']
3718 >> MATCH_MP_TAC le_trans
3719 >> Q.EXISTS_TAC ‘a (MAX m m')’
3720 >> reverse CONJ_TAC
3721 >- (FIRST_X_ASSUM MATCH_MP_TAC \\
3722     Q.EXISTS_TAC ‘MAX m m'’ >> rw [MAX_LE])
3723 >> FIRST_X_ASSUM MATCH_MP_TAC
3724 >> Q.EXISTS_TAC ‘MAX m m'’
3725 >> rw [MAX_LE]
3726QED
3727
3728(* Properties A.1 (ii) [1, p.409] *)
3729Theorem ext_liminf_alt_limsup :
3730    !a. liminf a = -limsup (numeric_negate o a)
3731Proof
3732    rw [ext_liminf_def, ext_limsup_def, extreal_inf_def]
3733 >> Know ‘!m. IMAGE numeric_negate {a n | m <= n} = {-a n | m <= n}’
3734 >- (rw [Once EXTENSION, IN_IMAGE] \\
3735     EQ_TAC >> rw [] >- (Q.EXISTS_TAC ‘n’ >> rw []) \\
3736     Q.EXISTS_TAC ‘a n’ >> rw [] \\
3737     Q.EXISTS_TAC ‘n’ >> rw [])
3738 >> Rewr'
3739 >> Q.ABBREV_TAC ‘f = \m. sup {(-a n) | m <= n}’ >> simp []
3740 >> rw [IMAGE_IMAGE, o_DEF]
3741QED
3742
3743Theorem ext_limsup_alt_liminf :
3744    !a. limsup a = -liminf (numeric_negate o a)
3745Proof
3746    rw [ext_liminf_alt_limsup, o_DEF]
3747 >> METIS_TAC []
3748QED
3749
3750Theorem ext_limsup_upperbound :
3751    !a c. (!n. a n <= c) ==> limsup a <= c
3752Proof
3753    rw [ext_limsup_def, inf_le']
3754 >> Know ‘!m. y <= sup {a n | m <= n}’
3755 >- (Q.X_GEN_TAC ‘m’ \\
3756     FIRST_X_ASSUM MATCH_MP_TAC \\
3757     Q.EXISTS_TAC ‘m’ >> art [])
3758 >> DISCH_TAC
3759 >> Q.PAT_X_ASSUM ‘!z. _ ==> y <= z’ K_TAC
3760 >> Q_TAC (TRANS_TAC le_trans) ‘sup {a n | 0 <= n}’
3761 >> rw [sup_le'] >> art []
3762QED
3763
3764Theorem ext_limsup_lowerbound :
3765    !a c. (!n. c <= a n) ==> c <= limsup a
3766Proof
3767    rw [ext_limsup_def, le_inf']
3768 >> rw [le_sup']
3769 >> Know ‘!n. m <= n ==> a n <= y’
3770 >- (rpt STRIP_TAC \\
3771     FIRST_X_ASSUM MATCH_MP_TAC \\
3772     Q.EXISTS_TAC ‘n’ >> art [])
3773 >> DISCH_TAC
3774 >> Q.PAT_X_ASSUM ‘!z. _ ==> z <= y’ K_TAC
3775 >> Q_TAC (TRANS_TAC le_trans) ‘a m’ >> rw []
3776QED
3777
3778Theorem ext_liminf_upperbound :
3779    !a c. (!n. a n <= c) ==> liminf a <= c
3780Proof
3781    rw [ext_liminf_def, sup_le']
3782 >> rw [inf_le']
3783 >> Know ‘!n. m <= n ==> y <= a n’
3784 >- (rpt STRIP_TAC \\
3785     FIRST_X_ASSUM MATCH_MP_TAC \\
3786     Q.EXISTS_TAC ‘n’ >> art [])
3787 >> DISCH_TAC
3788 >> Q.PAT_X_ASSUM ‘!z. _ ==> y <= z’ K_TAC
3789 >> Q_TAC (TRANS_TAC le_trans) ‘a m’ >> rw []
3790QED
3791
3792Theorem ext_liminf_lowerbound :
3793    !a c. (!n. c <= a n) ==> c <= liminf a
3794Proof
3795    rw [ext_liminf_def, le_sup']
3796 >> Know ‘!m. inf {a n | m <= n} <= y’
3797 >- (Q.X_GEN_TAC ‘m’ \\
3798     FIRST_X_ASSUM MATCH_MP_TAC \\
3799     Q.EXISTS_TAC ‘m’ >> art [])
3800 >> DISCH_TAC
3801 >> Q.PAT_X_ASSUM ‘!z. _ ==> z <= y’ K_TAC
3802 >> Q_TAC (TRANS_TAC le_trans) ‘inf {a n | 0 <= n}’
3803 >> rw [le_inf'] >> art []
3804QED
3805
3806Theorem ext_limsup_pos :
3807    !a. (!n. 0 <= a n) ==> 0 <= limsup a
3808Proof
3809    rpt STRIP_TAC
3810 >> MATCH_MP_TAC ext_limsup_lowerbound >> art []
3811QED
3812
3813Theorem ext_liminf_pos :
3814    !a. (!n. 0 <= a n) ==> 0 <= liminf a
3815Proof
3816    rpt STRIP_TAC
3817 >> MATCH_MP_TAC ext_liminf_lowerbound >> art []
3818QED
3819
3820Theorem ext_limsup_bounded :
3821    !a k. (!n. abs (a n) <= k) ==> abs (limsup a) <= k
3822Proof
3823    rw [abs_bounds]
3824 >| [ MATCH_MP_TAC ext_limsup_lowerbound >> rw [],
3825      MATCH_MP_TAC ext_limsup_upperbound >> rw [] ]
3826QED
3827
3828Theorem ext_liminf_bounded :
3829    !a k. (!n. abs (a n) <= k) ==> abs (liminf a) <= k
3830Proof
3831    rw [abs_bounds]
3832 >| [ MATCH_MP_TAC ext_liminf_lowerbound >> rw [],
3833      MATCH_MP_TAC ext_liminf_upperbound >> rw [] ]
3834QED
3835
3836Theorem sup_pos :
3837    !a m. (!n. 0 <= a n) ==> 0 <= sup {a n | m <= (n :num)}
3838Proof
3839    rw [le_sup']
3840 >> Q_TAC (TRANS_TAC le_trans) ‘a m’ >> rw []
3841 >> POP_ASSUM MATCH_MP_TAC
3842 >> Q.EXISTS_TAC ‘m’ >> rw []
3843QED
3844
3845Theorem sup_pos' :
3846    !a. (!n. 0 <= a n) ==> 0 <= sup (IMAGE a UNIV)
3847Proof
3848    rw [le_sup']
3849 >> Q_TAC (TRANS_TAC le_trans) ‘a ARB’ >> rw []
3850 >> POP_ASSUM MATCH_MP_TAC
3851 >> Q.EXISTS_TAC ‘ARB’ >> rw []
3852QED
3853
3854Theorem inf_pos :
3855    !a m. (!n. 0 <= a n) ==> 0 <= inf {a n | m <= (n :num)}
3856Proof
3857    rw [le_inf'] >> rw []
3858QED
3859
3860Theorem inf_pos' :
3861    !a. (!n. 0 <= a n) ==> 0 <= inf (IMAGE a UNIV)
3862Proof
3863    rw [le_inf'] >> rw []
3864QED
3865
3866Theorem sup_bounded :
3867    !a k. (!n. abs (a n) <= k) ==> !m. abs (sup {a n | m <= (n :num)}) <= k
3868Proof
3869    reverse (rw [abs_bounds])
3870 >- (rw [sup_le'] >> art [])
3871 >> rw [le_sup']
3872 >> Q_TAC (TRANS_TAC le_trans) ‘a m’ >> rw []
3873 >> POP_ASSUM MATCH_MP_TAC
3874 >> Q.EXISTS_TAC ‘m’ >> rw []
3875QED
3876
3877Theorem sup_bounded' :
3878    !a k. (!n. abs (a n) <= k) ==> abs (sup (IMAGE a UNIV)) <= k
3879Proof
3880    reverse (rw [abs_bounds])
3881 >- (rw [sup_le'] >> art [])
3882 >> rw [le_sup']
3883 >> Q_TAC (TRANS_TAC le_trans) ‘a ARB’ >> rw []
3884 >> POP_ASSUM MATCH_MP_TAC
3885 >> Q.EXISTS_TAC ‘ARB’ >> rw []
3886QED
3887
3888Theorem sup_bounded_alt :
3889    !s. s <> {} /\ (!x. x IN s ==> abs x <= Normal k) ==>
3890        abs (sup s) <= Normal k
3891Proof
3892    reverse (rw [abs_bounds]) >- rw [sup_le']
3893 >> rw [le_sup']
3894 >> fs [GSYM MEMBER_NOT_EMPTY]
3895 >> Q_TAC (TRANS_TAC le_trans) ‘x’ >> rw []
3896QED
3897
3898Theorem inf_bounded :
3899    !a k. (!n. abs (a n) <= k) ==> !m. abs (inf {a n | m <= (n :num)}) <= k
3900Proof
3901    rw [abs_bounds]
3902 >- (rw [le_inf'] >> art [])
3903 >> rw [inf_le']
3904 >> Q_TAC (TRANS_TAC le_trans) ‘a m’ >> rw []
3905 >> POP_ASSUM MATCH_MP_TAC
3906 >> Q.EXISTS_TAC ‘m’ >> rw []
3907QED
3908
3909Theorem inf_bounded' :
3910    !a k. (!n. abs (a n) <= k) ==> !m. abs (inf (IMAGE a UNIV)) <= k
3911Proof
3912    rw [abs_bounds]
3913 >- (rw [le_inf'] >> art [])
3914 >> rw [inf_le']
3915 >> Q_TAC (TRANS_TAC le_trans) ‘a ARB’ >> rw []
3916 >> POP_ASSUM MATCH_MP_TAC
3917 >> Q.EXISTS_TAC ‘ARB’ >> rw []
3918QED
3919
3920Theorem inf_bounded_alt :
3921    !s. s <> {} /\ (!x. x IN s ==> abs x <= Normal k) ==>
3922        abs (inf s) <= Normal k
3923Proof
3924    rw [abs_bounds] >- rw [le_inf']
3925 >> rw [inf_le']
3926 >> fs [GSYM MEMBER_NOT_EMPTY]
3927 >> Q_TAC (TRANS_TAC le_trans) ‘x’ >> rw []
3928QED
3929
3930Theorem sup_normal :
3931    !s k. abs (sup s) <= Normal k ==> Normal (sup (s o Normal)) = sup s
3932Proof
3933    rw [extreal_sup_def, extreal_abs_def, abs_bounds, le_infty, extreal_ainv_def,
3934        extreal_le_eq, o_DEF]
3935QED
3936
3937Theorem inf_normal :
3938    !s k. abs (inf s) <= Normal k ==> Normal (inf (s o Normal)) = inf s
3939Proof
3940    rw [extreal_inf_def, inf_def, GSYM extreal_ainv_def, abs_bounds, le_neg]
3941 >> Know ‘(\r. s (-Normal r)) = s o numeric_negate o Normal’
3942 >- rw [o_DEF, FUN_EQ_THM]
3943 >> Rewr'
3944 >> REWRITE_TAC [o_ASSOC]
3945 >> Know ‘IMAGE numeric_negate s = s o numeric_negate’
3946 >- (rw [Once EXTENSION, o_DEF, IN_APP] \\
3947     METIS_TAC [neg_neg])
3948 >> DISCH_THEN (FULL_SIMP_TAC bool_ss o wrap)
3949 >> qabbrev_tac ‘P = s o numeric_negate’
3950 >> MATCH_MP_TAC sup_normal
3951 >> Q.EXISTS_TAC ‘k’
3952 >> rw [abs_bounds]
3953 >> METIS_TAC [neg_neg, le_neg]
3954QED
3955
3956(* ------------------------------------------------------------------------- *)
3957(* Suminf over extended reals. Definition and properties                     *)
3958(* ------------------------------------------------------------------------- *)
3959
3960(* old definition, which (wrongly) allows `!f. 0 <= ext_suminf f`:
3961val ext_suminf_def = Define
3962   `ext_suminf f = sup (IMAGE (\n. SIGMA f (count n)) UNIV)`;
3963
3964   new definition, which is only specified on positive functions: *)
3965local
3966  val thm = Q.prove (
3967     `?sum. !f. (!n. 0 <= f n) ==>
3968                (sum f = sup (IMAGE (\n. SIGMA f (count n)) UNIV))`,
3969      Q.EXISTS_TAC `\f. sup (IMAGE (\n. SIGMA f (count n)) UNIV)` \\
3970      RW_TAC std_ss []);
3971in
3972  val ext_suminf_def = new_specification
3973    ("ext_suminf_def", ["ext_suminf"], thm);
3974end;
3975
3976Theorem ext_suminf_alt : (* without IMAGE *)
3977    !f. (!n. 0 <= f n) ==>
3978        (ext_suminf (\x. f x) = sup {SIGMA (\i. f i) (count n) | n IN UNIV})
3979Proof
3980    RW_TAC std_ss [ext_suminf_def, IMAGE_DEF]
3981QED
3982
3983Theorem ext_suminf_alt' : (* without IMAGE, further simplified *)
3984    !f. (!n. 0 <= f n) ==>
3985        (ext_suminf (\x. f x) = sup {SIGMA f (count n) | n | T})
3986Proof
3987    RW_TAC bool_ss [ext_suminf_alt, ETA_AX, IN_UNIV]
3988QED
3989
3990Theorem ext_suminf_add :
3991    !f g. (!n. 0 <= f n /\ 0 <= g n) ==>
3992          (ext_suminf (\n. f n + g n) = ext_suminf f + ext_suminf g)
3993Proof
3994    rpt STRIP_TAC
3995 >> Know `!n. 0 <= (\n. f n + g n) n`
3996 >- (RW_TAC std_ss [] >> MATCH_MP_TAC le_add >> art []) >> DISCH_TAC
3997 >> RW_TAC std_ss [ext_suminf_def]
3998 >> POP_ASSUM (ONCE_REWRITE_TAC o wrap o (MATCH_MP ext_suminf_def))
3999 >> RW_TAC std_ss [sup_eq', IN_IMAGE, IN_UNIV]
4000 >- (`!n. f n <> NegInf /\ g n <> NegInf`
4001       by METIS_TAC [lt_infty, lte_trans, num_not_infty] \\
4002     RW_TAC std_ss [FINITE_COUNT, EXTREAL_SUM_IMAGE_ADD] \\
4003     MATCH_MP_TAC le_add2 \\
4004     RW_TAC std_ss [le_sup'] \\
4005     POP_ASSUM MATCH_MP_TAC \\
4006     RW_TAC std_ss [IN_IMAGE, IN_UNIV] \\
4007     Q.EXISTS_TAC `n` >> REWRITE_TAC [])
4008 >> Know `!n. SIGMA (\n. f n + g n) (count n) <= y`
4009 >- (RW_TAC std_ss [] >> POP_ASSUM MATCH_MP_TAC \\
4010     RW_TAC std_ss [IN_IMAGE, IN_UNIV] \\
4011     Q.EXISTS_TAC `n` >> REWRITE_TAC []) >> DISCH_TAC
4012 >> `!n. f n <> NegInf /\ g n <> NegInf`
4013       by METIS_TAC [lt_infty, lte_trans, num_not_infty]
4014 >> `!n. SIGMA (\n. f n + g n) (count n) =
4015         SIGMA f (count n) + SIGMA g (count n)`
4016       by METIS_TAC [EXTREAL_SUM_IMAGE_ADD, FINITE_COUNT]
4017 >> `!n. SIGMA f (count n) + SIGMA g (count n) <= y`
4018       by FULL_SIMP_TAC std_ss []
4019 >> Know `!n m. SIGMA f (count n) + SIGMA g (count m) <= y`
4020 >- (RW_TAC std_ss [] \\
4021     Cases_on `n <= m`
4022     >- (MATCH_MP_TAC le_trans \\
4023         Q.EXISTS_TAC `SIGMA f (count m) + SIGMA g (count m)` \\
4024         RW_TAC std_ss [] \\
4025         MATCH_MP_TAC le_radd_imp \\
4026         MATCH_MP_TAC EXTREAL_SUM_IMAGE_MONO_SET \\
4027         RW_TAC std_ss [FINITE_COUNT, SUBSET_DEF, IN_COUNT] \\
4028         DECIDE_TAC) \\
4029     MATCH_MP_TAC le_trans \\
4030     Q.EXISTS_TAC `SIGMA f (count n) + SIGMA g (count n)` \\
4031     RW_TAC std_ss [] \\
4032     MATCH_MP_TAC le_ladd_imp \\
4033     MATCH_MP_TAC EXTREAL_SUM_IMAGE_MONO_SET \\
4034     RW_TAC std_ss [FINITE_COUNT, SUBSET_DEF, IN_COUNT] \\
4035     DECIDE_TAC) >> DISCH_TAC
4036 >> Cases_on `y = PosInf` >- RW_TAC std_ss [le_infty]
4037 >> `!n. SIGMA f (count n) <> NegInf`
4038       by METIS_TAC [EXTREAL_SUM_IMAGE_NOT_INFTY, FINITE_COUNT]
4039 >> `!n. SIGMA g (count n) <> NegInf`
4040       by METIS_TAC [EXTREAL_SUM_IMAGE_NOT_INFTY, FINITE_COUNT]
4041 >> `y <> NegInf` by METIS_TAC [lt_infty, add_not_infty, lte_trans]
4042 >> FULL_SIMP_TAC std_ss [GSYM le_sub_eq2]
4043 >> Know `!m. sup (IMAGE (\n. SIGMA f (count n)) univ(:num)) <= y - SIGMA g (count m)`
4044 >- (RW_TAC std_ss [sup_le', IN_IMAGE, IN_UNIV] \\
4045     FULL_SIMP_TAC std_ss []) >> DISCH_TAC
4046 >> Know `sup (IMAGE (\n. SIGMA f (count n)) univ(:num)) <> NegInf`
4047 >- (RW_TAC std_ss [lt_infty, GSYM sup_lt', IN_IMAGE, IN_UNIV] \\
4048     Q.EXISTS_TAC `SIGMA f (count 0)` \\
4049     reverse (RW_TAC bool_ss []) >- FULL_SIMP_TAC std_ss [lt_infty] \\
4050     Q.EXISTS_TAC `0` >> REWRITE_TAC []) >> DISCH_TAC
4051 >> `!m. SIGMA g (count m) + sup (IMAGE (\n. SIGMA f (count n)) univ(:num)) <= y`
4052       by METIS_TAC [le_sub_eq2, add_comm]
4053 >> `!m. SIGMA g (count m) <= y - sup (IMAGE (\n. SIGMA f (count n)) univ(:num))`
4054       by METIS_TAC [le_sub_eq2]
4055 >> `!m. sup (IMAGE (\n. SIGMA g (count n)) univ(:num)) <=
4056         y - sup (IMAGE (\n. SIGMA f (count n)) univ(:num))`
4057       by (RW_TAC std_ss [sup_le', IN_IMAGE, IN_UNIV] \\
4058           FULL_SIMP_TAC std_ss [])
4059 >> Know `sup (IMAGE (\n. SIGMA g (count n)) univ(:num)) <> NegInf`
4060 >- (RW_TAC std_ss [lt_infty, GSYM sup_lt', IN_IMAGE, IN_UNIV] \\
4061     Q.EXISTS_TAC `SIGMA g (count 0)` \\
4062     reverse (RW_TAC bool_ss []) >- FULL_SIMP_TAC std_ss [lt_infty] \\
4063     Q.EXISTS_TAC `0` >> REWRITE_TAC []) >> DISCH_TAC
4064 >> METIS_TAC [le_sub_eq2, add_comm]
4065QED
4066
4067Theorem ext_suminf_add' :
4068    !f g h. (!n. 0 <= f n) /\ (!n. 0 <= g n) /\ (!n. h n = f n + g n) ==>
4069            (ext_suminf h = ext_suminf f + ext_suminf g)
4070Proof
4071    rpt STRIP_TAC
4072 >> ‘h = \n. f n + g n’ by METIS_TAC [] >> POP_ORW
4073 >> MATCH_MP_TAC ext_suminf_add >> rw []
4074QED
4075
4076Theorem ext_suminf_cmul :
4077    !f c. 0 <= c /\ (!n. 0 <= f n) ==>
4078          (ext_suminf (\n. c * f n) = c * ext_suminf f)
4079Proof
4080    rpt STRIP_TAC
4081 >> Know `!n. 0 <= (\n. c * f n) n`
4082 >- (RW_TAC std_ss [] >> MATCH_MP_TAC le_mul >> art [])
4083 >> RW_TAC std_ss [ext_suminf_def]
4084 >> `c <> NegInf` by METIS_TAC [lt_infty, num_not_infty, lte_trans]
4085 >> `!n. f n <> NegInf` by METIS_TAC [lt_infty, num_not_infty, lte_trans]
4086 >> reverse (Cases_on `c` >> (RW_TAC std_ss []))
4087 >- (`!n. SIGMA (\n. Normal r * f n) (count n) =
4088          Normal r * SIGMA f (count n)`
4089       by METIS_TAC [EXTREAL_SUM_IMAGE_CMUL, FINITE_COUNT] >> POP_ORW \\
4090     METIS_TAC [sup_cmul, extreal_le_def, extreal_of_num_def])
4091 >> Cases_on `!n. f n = 0`
4092 >- (RW_TAC std_ss [extreal_mul_def, extreal_of_num_def, EXTREAL_SUM_IMAGE_0,
4093                    FINITE_COUNT] \\
4094     Know `sup (IMAGE (\n. Normal 0) univ(:num)) = 0`
4095     >- (MATCH_MP_TAC sup_const_alt' \\
4096         RW_TAC std_ss [IN_IMAGE, IN_UNIV] \\
4097         REWRITE_TAC [extreal_of_num_def]) >> DISCH_TAC \\
4098     RW_TAC std_ss [extreal_of_num_def, extreal_mul_def])
4099 >> FULL_SIMP_TAC std_ss []
4100 >> `0 < f n` by METIS_TAC [lt_le]
4101 >> Know `0 < sup (IMAGE (\n. SIGMA f (count n)) univ(:num))`
4102 >- (RW_TAC std_ss [GSYM sup_lt'] \\
4103     Q.EXISTS_TAC `SIGMA f (count (SUC n))` \\
4104     RW_TAC std_ss [IN_IMAGE, IN_UNIV]
4105     >- (Q.EXISTS_TAC `SUC n` >> REWRITE_TAC []) \\
4106    `f n <= SIGMA f (count (SUC n))`
4107       by METIS_TAC [COUNT_SUC, IN_INSERT, FINITE_COUNT,
4108                     EXTREAL_SUM_IMAGE_POS_MEM_LE] \\
4109     METIS_TAC [lte_trans]) >> DISCH_TAC
4110 >> `PosInf * f n <= SIGMA (\n. PosInf * f n) (count (SUC n))`
4111       by (`!n. 0 <= PosInf * f n` by METIS_TAC [le_infty, le_mul] \\
4112           `n IN count (SUC n)` by METIS_TAC [COUNT_SUC, IN_INSERT] \\
4113           (MP_TAC o REWRITE_RULE [FINITE_COUNT] o
4114            Q.ISPECL [`(\n:num. PosInf * f n)`, `count (SUC n)`])
4115              EXTREAL_SUM_IMAGE_POS_MEM_LE \\
4116           RW_TAC std_ss [])
4117 >> `!x. 0 < x ==> (PosInf * x = PosInf)`
4118       by (Cases_on `x`
4119           >| [ METIS_TAC [lt_infty],
4120                RW_TAC std_ss [extreal_mul_def],
4121                RW_TAC real_ss [extreal_lt_eq, extreal_of_num_def,
4122                                extreal_mul_def] ])
4123 >> `PosInf * f n = PosInf`
4124       by ((Cases_on `f n` >> FULL_SIMP_TAC std_ss [extreal_mul_def])
4125           >- METIS_TAC []
4126           >> METIS_TAC [extreal_lt_eq, extreal_of_num_def])
4127 >> `SIGMA (\n. PosInf * f n) (count (SUC n)) = PosInf` by METIS_TAC [le_infty]
4128 >> `SIGMA (\n. PosInf * f n) (count (SUC n)) <=
4129     sup (IMAGE (\n. SIGMA (\n. PosInf * f n) (count n)) univ(:num))`
4130       by (MATCH_MP_TAC le_sup_imp' \\
4131           RW_TAC std_ss [IN_IMAGE, IN_UNIV] \\
4132           METIS_TAC [])
4133 >> `sup (IMAGE (\n. SIGMA (\n. PosInf * f n) (count n)) univ(:num)) = PosInf`
4134       by METIS_TAC [le_infty]
4135 >> METIS_TAC []
4136QED
4137
4138Theorem ext_suminf_cmul_alt :
4139    !f c. 0 <= c /\ (!n. 0 <= f n) /\ (!n. f n < PosInf) ==>
4140         (ext_suminf (\n. (Normal c) * f n) = (Normal c) * ext_suminf f)
4141Proof
4142    rpt STRIP_TAC
4143 >> Know `!n. 0 <= (\n. Normal c * f n) n`
4144 >- (RW_TAC std_ss [] >> MATCH_MP_TAC le_mul >> art [] \\
4145     ASM_REWRITE_TAC [extreal_of_num_def, extreal_le_eq]) >> DISCH_TAC
4146 >> RW_TAC std_ss [ext_suminf_def]
4147 >> POP_ASSUM (ONCE_REWRITE_TAC o wrap o (MATCH_MP ext_suminf_def))
4148 >> Know `!n. SIGMA (\n. Normal c * f n) (count n) =
4149              (Normal c) * SIGMA f (count n)`
4150 >- (GEN_TAC >> irule EXTREAL_SUM_IMAGE_CMUL \\
4151     RW_TAC std_ss [FINITE_COUNT, lt_infty]) >> Rewr'
4152 >> RW_TAC std_ss [sup_cmul]
4153QED
4154
4155(* Note: changed `ext_suminf f <> PosInf` to `ext_suminf f < PosInf` for
4156   easier applications. To get the original version, use "lt_infty". *)
4157Theorem ext_suminf_lt_infty :
4158    !f. (!n. 0 <= f n) /\ ext_suminf f < PosInf ==> !n. f n < PosInf
4159Proof
4160    rpt STRIP_TAC
4161 >> Q.PAT_ASSUM `!n. 0 <= f n`
4162       ((FULL_SIMP_TAC std_ss) o wrap o (MATCH_MP ext_suminf_def))
4163 >> Know `!n. SIGMA f (count n) < PosInf`
4164 >- (GEN_TAC \\
4165    `!n. SIGMA f (count n) IN IMAGE (\n. SIGMA f (count n)) UNIV`
4166       by (RW_TAC std_ss [IN_IMAGE, IN_UNIV] >> METIS_TAC []) \\
4167     METIS_TAC [sup_lt_infty, SPECIFICATION])
4168 >> DISCH_TAC
4169 >> Suff `f n <= SIGMA f (count (SUC n))` >- METIS_TAC [let_trans]
4170 >> `FINITE (count (SUC n))` by RW_TAC std_ss [FINITE_COUNT]
4171 >> `n IN (count (SUC n))` by RW_TAC real_ss [IN_COUNT]
4172 >> METIS_TAC [EXTREAL_SUM_IMAGE_POS_MEM_LE]
4173QED
4174
4175Theorem lemma[local] =
4176      SIMP_RULE std_ss [GSYM lt_infty]
4177                       (ONCE_REWRITE_RULE [MONO_NOT_EQ] (Q.SPEC `f` ext_suminf_lt_infty))
4178
4179Theorem ext_suminf_posinf:
4180    !f. (!n. 0 <= f n) /\ (?n. f n = PosInf) ==> (ext_suminf f = PosInf)
4181Proof
4182    METIS_TAC [lemma]
4183QED
4184
4185Theorem ext_suminf_suminf :
4186    !r. (!n. 0 <= r n) /\ ext_suminf (\n. Normal (r n)) <> PosInf ==>
4187        (ext_suminf (\n. Normal (r n)) = Normal (suminf r))
4188Proof
4189     GEN_TAC
4190  >> Suff `(!n. 0 <= r n) ==> ext_suminf (\n. Normal (r n)) <> PosInf ==>
4191           (ext_suminf (\n. Normal (r n)) = Normal (suminf r))` >- rw []
4192  >> DISCH_TAC
4193  >> Know `!n. 0 <= (\n. Normal (r n)) n`
4194  >- (RW_TAC std_ss [extreal_of_num_def, extreal_le_eq])
4195  >> DISCH_THEN (MP_TAC o (MATCH_MP ext_suminf_def)) >> Rewr'
4196  >> RW_TAC std_ss []
4197  >> `!n. FINITE (count n)` by RW_TAC std_ss [FINITE_COUNT]
4198  >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_NORMAL]
4199  >> `(\n. Normal (SIGMA r (count n))) = (\n. Normal ((\n. SIGMA r (count n)) n))` by METIS_TAC []
4200  >> POP_ORW
4201  >> `mono_increasing (\n. SIGMA r (count n))`
4202      by (RW_TAC std_ss [mono_increasing_def,GSYM extreal_le_def]
4203          >> FULL_SIMP_TAC std_ss [GSYM EXTREAL_SUM_IMAGE_NORMAL]
4204          >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_MONO_SET
4205          >> RW_TAC std_ss [extreal_le_def,extreal_of_num_def,SUBSET_DEF,IN_COUNT]
4206          >> DECIDE_TAC)
4207  >> RW_TAC std_ss [GSYM sup_seq]
4208  >> FULL_SIMP_TAC std_ss [suminf,sums,REAL_SUM_IMAGE_EQ_sum]
4209  >> RW_TAC std_ss []
4210  >> SELECT_ELIM_TAC
4211  >> RW_TAC std_ss []
4212  >> FULL_SIMP_TAC std_ss [sup_eq,le_infty]
4213  >> `!n. SIGMA (\n. Normal (r n)) (count n) <= y`
4214       by (RW_TAC std_ss []
4215           >> Q.PAT_X_ASSUM `!z. P ==> Q` MATCH_MP_TAC
4216           >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
4217           >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
4218           >> METIS_TAC [])
4219  >> `!n. 0 <= SIGMA (\n. Normal (r n)) (count n)`
4220       by (RW_TAC std_ss []
4221           >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_POS
4222           >> METIS_TAC [extreal_le_def,extreal_of_num_def])
4223  >> `y <> NegInf` by METIS_TAC [lt_infty,num_not_infty,lte_trans]
4224  >> `?z. y = Normal z` by METIS_TAC [extreal_cases]
4225  >> `!n. SIGMA r (count n) <= z` by METIS_TAC [extreal_le_def,EXTREAL_SUM_IMAGE_NORMAL]
4226  >> RW_TAC std_ss [GSYM convergent]
4227  >> MATCH_MP_TAC SEQ_ICONV
4228  >> FULL_SIMP_TAC std_ss [GREATER_EQ,real_ge,mono_increasing_def]
4229  >> MATCH_MP_TAC SEQ_BOUNDED_2
4230  >> METIS_TAC [REAL_SUM_IMAGE_POS]
4231QED
4232
4233(* another version with functional composition *)
4234Theorem ext_suminf_suminf':
4235    !r. (!n. 0 <= r n) /\ (ext_suminf (Normal o r) < PosInf) ==>
4236        (ext_suminf (Normal o r) = Normal (suminf r))
4237Proof
4238    METIS_TAC [o_DEF, ext_suminf_suminf, lt_infty]
4239QED
4240
4241Theorem ext_suminf_mono :
4242    !f g. (!n. 0 <= g n) /\ (!n. g n <= f n) ==> (ext_suminf g <= ext_suminf f)
4243Proof
4244    rpt STRIP_TAC
4245 >> Know `!n. 0 <= f n`
4246 >- (GEN_TAC >> MATCH_MP_TAC le_trans \\
4247     Q.EXISTS_TAC `g n` >> art []) >> DISCH_TAC
4248 >> RW_TAC std_ss [ext_suminf_def, sup_le', le_sup', IN_IMAGE, IN_UNIV]
4249 >> MATCH_MP_TAC le_trans
4250 >> Q.EXISTS_TAC `SIGMA f (count n)`
4251 >> RW_TAC std_ss []
4252 >- (MATCH_MP_TAC ((REWRITE_RULE [FINITE_COUNT] o Q.ISPEC `count n`)
4253                       EXTREAL_SUM_IMAGE_MONO) \\
4254     RW_TAC std_ss [COUNT_SUC, IN_INSERT, IN_COUNT] \\
4255     DISJ1_TAC >> RW_TAC std_ss [] \\
4256     MATCH_MP_TAC pos_not_neginf >> art [])
4257 >> POP_ASSUM MATCH_MP_TAC
4258 >> Q.EXISTS_TAC `n` >> REWRITE_TAC []
4259QED
4260
4261(* removed ‘!n. 0 <= f n’ from antecedents *)
4262Theorem ext_suminf_eq :
4263    !f g. (!n. f n = g n) ==> (ext_suminf f = ext_suminf g)
4264Proof
4265    rpt STRIP_TAC
4266 >> Suff ‘f = g’ >- rw []
4267 >> rw [FUN_EQ_THM]
4268QED
4269
4270(* if the first N items of (g n) are all zero, we can shift them in suminf *)
4271Theorem ext_suminf_eq_shift :
4272    !f g N. (!n. n < N ==> g n = 0) /\ (!n. 0 <= f n /\ f n = g (n + N)) ==>
4273            (ext_suminf f = ext_suminf g)
4274Proof
4275    rpt STRIP_TAC
4276 >> Know ‘!n. 0 <= g n’
4277 >- (Q.X_GEN_TAC ‘n’ \\
4278     Cases_on ‘n < N’ >- rw [] \\
4279    ‘n = n - N + N’ by rw [] >> POP_ORW \\
4280    ‘g (n - N + N) = f (n - N)’ by rw [] >> POP_ORW >> rw [])
4281 >> DISCH_TAC
4282 >> RW_TAC std_ss [ext_suminf_def, GSYM le_antisym]
4283 >| [ (* goal 1 (of 2): easy *)
4284      rw [sup_le', le_sup'] \\
4285      FIRST_X_ASSUM MATCH_MP_TAC \\
4286      Q.EXISTS_TAC ‘n + N’ \\
4287      MATCH_MP_TAC EXTREAL_SUM_IMAGE_EQ_SHIFT >> rw [],
4288      (* goal 1 (of 2): hard *)
4289      rw [sup_le', le_sup'] \\
4290      Cases_on ‘n < N’
4291      >- (Know ‘SIGMA g (count n) = 0’
4292          >- (MATCH_MP_TAC EXTREAL_SUM_IMAGE_0 >> rw []) >> Rewr' \\
4293          FIRST_X_ASSUM MATCH_MP_TAC \\
4294          Q.EXISTS_TAC ‘0’ >> rw [EXTREAL_SUM_IMAGE_EMPTY]) \\
4295      FIRST_X_ASSUM MATCH_MP_TAC \\
4296     ‘n = n - N + N’ by rw [] >> POP_ORW \\
4297      Q.EXISTS_TAC ‘n - N’ \\
4298      ONCE_REWRITE_TAC [EQ_SYM_EQ] \\
4299      MATCH_MP_TAC EXTREAL_SUM_IMAGE_EQ_SHIFT >> rw [] ]
4300QED
4301
4302Theorem ext_suminf_sub :
4303    !f g. (!n. 0 <= g n /\ g n <= f n) /\ ext_suminf f <> PosInf ==>
4304          (ext_suminf (\i. f i - g i) = ext_suminf f - ext_suminf g)
4305Proof
4306    RW_TAC std_ss []
4307 >> `!n. 0 <= g n` by PROVE_TAC []
4308 >> `!n. 0 <= f n` by PROVE_TAC [le_trans]
4309 >> Know `ext_suminf g <= ext_suminf f`
4310 >- (RW_TAC std_ss [ext_suminf_def, sup_le', le_sup', IN_IMAGE, IN_UNIV] \\
4311     MATCH_MP_TAC le_trans \\
4312     Q.EXISTS_TAC `SIGMA f (count n)` \\
4313     RW_TAC std_ss []
4314     >- (MATCH_MP_TAC ((REWRITE_RULE [FINITE_COUNT] o Q.ISPEC `count n`)
4315                         EXTREAL_SUM_IMAGE_MONO) \\
4316         RW_TAC std_ss [IN_COUNT] \\
4317         DISJ1_TAC \\
4318         METIS_TAC [lt_infty, lte_trans, num_not_infty, le_trans]) \\
4319     POP_ASSUM MATCH_MP_TAC \\
4320     Q.EXISTS_TAC `n` >> REWRITE_TAC []) >> DISCH_TAC
4321 >> `ext_suminf g <> PosInf` by METIS_TAC [lt_infty,let_trans]
4322 >> `!n. f n <> PosInf` by METIS_TAC [ext_suminf_lt_infty,le_trans,lt_infty]
4323 >> `!n. g n <> PosInf` by METIS_TAC [ext_suminf_lt_infty,lt_infty]
4324 >> `!n. f n <> NegInf` by METIS_TAC [lt_infty,lte_trans,num_not_infty,le_trans]
4325 >> `!n. g n <> NegInf` by METIS_TAC [lt_infty,lte_trans,num_not_infty]
4326 >> `?p. !n. f n = Normal (p n)`
4327       by (Q.EXISTS_TAC `(\n. @r. f n = Normal r)`
4328           >> RW_TAC std_ss []
4329           >> SELECT_ELIM_TAC
4330           >> METIS_TAC [extreal_cases])
4331 >> `?q. !n. g n = Normal (q n)`
4332       by (Q.EXISTS_TAC `(\n. @r. g n = Normal r)`
4333           >> RW_TAC std_ss []
4334           >> SELECT_ELIM_TAC
4335           >> METIS_TAC [extreal_cases])
4336 >> `f = (\n. Normal (p n))` by METIS_TAC []
4337 >> `g = (\n. Normal (q n))` by METIS_TAC []
4338 >> FULL_SIMP_TAC std_ss []
4339 >> FULL_SIMP_TAC std_ss [extreal_sub_def, extreal_le_def,
4340                          extreal_not_infty, extreal_of_num_def]
4341 >> `!n. p n - q n <= p n`
4342       by METIS_TAC [REAL_LE_SUB_RADD, REAL_ADD_COMM, REAL_LE_ADDR]
4343 >> Know `ext_suminf (\i. Normal (p i - q i)) <> PosInf`
4344 >- (`!n. Normal (p n - q n) <= Normal (p n)` by METIS_TAC [extreal_le_def] \\
4345     Know `ext_suminf (\i. Normal (p i - q i)) <= ext_suminf (\n. Normal (p n))`
4346     >- (MATCH_MP_TAC ext_suminf_mono \\
4347         RW_TAC std_ss [extreal_le_eq, extreal_of_num_def] \\
4348         METIS_TAC [REAL_SUB_LE]) >> DISCH_TAC \\
4349     METIS_TAC [lt_infty, let_trans])
4350 >> `!n. 0 <= p n` by METIS_TAC [REAL_LE_TRANS]
4351 >> `!n. 0 <= p n - q n` by METIS_TAC [REAL_SUB_LE]
4352 >> RW_TAC std_ss [ext_suminf_suminf, extreal_sub_def]
4353 (* stage work *)
4354 >> Know `!n. 0 <= (\n. Normal (p n)) n`
4355 >- RW_TAC std_ss [extreal_of_num_def, extreal_le_eq]
4356 >> DISCH_THEN (MP_TAC o (MATCH_MP ext_suminf_def))
4357 >> DISCH_THEN ((FULL_SIMP_TAC bool_ss) o wrap)
4358 >> Know `!n. 0 <= (\n. Normal (q n)) n`
4359 >- RW_TAC std_ss [extreal_of_num_def, extreal_le_eq]
4360 >> DISCH_THEN (MP_TAC o (MATCH_MP ext_suminf_def))
4361 >> DISCH_THEN ((FULL_SIMP_TAC bool_ss) o wrap)
4362 >> Know `!n. 0 <= (\i. Normal (p i - q i)) n`
4363 >- RW_TAC std_ss [extreal_of_num_def, extreal_sub_def, extreal_le_eq]
4364 >> DISCH_THEN (MP_TAC o (MATCH_MP ext_suminf_def))
4365 >> DISCH_THEN ((FULL_SIMP_TAC bool_ss) o wrap)
4366 >> FULL_SIMP_TAC std_ss [sup_eq', le_infty, IN_IMAGE, IN_UNIV]
4367 >> Know `!n. SIGMA (\n. Normal (p n)) (count n) <= y`
4368 >- (RW_TAC std_ss [] \\
4369     FIRST_X_ASSUM MATCH_MP_TAC \\
4370     Q.EXISTS_TAC `n` >> REWRITE_TAC []) >> DISCH_TAC
4371 >> Know `!n. SIGMA (\n. Normal (q n)) (count n) <= y'`
4372 >- (RW_TAC std_ss [] \\
4373     FIRST_X_ASSUM MATCH_MP_TAC \\
4374     Q.EXISTS_TAC `n` >> REWRITE_TAC []) >> DISCH_TAC
4375 >> Know `!n. SIGMA (\n. Normal (p n - q n)) (count n) <= y''`
4376 >- (RW_TAC std_ss [] \\
4377     FIRST_X_ASSUM MATCH_MP_TAC \\
4378     Q.EXISTS_TAC `n` >> REWRITE_TAC []) >> DISCH_TAC
4379 >> Q.PAT_X_ASSUM `!z. Q ==> (z <= y)`   K_TAC
4380 >> Q.PAT_X_ASSUM `!z. Q ==> (z <= y')`  K_TAC
4381 >> Q.PAT_X_ASSUM `!z. Q ==> (z <= y'')` K_TAC
4382 >> Q.PAT_X_ASSUM `sup a <= sup b`       K_TAC
4383 >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_NORMAL, FINITE_COUNT]
4384 >> `0 <= y` by METIS_TAC [REAL_SUM_IMAGE_POS,FINITE_COUNT,extreal_le_def,
4385                            extreal_of_num_def,le_trans]
4386 >> `0 <= y'` by METIS_TAC [REAL_SUM_IMAGE_POS,FINITE_COUNT,extreal_le_def,
4387                             extreal_of_num_def,le_trans]
4388 >> `0 <= SIGMA (\n. p n - q n) (count n)`
4389       by (MATCH_MP_TAC REAL_SUM_IMAGE_POS
4390           >> RW_TAC std_ss [FINITE_COUNT])
4391 >> `0 <= y''` by METIS_TAC [extreal_le_def,extreal_of_num_def,le_trans]
4392 >> `y <> NegInf /\ y' <> NegInf /\ y'' <> NegInf`
4393       by METIS_TAC [lt_infty,num_not_infty,lte_trans]
4394 >> `?z. y = Normal z` by METIS_TAC [extreal_cases]
4395 >> `?z'. y' = Normal z'` by METIS_TAC [extreal_cases]
4396 >> `?z''. y'' = Normal z''` by METIS_TAC [extreal_cases]
4397 >> FULL_SIMP_TAC std_ss [extreal_le_def, extreal_not_infty]
4398 >> RW_TAC std_ss [suminf, sums]
4399 >> SELECT_ELIM_TAC
4400 >> RW_TAC std_ss []
4401 >- (RW_TAC std_ss [GSYM convergent]
4402      >> MATCH_MP_TAC SEQ_ICONV
4403      >> RW_TAC std_ss [GREATER_EQ,real_ge]
4404      >- (MATCH_MP_TAC SEQ_BOUNDED_2
4405          >> RW_TAC std_ss [REAL_SUM_IMAGE_EQ_sum]
4406          >> Q.EXISTS_TAC `0` >> Q.EXISTS_TAC `z''`
4407          >> RW_TAC std_ss []
4408          >> MATCH_MP_TAC REAL_SUM_IMAGE_POS
4409          >> RW_TAC std_ss [FINITE_COUNT])
4410      >> RW_TAC std_ss [REAL_SUM_IMAGE_EQ_sum,GSYM extreal_le_def]
4411      >> FULL_SIMP_TAC std_ss [FINITE_COUNT,GSYM EXTREAL_SUM_IMAGE_NORMAL]
4412      >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_MONO_SET
4413      >> RW_TAC std_ss [extreal_le_def,extreal_of_num_def,FINITE_COUNT,SUBSET_DEF,IN_COUNT]
4414      >> DECIDE_TAC)
4415 >> SELECT_ELIM_TAC
4416 >> RW_TAC std_ss []
4417 >- (RW_TAC std_ss [GSYM convergent]
4418      >> MATCH_MP_TAC SEQ_ICONV
4419      >> RW_TAC std_ss [GREATER_EQ,real_ge]
4420      >- (MATCH_MP_TAC SEQ_BOUNDED_2
4421          >> RW_TAC std_ss [REAL_SUM_IMAGE_EQ_sum]
4422          >> Q.EXISTS_TAC `0` >> Q.EXISTS_TAC `z`
4423          >> RW_TAC std_ss []
4424          >> MATCH_MP_TAC REAL_SUM_IMAGE_POS
4425          >> RW_TAC std_ss [FINITE_COUNT])
4426      >> RW_TAC std_ss [REAL_SUM_IMAGE_EQ_sum,GSYM extreal_le_def]
4427      >> FULL_SIMP_TAC std_ss [FINITE_COUNT,GSYM EXTREAL_SUM_IMAGE_NORMAL]
4428      >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_MONO_SET
4429      >> RW_TAC std_ss [extreal_le_def,extreal_of_num_def,FINITE_COUNT,SUBSET_DEF,IN_COUNT]
4430      >> DECIDE_TAC)
4431 >> SELECT_ELIM_TAC
4432 >> RW_TAC std_ss []
4433 >- (RW_TAC std_ss [GSYM convergent]
4434      >> MATCH_MP_TAC SEQ_ICONV
4435      >> RW_TAC std_ss [GREATER_EQ,real_ge]
4436      >- (MATCH_MP_TAC SEQ_BOUNDED_2
4437          >> RW_TAC std_ss [REAL_SUM_IMAGE_EQ_sum]
4438          >> Q.EXISTS_TAC `0` >> Q.EXISTS_TAC `z'`
4439          >> RW_TAC std_ss []
4440          >> MATCH_MP_TAC REAL_SUM_IMAGE_POS
4441          >> RW_TAC std_ss [FINITE_COUNT])
4442      >> RW_TAC std_ss [REAL_SUM_IMAGE_EQ_sum,GSYM extreal_le_def]
4443      >> FULL_SIMP_TAC std_ss [FINITE_COUNT,GSYM EXTREAL_SUM_IMAGE_NORMAL]
4444      >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_MONO_SET
4445      >> RW_TAC std_ss [extreal_le_def,extreal_of_num_def,FINITE_COUNT,SUBSET_DEF,IN_COUNT]
4446      >> DECIDE_TAC)
4447 >> Suff `(\n. sum (0,n) (\i. p i - q i)) --> (x' - x'')` >- METIS_TAC [SEQ_UNIQ]
4448 >> FULL_SIMP_TAC std_ss [REAL_SUM_IMAGE_EQ_sum]
4449 >> `(\n. SIGMA (\i. p i - q i) (count n)) =
4450     (\n. (\n. SIGMA p (count n)) n - (\n.  SIGMA q (count n)) n)`
4451        by (RW_TAC std_ss [FUN_EQ_THM,real_sub]
4452            >> `-SIGMA q (count n') = SIGMA (\x. - q x) (count n')`
4453                by METIS_TAC [REAL_NEG_MINUS1,REAL_SUM_IMAGE_CMUL,FINITE_COUNT]
4454            >> RW_TAC std_ss [REAL_SUM_IMAGE_ADD,FINITE_COUNT])
4455 >> POP_ORW
4456 >> MATCH_MP_TAC SEQ_SUB
4457 >> RW_TAC std_ss []
4458QED
4459
4460Theorem ext_suminf_sum :
4461    !f n. (!n. 0 <= f n) /\ (!m. n <= m ==> (f m = 0)) ==>
4462          (ext_suminf f = SIGMA f (count n))
4463Proof
4464    rpt STRIP_TAC
4465 >> RW_TAC std_ss [ext_suminf_def, sup_eq', IN_IMAGE, IN_UNIV]
4466 >- (Cases_on `n' <= n`
4467     >- (MATCH_MP_TAC EXTREAL_SUM_IMAGE_MONO_SET \\
4468         RW_TAC real_ss [SUBSET_DEF, IN_COUNT, FINITE_COUNT])
4469     >> `count n SUBSET (count n')` by METIS_TAC [IN_COUNT,NOT_LESS_EQUAL,SUBSET_DEF,LESS_TRANS]
4470     >> `count n' = (count n) UNION (count n' DIFF (count n))` by METIS_TAC [UNION_DIFF]
4471     >> POP_ORW
4472     >> `DISJOINT (count n) (count n' DIFF count n)` by METIS_TAC [DISJOINT_DIFF]
4473     >> `!n. f n <> NegInf` by METIS_TAC [lt_infty,extreal_of_num_def,lte_trans]
4474     >> RW_TAC std_ss [FINITE_COUNT, EXTREAL_SUM_IMAGE_DISJOINT_UNION]
4475     >> `FINITE (count n' DIFF count n)` by METIS_TAC [FINITE_COUNT,FINITE_DIFF]
4476     >> (MP_TAC o (REWRITE_RULE [FINITE_COUNT]) o
4477         (Q.ISPECL [`count n`, `count n' DIFF count n`])) EXTREAL_SUM_IMAGE_DISJOINT_UNION
4478     >> RW_TAC std_ss []
4479     >> POP_ASSUM (MP_TAC o Q.SPEC `f`)
4480     >> RW_TAC std_ss []
4481     >> Suff `SIGMA f (count n' DIFF count n) = 0`
4482     >- RW_TAC std_ss [add_rzero,le_refl]
4483     >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_0
4484     >> RW_TAC std_ss [IN_COUNT,IN_DIFF]
4485     >> METIS_TAC [NOT_LESS])
4486 >> POP_ASSUM MATCH_MP_TAC
4487 >> Q.EXISTS_TAC `n` >> REWRITE_TAC []
4488QED
4489
4490Overload suminf = ``ext_suminf``
4491
4492Theorem ext_suminf_zero:   !f. (!n. f n = 0) ==> (ext_suminf f = 0)
4493Proof
4494    rpt STRIP_TAC
4495 >> ASSUME_TAC (Q.SPECL [`f`, `0`] ext_suminf_sum)
4496 >> `0 = SIGMA f (count 0)` by PROVE_TAC [COUNT_ZERO, EXTREAL_SUM_IMAGE_EMPTY]
4497 >> POP_ASSUM (ONCE_REWRITE_TAC o wrap)
4498 >> POP_ASSUM MATCH_MP_TAC
4499 >> RW_TAC std_ss [le_refl]
4500QED
4501
4502(* |- suminf (\n. 0) = 0 *)
4503Theorem ext_suminf_0 = SIMP_RULE std_ss [] (Q.SPEC `\n. 0` ext_suminf_zero);
4504
4505Theorem ext_suminf_pos :
4506    !f. (!n. 0 <= f n) ==> (0 <= ext_suminf f)
4507Proof
4508    rpt STRIP_TAC
4509 >> MATCH_MP_TAC (REWRITE_RULE [ext_suminf_0]
4510                               (Q.SPECL [`f`, `\n. 0`] ext_suminf_mono))
4511 >> rw [le_refl]
4512QED
4513
4514Theorem ext_suminf_sing:
4515    !r. 0 <= r ==> (ext_suminf (\n. if n = 0 then r else 0) = r)
4516Proof
4517    GEN_TAC >> STRIP_TAC
4518 >> Q.ABBREV_TAC `f = (\n :num. if n = 0 then r else 0)`
4519 >> Suff `ext_suminf f = SIGMA f (count 1)`
4520 >- (Rewr >> REWRITE_TAC [ONE, COUNT_SUC, COUNT_ZERO] \\
4521     REWRITE_TAC [EXTREAL_SUM_IMAGE_SING] \\
4522     Q.UNABBREV_TAC `f` >> SIMP_TAC std_ss [])
4523 >> MATCH_MP_TAC ext_suminf_sum
4524 >> Q.UNABBREV_TAC `f`
4525 >> SIMP_TAC arith_ss []
4526 >> METIS_TAC [le_refl]
4527QED
4528
4529(* finite version of ext_suminf_add *)
4530Theorem ext_suminf_sigma :
4531    !f n. (!i x. i < n ==> 0 <= f i x) ==>
4532          (SIGMA (ext_suminf o f) (count n) = ext_suminf (\x. SIGMA (\i. f i x) (count n)))
4533Proof
4534    REWRITE_TAC [o_DEF]
4535 >> GEN_TAC >> Induct_on `n`
4536 >- (DISCH_TAC >> REWRITE_TAC [COUNT_ZERO, EXTREAL_SUM_IMAGE_EMPTY] \\
4537     MATCH_MP_TAC EQ_SYM >> MATCH_MP_TAC ext_suminf_zero \\
4538     BETA_TAC >> REWRITE_TAC [])
4539 >> RW_TAC std_ss [COUNT_SUC]
4540 >> Know `SIGMA (\i. suminf (f i)) (n INSERT count n) =
4541          (\i. suminf (f i)) n + SIGMA (\i. suminf (f i)) (count n DELETE n)`
4542 >- (irule EXTREAL_SUM_IMAGE_PROPERTY \\
4543     REWRITE_TAC [FINITE_COUNT, IN_INSERT, IN_COUNT] \\
4544     DISJ1_TAC >> GEN_TAC >> DISCH_TAC >> BETA_TAC \\
4545     MATCH_MP_TAC pos_not_neginf \\
4546     MATCH_MP_TAC ext_suminf_pos \\
4547     GEN_TAC >> POP_ASSUM STRIP_ASSUME_TAC \\ (* 2 subgoals, same tactics *)
4548    `x < SUC n` by RW_TAC arith_ss [] >> PROVE_TAC [])
4549 >> Rewr' >> BETA_TAC >> REWRITE_TAC [COUNT_DELETE]
4550 >> Know `!i x. i < n ==> 0 <= f i x`
4551 >- (rpt STRIP_TAC >> `i < SUC n` by RW_TAC arith_ss [] >> PROVE_TAC [])
4552 >> DISCH_TAC >> RES_TAC >> POP_ORW
4553 >> Q.PAT_X_ASSUM `X ==> Y` K_TAC
4554 >> Know `!x. SIGMA (\i. f i x) (n INSERT count n) =
4555              (\i. f i x) n + SIGMA (\i. f i x) (count n DELETE n)`
4556 >- (GEN_TAC >> irule EXTREAL_SUM_IMAGE_PROPERTY \\
4557     REWRITE_TAC [FINITE_COUNT, IN_INSERT, IN_COUNT] \\
4558     DISJ1_TAC >> GEN_TAC >> DISCH_TAC >> BETA_TAC \\
4559     MATCH_MP_TAC pos_not_neginf \\
4560     POP_ASSUM STRIP_ASSUME_TAC \\ (* 2 subgoals, same tactics *)
4561    `x' < SUC n` by RW_TAC arith_ss [] >> PROVE_TAC [])
4562 >> Rewr' >> BETA_TAC >> REWRITE_TAC [COUNT_DELETE]
4563 >> `suminf (\x. f n x + SIGMA (\i. f i x) (count n)) =
4564     suminf (\x. (f n) x + (\y. SIGMA (\i. f i y) (count n)) x)` by PROVE_TAC []
4565 >> POP_ORW
4566 >> Suff `suminf (\x. f n x + (\y. SIGMA (\i. f i y) (count n)) x) =
4567          suminf (f n) + suminf (\x. SIGMA (\i. f i x) (count n))` >- Rewr
4568 >> MATCH_MP_TAC ext_suminf_add >> GEN_TAC >> BETA_TAC
4569 >> CONJ_TAC >- (`n < SUC n` by RW_TAC arith_ss [] >> PROVE_TAC [])
4570 >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_POS
4571 >> RW_TAC std_ss [FINITE_COUNT, IN_COUNT]
4572QED
4573
4574(* |- !f n.
4575         (!i x. i < n ==> 0 <= f i x) ==>
4576         (SIGMA (\x. suminf (f x)) (count n) =
4577          suminf (\x. SIGMA (\i. f i x) (count n))) *)
4578Theorem ext_suminf_sigma' = REWRITE_RULE [o_DEF] ext_suminf_sigma;
4579
4580Theorem lemma[local]:
4581    !f n'. (!i. (!m n. m <= n ==> (\x. f x i) m <= (\x. f x i) n)) /\
4582        (!n i. 0 <= f n i) ==>
4583        (SIGMA (\i. sup {f k i | k IN univ(:num)}) (count n') =
4584         sup {SIGMA (\i. f k i) (count n') | k IN UNIV})
4585Proof
4586  RW_TAC std_ss [] THEN Q.ABBREV_TAC `s = count n'` THEN
4587  `FINITE s` by METIS_TAC [FINITE_COUNT] THEN POP_ASSUM MP_TAC THEN
4588  Q.SPEC_TAC (`s`,`s`) THEN SET_INDUCT_TAC THENL
4589  [SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_EMPTY, IN_UNIV] THEN
4590   ONCE_REWRITE_TAC [SET_RULE ``{0 | k | T} = {0}``] THEN
4591   SIMP_TAC std_ss [sup_sing],
4592   ALL_TAC] THEN
4593  Q_TAC SUFF_TAC `sup {SIGMA (\i. f k i) s' + SIGMA (\i. f k i) {e} | k IN univ(:num)} =
4594   sup {SIGMA (\i. f k i) s' | k IN univ(:num)} +
4595   sup {SIGMA (\i. f k i) {e} | k IN univ(:num)}` THENL
4596  [ALL_TAC,
4597   SIMP_TAC std_ss [GSYM IMAGE_DEF] THEN
4598   ONCE_REWRITE_TAC [METIS [] ``SIGMA (\i. f k i) s' + SIGMA (\i. f k i) {e} =
4599     (\k. SIGMA (\i. f k i) s') k + (\k. SIGMA (\i. f k i) {e}) k``] THEN
4600   MATCH_MP_TAC sup_add_mono THEN RW_TAC std_ss [] THENL
4601   [MATCH_MP_TAC EXTREAL_SUM_IMAGE_POS THEN ASM_SIMP_TAC std_ss [],
4602    FIRST_ASSUM (MATCH_MP_TAC o MATCH_MP EXTREAL_SUM_IMAGE_MONO) THEN
4603    RW_TAC std_ss [] THEN DISJ1_TAC THEN GEN_TAC THEN
4604    SIMP_TAC std_ss [lt_infty] THEN DISCH_TAC THEN
4605    METIS_TAC [lte_trans, num_not_infty, lt_infty],
4606    ASM_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_SING],
4607    ALL_TAC] THEN
4608   RW_TAC std_ss [EXTREAL_SUM_IMAGE_SING]] THEN
4609  DISCH_TAC THEN `FINITE {e}` by SIMP_TAC std_ss [FINITE_SING] THEN
4610  `DISJOINT s' {e}` by ASM_SET_TAC [] THEN
4611  `!k.
4612   (!x. x IN (s' UNION {e}) ==> (\i. f k i) x <> NegInf) \/
4613   (!x. x IN (s' UNION {e}) ==> (\i. f k i) x <> PosInf) ==>
4614   (SIGMA (\i. f k i) (s' UNION {e}) = SIGMA (\i. f k i) s' + SIGMA (\i. f k i) {e})` by
4615   METIS_TAC [EXTREAL_SUM_IMAGE_DISJOINT_UNION] THEN
4616  Q_TAC SUFF_TAC `!k. (SIGMA (\i. f k i) (s' UNION {e}) =
4617       SIGMA (\i. f k i) s' + SIGMA (\i. f k i) {e})` THENL
4618  [ALL_TAC,
4619   GEN_TAC THEN POP_ASSUM MATCH_MP_TAC THEN DISJ1_TAC THEN
4620   RW_TAC std_ss [lt_infty] THEN METIS_TAC [lte_trans, num_not_infty, lt_infty]] THEN
4621  DISCH_TAC THEN ONCE_REWRITE_TAC [SET_RULE ``e INSERT s' = s' UNION {e}``] THEN
4622  ASM_REWRITE_TAC [] THEN
4623  `(!x. x IN s' UNION {e} ==> (\i. sup {f k i | k IN univ(:num)}) x <> NegInf) \/
4624   (!x. x IN s' UNION {e} ==> (\i. sup {f k i | k IN univ(:num)}) x <> PosInf) ==>
4625   (SIGMA (\i. sup {f k i | k IN univ(:num)}) (s' UNION {e}) =
4626    SIGMA (\i. sup {f k i | k IN univ(:num)}) s' + SIGMA (\i. sup {f k i | k IN univ(:num)}) {e})`
4627   by (MATCH_MP_TAC EXTREAL_SUM_IMAGE_DISJOINT_UNION THEN ASM_SIMP_TAC std_ss []) THEN
4628  Q_TAC SUFF_TAC `(SIGMA (\i. sup {f k i | k IN univ(:num)}) (s' UNION {e}) =
4629        SIGMA (\i. sup {f k i | k IN univ(:num)}) s' +
4630        SIGMA (\i. sup {f k i | k IN univ(:num)}) {e})` THENL
4631  [ALL_TAC,
4632   POP_ASSUM MATCH_MP_TAC THEN DISJ1_TAC THEN RW_TAC std_ss [sup_eq] THEN
4633   DISJ1_TAC THEN Q.EXISTS_TAC `f k x` THEN CONJ_TAC THENL
4634   [ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN SET_TAC [], ALL_TAC] THEN
4635   SIMP_TAC std_ss [GSYM extreal_lt_def] THEN
4636   METIS_TAC [lte_trans, num_not_infty, lt_infty]]
4637 >> Rewr'
4638 >> ASM_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_SING]
4639QED
4640
4641Theorem ext_suminf_sup_eq : (* was: suminf_SUP_eq *)
4642   !(f:num->num->extreal).
4643     (!i m n. m <= n ==> f m i <= f n i) /\
4644     (!n i. 0 <= f n i) ==>
4645     (suminf (\i. sup {f n i | n IN UNIV}) = sup {suminf (\i. f n i) | n IN UNIV})
4646Proof
4647    rpt STRIP_TAC
4648 >> Know `!n. 0 <= (\i. sup {f n i | n IN UNIV}) n`
4649 >- (RW_TAC set_ss [IN_UNIV, le_sup'] \\
4650     MATCH_MP_TAC le_trans \\
4651     Q.EXISTS_TAC `f 0 n` >> rw [] \\
4652     POP_ASSUM MATCH_MP_TAC >> Q.EXISTS_TAC `0` >> rw [])
4653 >> RW_TAC std_ss [ext_suminf_def, IMAGE_DEF]
4654 >> Suff `!n. SIGMA (\i. sup {f k i | k IN UNIV}) (count n) =
4655              sup {SIGMA (\i. f k i) (count n) | k IN UNIV}`
4656 >- (DISCH_TAC \\
4657     Know `sup {SIGMA (\i. sup {f n i | n IN UNIV}) (count n) | n IN UNIV} =
4658           sup {sup {SIGMA (\i. f k i) (count n) | k IN UNIV} | n IN UNIV}`
4659     >- (AP_TERM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN METIS_TAC []) >> Rewr' \\
4660     Know
4661    `sup {sup {(\k n. SIGMA (\i. f k i) (count n)) k n | k IN UNIV} | n IN UNIV} =
4662     sup {sup {(\k n. SIGMA (\i. f k i) (count n)) k n | n IN UNIV} | k IN UNIV}`
4663     >- (Q.ABBREV_TAC `g = (\k n. SIGMA (\i. f k i) (count n))` \\
4664         SIMP_TAC std_ss [sup_comm]) \\
4665     METIS_TAC [])
4666 >> ASM_SIMP_TAC std_ss [lemma]
4667QED
4668
4669(* ------------------------------------------------------------------------- *)
4670(*  Further theorems concerning the relationship of suminf and SIGMA         *)
4671(*  Used by the new measureTheory. (Chun Tian)                               *)
4672(* ------------------------------------------------------------------------- *)
4673
4674(* The extreal version of POS_SUMMABLE (util_probTheory) *)
4675Theorem pos_summable :
4676    !f. (!n. 0 <= f n) /\ (?r. !n. SIGMA f (count n) <= Normal r) ==>
4677        suminf f < PosInf
4678Proof
4679    GEN_TAC >> STRIP_TAC
4680 (* 1. f is a normal extreal function *)
4681 >> Know `!n. f n <> PosInf`
4682 >- (CCONTR_TAC >> FULL_SIMP_TAC bool_ss [] \\
4683     Q.PAT_X_ASSUM `!n. SIGMA f (count n) <= Normal r`
4684       (MP_TAC o (REWRITE_RULE [COUNT_SUC]) o (Q.SPEC `SUC n`)) \\
4685    `FINITE (count n)` by PROVE_TAC [FINITE_COUNT] \\
4686    `!x. x IN (n INSERT (count n)) ==> f x <> NegInf` by PROVE_TAC [le_not_infty] \\
4687     ASM_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY, GSYM extreal_lt_def] \\
4688     Suff `SIGMA f (count n DELETE n) <> NegInf`
4689     >- RW_TAC std_ss [add_infty, lt_infty] \\
4690     MATCH_MP_TAC EXTREAL_SUM_IMAGE_NOT_NEGINF \\
4691     CONJ_TAC >- PROVE_TAC [FINITE_DELETE] \\
4692     rpt STRIP_TAC >> PROVE_TAC [le_not_infty])
4693 >> DISCH_TAC
4694 (* 2. g is the real version of f, and `!n. 0 <= g n` *)
4695 >> Q.ABBREV_TAC `g = real o f`
4696 >> Know `f = \x. Normal (g x)`
4697 >- (Q.UNABBREV_TAC `g` >> REWRITE_TAC [FUN_EQ_THM] >> GEN_TAC \\
4698     REWRITE_TAC [o_DEF] >> BETA_TAC \\
4699    `!n. f n <> NegInf` by PROVE_TAC [pos_not_neginf] \\
4700     METIS_TAC [normal_real]) >> DISCH_TAC
4701 >> Know `!n. 0 <= g n`
4702 >- (Q.UNABBREV_TAC `g` >> REWRITE_TAC [o_DEF] >> BETA_TAC \\
4703     POP_ASSUM K_TAC \\ (* useless *)
4704     GEN_TAC >> `0 <= f n /\ f n <> PosInf` by PROVE_TAC [] \\
4705     Q.ABBREV_TAC `h = f n` \\
4706     Cases_on `h` >|
4707     [ REWRITE_TAC [REAL_LE_REFL, extreal_not_infty, real_def],
4708       REWRITE_TAC [REAL_LE_REFL, extreal_not_infty, real_def],
4709       REWRITE_TAC [real_normal] \\
4710       METIS_TAC [extreal_of_num_def, extreal_le_def] ]) >> DISCH_TAC
4711 (* 3. g is summable, using POS_SUMMABLE *)
4712 >> Know `summable g`
4713 >- (MATCH_MP_TAC POS_SUMMABLE >> art [] \\
4714     Q.PAT_X_ASSUM `f = \x. Normal (g x)` SUBST_ALL_TAC \\
4715     REWRITE_TAC [REAL_SUM_IMAGE_EQ_sum] \\
4716     Q.EXISTS_TAC `r` >> GEN_TAC \\
4717     REWRITE_TAC [GSYM extreal_le_eq] \\
4718     METIS_TAC [EXTREAL_SUM_IMAGE_NORMAL, FINITE_COUNT])
4719 (* stage work *)
4720 >> RW_TAC std_ss [summable, sums, REAL_SUM_IMAGE_EQ_sum]
4721 >> Q.PAT_X_ASSUM `!n. 0 <= (\x. Normal (g x)) n`
4722      (REWRITE_TAC o wrap o (MATCH_MP ext_suminf_def))
4723 (* 4. `\n. SIGMA g (count n)` is mono_increasing (for sup_seq) *)
4724 >> Know `mono_increasing (\n. SIGMA g (count n))`
4725 >- (REWRITE_TAC [mono_increasing_suc] >> BETA_TAC >> GEN_TAC \\
4726     MATCH_MP_TAC REAL_SUM_IMAGE_MONO_SET \\
4727     CONJ_TAC >- PROVE_TAC [FINITE_COUNT] \\
4728     CONJ_TAC >- PROVE_TAC [FINITE_COUNT] \\
4729     CONJ_TAC >- ( REWRITE_TAC [SUBSET_DEF, IN_COUNT] >> RW_TAC arith_ss [] ) \\
4730     rpt STRIP_TAC >> ASM_REWRITE_TAC [])
4731 >> DISCH_THEN (MP_TAC o (Q.SPEC `s`) o (MATCH_MP sup_seq))
4732 >> DISCH_THEN ((FULL_SIMP_TAC std_ss) o wrap)
4733 (* 5. now swap Normal and SIGMA *)
4734 >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_NORMAL, FINITE_COUNT, lt_infty]
4735QED
4736
4737(* the lemma is non-trivial because it depends on "pos_summable" *)
4738Theorem summable_ext_suminf:
4739    !f. (!n. 0 <= f n) /\ summable f ==> suminf (Normal o f) < PosInf
4740Proof
4741    REWRITE_TAC [o_DEF]
4742 >> rpt STRIP_TAC
4743 >> MATCH_MP_TAC pos_summable
4744 >> BETA_TAC
4745 >> CONJ_TAC >- ASM_REWRITE_TAC [extreal_le_eq, extreal_of_num_def]
4746 >> Q.EXISTS_TAC `suminf f`
4747 (* !n. SIGMA (\n. Normal (f n)) (count n) <= Normal (suminf f) *)
4748 >> GEN_TAC
4749 >> Know `SIGMA (\n. Normal (f n)) (count n) = Normal (SIGMA f (count n))`
4750 >- (MATCH_MP_TAC EXTREAL_SUM_IMAGE_NORMAL >> METIS_TAC [FINITE_COUNT])
4751 >> DISCH_THEN (REWRITE_TAC o wrap)
4752 >> REWRITE_TAC [extreal_le_eq]
4753 (* SIGMA f (count n) <= suminf f *)
4754 >> REWRITE_TAC [REAL_SUM_IMAGE_COUNT]
4755 >> MATCH_MP_TAC SER_POS_LE
4756 >> METIS_TAC []
4757QED
4758
4759Theorem summable_ext_suminf_suminf:
4760    !f. (!n. 0 <= f n) /\ summable f ==> (suminf (Normal o f) = Normal (suminf f))
4761Proof
4762    rpt STRIP_TAC
4763 >> MATCH_MP_TAC ext_suminf_suminf'
4764 >> ASM_REWRITE_TAC [lt_infty]
4765 >> MATCH_MP_TAC summable_ext_suminf
4766 >> ASM_REWRITE_TAC []
4767QED
4768
4769(* added `(!n. 0 <= f n)`, otherwise not true *)
4770Theorem EXTREAL_SUM_IMAGE_le_suminf :
4771    !f n. (!n. 0 <= f n) ==> SIGMA f (count n) <= ext_suminf f
4772Proof
4773    rpt STRIP_TAC
4774 >> ASM_SIMP_TAC std_ss [ext_suminf_def]
4775 >> MATCH_MP_TAC le_sup_imp'
4776 >> RW_TAC std_ss [IN_IMAGE, IN_UNIV]
4777 >> Q.EXISTS_TAC `n` >> REWRITE_TAC []
4778QED
4779
4780Theorem ext_suminf_summable :
4781    !g. (!n. 0 <= g n) /\ suminf g < PosInf ==> summable (real o g)
4782Proof
4783    rpt STRIP_TAC
4784 >> Know `!n. g n < PosInf`
4785 >- (MATCH_MP_TAC ext_suminf_lt_infty \\
4786     METIS_TAC [lt_infty]) >> DISCH_TAC
4787 >> Q.ABBREV_TAC `f = real o g`
4788 >> Know `g = \n. Normal (f n)`
4789 >- (RW_TAC std_ss [FUN_EQ_THM] \\
4790     Q.UNABBREV_TAC `f` >> RW_TAC std_ss [o_DEF] \\
4791     MATCH_MP_TAC EQ_SYM \\
4792     MATCH_MP_TAC normal_real \\
4793     METIS_TAC [lt_infty, pos_not_neginf]) >> DISCH_TAC
4794 >> MATCH_MP_TAC POS_SUMMABLE
4795 >> CONJ_TAC
4796 >- (Q.UNABBREV_TAC `f` >> GEN_TAC >> RW_TAC std_ss [o_DEF] \\
4797     REWRITE_TAC [GSYM extreal_le_eq, GSYM extreal_of_num_def] \\
4798     Know `Normal (real (g n)) = g n`
4799     >- (MATCH_MP_TAC normal_real >> METIS_TAC [lt_infty, pos_not_neginf]) \\
4800     DISCH_THEN (REWRITE_TAC o wrap) >> ASM_REWRITE_TAC [])
4801 >> Q.EXISTS_TAC `real (suminf g)`
4802 >> GEN_TAC >> REWRITE_TAC [GSYM REAL_SUM_IMAGE_COUNT]
4803 >> REWRITE_TAC [GSYM extreal_le_eq]
4804 >> `0 <= suminf g` by PROVE_TAC [ext_suminf_pos]
4805 >> Know `Normal (real (suminf g)) = suminf g`
4806 >- (MATCH_MP_TAC normal_real >> METIS_TAC [lt_infty, pos_not_neginf])
4807 >> DISCH_THEN (REWRITE_TAC o wrap)
4808 (* Normal (SIGMA f (count n)) <= suminf g *)
4809 >> Know `Normal (SIGMA f (count n)) = SIGMA (\n. Normal (f n)) (count n)`
4810 >- (MATCH_MP_TAC EQ_SYM \\
4811     MATCH_MP_TAC EXTREAL_SUM_IMAGE_NORMAL >> PROVE_TAC [FINITE_COUNT])
4812 >> DISCH_THEN (REWRITE_TAC o wrap)
4813 >> Q.PAT_X_ASSUM `g = (\n. Normal (f n))` (REWRITE_TAC o wrap o SYM)
4814 (* SIGMA g (count n) <= suminf g *)
4815 >> ASM_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_le_suminf]
4816QED
4817
4818Theorem ext_suminf_real_suminf:
4819    !g. (!n. 0 <= g n) /\ suminf g < PosInf ==> (suminf (real o g) = real (suminf g))
4820Proof
4821    rpt STRIP_TAC
4822 >> Know `!n. g n < PosInf`
4823 >- (MATCH_MP_TAC ext_suminf_lt_infty \\
4824     METIS_TAC [lt_infty])
4825 >> DISCH_TAC
4826 >> Know `!n. Normal (real (g n)) = g n`
4827 >- (GEN_TAC >> MATCH_MP_TAC normal_real >> METIS_TAC [lt_infty, pos_not_neginf])
4828 >> DISCH_TAC
4829 >> `summable (real o g)` by PROVE_TAC [ext_suminf_summable]
4830 >> REWRITE_TAC [GSYM extreal_11]
4831 >> `0 <= suminf g` by PROVE_TAC [ext_suminf_pos]
4832 >> Know `Normal (real (suminf g)) = suminf g`
4833 >- (MATCH_MP_TAC normal_real >> METIS_TAC [lt_infty, pos_not_neginf])
4834 >> DISCH_THEN (REWRITE_TAC o wrap)
4835 >> Know `Normal (suminf (real o g)) = suminf (\n. Normal ((real o g) n))`
4836 >- (MATCH_MP_TAC EQ_SYM >> MATCH_MP_TAC ext_suminf_suminf \\
4837     RW_TAC std_ss [o_DEF] >| (* 2 subgoals *)
4838     [ (* goal 1 (of 2) *)
4839       REWRITE_TAC [GSYM extreal_le_eq, GSYM extreal_of_num_def] \\
4840       ASM_REWRITE_TAC [],
4841       (* goal 2 (of 2) *)
4842       METIS_TAC [lt_infty] ])
4843 >> DISCH_THEN (REWRITE_TAC o wrap)
4844 >> ASM_SIMP_TAC std_ss [o_DEF]
4845 >> REWRITE_TAC [ETA_AX]
4846QED
4847
4848Theorem SUMINF_2D_suminf[local]:
4849    !(f :num -> num -> real) (g :num -> real) (h :num -> num # num).
4850       (!m n. 0 <= f m n) /\ (!n. summable (f n) /\ (suminf (f n) = g n)) /\ summable g /\
4851       BIJ h UNIV (UNIV CROSS UNIV) ==>
4852       (suminf (UNCURRY f o h) = suminf g)
4853Proof
4854    rpt STRIP_TAC
4855 >> MATCH_MP_TAC EQ_SYM
4856 >> MATCH_MP_TAC SUM_UNIQ
4857 >> MATCH_MP_TAC SUMINF_2D
4858 >> ASM_REWRITE_TAC []
4859 >> GEN_TAC
4860 >> `summable (f n)` by METIS_TAC []
4861 >> METIS_TAC [SUMMABLE_SUM]
4862QED
4863
4864Theorem SUMINF_2D_summable[local]:
4865    !(f :num -> num -> real) (g :num -> real) (h :num -> num # num).
4866       (!m n. 0 <= f m n) /\ (!n. summable (f n) /\ (suminf (f n) = g n)) /\ summable g /\
4867       BIJ h UNIV (UNIV CROSS UNIV) ==>
4868       summable (UNCURRY f o h)
4869Proof
4870    rpt STRIP_TAC
4871 >> REWRITE_TAC [summable]
4872 >> Q.EXISTS_TAC `suminf g`
4873 >> MATCH_MP_TAC SUMINF_2D
4874 >> ASM_REWRITE_TAC []
4875 >> GEN_TAC
4876 >> Suff `f n sums suminf (f n)` >- METIS_TAC []
4877 >> MATCH_MP_TAC SUMMABLE_SUM
4878 >> ASM_REWRITE_TAC []
4879QED
4880
4881(* extreal version of SUMINF_2D, based on SUMINF_2D_suminf and SUMINF_2D_summable,
4882   c.f. ext_suminf_2d_infinite (more general, proved from scratch)
4883 *)
4884Theorem ext_suminf_2d :
4885    !(f :num -> num -> extreal) (g :num -> extreal) (h :num -> num # num).
4886      (!m n. 0 <= f m n) /\
4887      (!n. ext_suminf (f n) = g n) /\  (* f n sums g n *)
4888      (ext_suminf g < PosInf) /\       (* summable g *)
4889      BIJ h UNIV (UNIV CROSS UNIV)
4890     ==>
4891      (ext_suminf (UNCURRY f o h) = ext_suminf g)
4892Proof
4893 (* general properties of g and f *)
4894    rpt STRIP_TAC
4895 >> `!n. 0 <= g n` by PROVE_TAC [ext_suminf_pos]
4896 >> `!n. g n < PosInf` by PROVE_TAC [ext_suminf_lt_infty]
4897 >> `!n. g n <> PosInf /\ g n <> NegInf` by PROVE_TAC [GSYM lt_infty, pos_not_neginf]
4898 >> `!x. 0 <= UNCURRY f x` by METIS_TAC [UNCURRY]
4899 >> Know `!m n. f m n < PosInf`
4900 >- (GEN_TAC >> MATCH_MP_TAC ext_suminf_lt_infty \\
4901     CONJ_TAC >- ASM_REWRITE_TAC [] \\
4902     METIS_TAC [lt_infty]) >> DISCH_TAC
4903 >> `!m n. f m n <> PosInf /\ f m n <> NegInf`
4904        by PROVE_TAC [GSYM lt_infty, pos_not_neginf]
4905 (* properties of `UNCURRY f` *)
4906 >> `!x. UNCURRY f x < PosInf` by METIS_TAC [UNCURRY]
4907 >> `!x. UNCURRY f x <> PosInf /\ UNCURRY f x <> NegInf`
4908        by PROVE_TAC [GSYM lt_infty, pos_not_neginf]
4909 (* convert g into real function g' *)
4910 >> Q.ABBREV_TAC `g' = real o g`
4911 >> Know `g = \x. Normal (g' x)`
4912 >- (Q.UNABBREV_TAC `g'` >> REWRITE_TAC [FUN_EQ_THM] >> GEN_TAC \\
4913     REWRITE_TAC [o_DEF] >> BETA_TAC \\
4914     METIS_TAC [normal_real])
4915 >> DISCH_TAC
4916 >> ASM_REWRITE_TAC []
4917 (* properties of g' *)
4918 >> Know `summable g'`
4919 >- (Q.UNABBREV_TAC `g'` \\
4920     MATCH_MP_TAC ext_suminf_summable >> ASM_REWRITE_TAC [])
4921 >> DISCH_TAC
4922 (* RHS reduce of the goal *)
4923 >> Know `suminf (\x. Normal (g' x)) = Normal (suminf g')`
4924 >- (MATCH_MP_TAC ext_suminf_suminf \\
4925     reverse CONJ_TAC >- fs [GSYM lt_infty] \\
4926     Q.UNABBREV_TAC `g'` >> REWRITE_TAC [o_DEF] >> BETA_TAC \\
4927     REWRITE_TAC [GSYM extreal_le_eq] \\
4928     GEN_TAC >> REWRITE_TAC [GSYM extreal_of_num_def] \\
4929     METIS_TAC [normal_real])
4930 >> DISCH_THEN (REWRITE_TAC o wrap)
4931 (* convert f into real function f' *)
4932 >> Q.ABBREV_TAC `(f' :num -> num -> real) = (\n. real o f n)`
4933 >> Know `f = (\n. Normal o f' n)`
4934 >- (Q.UNABBREV_TAC `f'` >> REWRITE_TAC [FUN_EQ_THM] >> GEN_TAC \\
4935     REWRITE_TAC [o_DEF] >> BETA_TAC \\
4936     METIS_TAC [normal_real]) >> DISCH_TAC
4937 >> `!m n. Normal (f' m n) = f m n` by METIS_TAC [o_DEF]
4938 (* properties of f' *)
4939 >> Know `!m n. 0 <= f' m n`
4940 >- (NTAC 2 GEN_TAC \\
4941     REWRITE_TAC [GSYM extreal_le_eq, GSYM extreal_of_num_def] \\
4942     METIS_TAC []) >> DISCH_TAC
4943 >> Know `!n. summable (f' n)`
4944 >- (GEN_TAC >> Q.UNABBREV_TAC `f'` >> BETA_TAC \\
4945     MATCH_MP_TAC ext_suminf_summable >> METIS_TAC []) >> DISCH_TAC
4946 >> Know `!n. suminf (f' n) = g' n`
4947 >- (GEN_TAC >> REWRITE_TAC [GSYM extreal_11] \\
4948     Q.PAT_X_ASSUM `g = X`
4949        (REWRITE_TAC o wrap o (SIMP_RULE std_ss [FUN_EQ_THM]) o (MATCH_MP EQ_SYM)) \\
4950     Know `Normal (suminf (f' n)) = suminf (\m. Normal ((f' n) m))`
4951     >- (MATCH_MP_TAC EQ_SYM >> MATCH_MP_TAC ext_suminf_suminf \\
4952         ASM_REWRITE_TAC [] >> BETA_TAC >> METIS_TAC [o_DEF]) >> Rewr \\
4953     Q.PAT_X_ASSUM `!m n. Normal (f' m n) = f m n` (REWRITE_TAC o wrap) \\
4954     METIS_TAC []) >> DISCH_TAC
4955 (* applying SUMINF_2D_summable *)
4956 >> Know `summable (UNCURRY f' o h)`
4957 >- (MATCH_MP_TAC SUMINF_2D_summable \\
4958     Q.EXISTS_TAC `g'` >> ASM_REWRITE_TAC []) >> DISCH_TAC
4959 >> `!n. 0 <= (UNCURRY f' o h) n` by RW_TAC std_ss [o_DEF, UNCURRY]
4960 >> Know `UNCURRY f o h = Normal o (UNCURRY f' o h)`
4961 >- (ASM_REWRITE_TAC [] \\
4962     PURE_ONCE_REWRITE_TAC [o_DEF] \\
4963     PURE_ONCE_REWRITE_TAC [UNCURRY] \\
4964     REWRITE_TAC [o_DEF, UNCURRY] \\
4965     METIS_TAC []) >> DISCH_TAC
4966 (* using summable_ext_suminf, indirectly uses "pos_summable"! *)
4967 >> Know `suminf (UNCURRY f o h) < PosInf`
4968 >- (ASM_REWRITE_TAC [] \\
4969     MATCH_MP_TAC summable_ext_suminf >> ASM_REWRITE_TAC []) >> DISCH_TAC
4970 >> ASM_REWRITE_TAC []
4971 (* LHS reduce of the goal *)
4972 >> Know `suminf (Normal o UNCURRY f' o h) = Normal (suminf (UNCURRY f' o h))`
4973 >- (MATCH_MP_TAC ext_suminf_suminf' \\
4974     ASM_REWRITE_TAC [lt_infty] \\
4975     Q.PAT_X_ASSUM `UNCURRY f o h = Normal o UNCURRY f' o h`
4976        (REWRITE_TAC o wrap o (MATCH_MP EQ_SYM)) \\
4977     ASM_REWRITE_TAC []) >> Rewr
4978 (* remove outer `Normal`s from LHS and RHS *)
4979 >> REWRITE_TAC [extreal_11]
4980 (* finally, apply SUMINF_2D_suminf, with all assumptions already proved. *)
4981 >> MATCH_MP_TAC SUMINF_2D_suminf >> art []
4982QED
4983
4984(* some local facts of extreals needed by CARATHEODORY_SEMIRING *)
4985Theorem lt_inf_epsilon_set:
4986    !P e. 0 < e /\ (?x. x IN P /\ x <> PosInf) /\ inf P <> NegInf ==>
4987          ?x. x IN P /\ x < inf P + e
4988Proof
4989    METIS_TAC [IN_APP, lt_inf_epsilon]
4990QED
4991
4992Theorem le_inf_epsilon_set:
4993    !P e. 0 < e /\ (?x. x IN P /\ x <> PosInf) /\ inf P <> NegInf ==>
4994          ?x. x IN P /\ x <= inf P + e
4995Proof
4996    rpt STRIP_TAC
4997 >> `?x. x IN P /\ x < inf P + e` by PROVE_TAC [lt_inf_epsilon_set]
4998 >> Q.EXISTS_TAC `x'` >> ASM_REWRITE_TAC []
4999 >> PROVE_TAC [lt_le]
5000QED
5001
5002Theorem pow_half_pos_lt:   !n. 0  < (1 / 2) pow (n + 1)
5003Proof
5004    MATCH_MP_TAC pow_pos_lt >> PROVE_TAC [half_between]
5005QED
5006
5007Theorem pow_half_pos_le :
5008    !n. 0 <= (1 / 2) pow n
5009Proof
5010    Cases_on ‘n’ >- REWRITE_TAC [pow_0, le_01]
5011 >> REWRITE_TAC [ADD1]
5012 >> MATCH_MP_TAC pow_pos_le
5013 >> REWRITE_TAC [half_between]
5014QED
5015
5016Theorem ext_suminf_eq_infty_imp :
5017    !f. (!n. 0 <= f n) /\ (ext_suminf f = PosInf) ==>
5018        !e. e < PosInf ==> ?n. e <= SIGMA f (count n)
5019Proof
5020    rpt STRIP_TAC
5021 >> `!n. SIGMA f (count n) = (\n. SIGMA f (count n)) n` by PROVE_TAC []
5022 >> POP_ORW >> MATCH_MP_TAC sup_le_mono
5023 >> BETA_TAC >> reverse CONJ_TAC
5024 >- ASM_SIMP_TAC std_ss [GSYM ext_suminf_def]
5025 >> GEN_TAC >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_MONO_SET
5026 >> fs [FINITE_COUNT, COUNT_SUC]
5027QED
5028
5029(* the other direction *)
5030Theorem ext_suminf_eq_infty :
5031    !f. (!n. 0 <= f n) /\ (!e. e < PosInf ==> ?n. e <= SIGMA f (count n)) ==>
5032        (ext_suminf f = PosInf)
5033Proof
5034    rpt STRIP_TAC
5035 >> REWRITE_TAC [GSYM le_infty]
5036 >> Suff `sup (\x. ?n : num. x = & n) <= suminf f` >- PROVE_TAC [sup_num]
5037 >> ASM_SIMP_TAC std_ss [ext_suminf_def]
5038 >> MATCH_MP_TAC sup_le_sup_imp'
5039 >> SIMP_TAC std_ss [IN_IMAGE, IN_UNIV]
5040 >> RW_TAC std_ss [IN_APP]
5041 >> `&n < PosInf` by PROVE_TAC [lt_infty, extreal_of_num_def]
5042 >> RES_TAC
5043 >> Q.EXISTS_TAC `SIGMA f (count n')` >> art []
5044 >> Q.EXISTS_TAC `n'` >> REWRITE_TAC []
5045QED
5046
5047(* general version of `ext_suminf_2d` without ``ext_suminf g < PosInf`` *)
5048Theorem ext_suminf_2d_full :
5049    !(f :num -> num -> extreal) (g :num -> extreal) (h :num -> num # num).
5050       (!m n. 0 <= f m n) /\ (!n. ext_suminf (f n) = g n) /\
5051        BIJ h UNIV (UNIV CROSS UNIV) ==>
5052       (ext_suminf (UNCURRY f o h) = ext_suminf g)
5053Proof
5054    rpt STRIP_TAC
5055 >> Cases_on `suminf g < PosInf`
5056 >- (MATCH_MP_TAC ext_suminf_2d >> art [])
5057 >> fs [GSYM lt_infty]
5058 >> Know `!n. 0 <= g n`
5059 >- (GEN_TAC \\
5060     Q.PAT_X_ASSUM `!n. X = g n` (REWRITE_TAC o wrap o GSYM) \\
5061     MATCH_MP_TAC ext_suminf_pos >> art []) >> DISCH_TAC
5062(* suminf (UNCURRY f o h) = PosInf *)
5063 >> Know `suminf g = sup (IMAGE
5064                           (\n. SIGMA (\i. SIGMA (f i) (count n)) (count n))
5065                           univ(:num))`
5066 >- (REWRITE_TAC [GSYM le_antisym] \\
5067     reverse CONJ_TAC >| (* easy goal first *)
5068     [ (* goal 1 (of 2) *)
5069       RW_TAC std_ss [sup_le', IN_IMAGE, IN_UNIV] \\
5070       Q.PAT_X_ASSUM `suminf g = PosInf` (ONCE_REWRITE_TAC o wrap o SYM) \\
5071       POP_ASSUM (REWRITE_TAC o wrap o (MATCH_MP ext_suminf_def)) \\
5072       RW_TAC std_ss [le_sup', IN_IMAGE, IN_UNIV] \\
5073       MATCH_MP_TAC le_trans >> Q.EXISTS_TAC `SIGMA g (count n)` \\
5074       reverse CONJ_TAC >- (POP_ASSUM MATCH_MP_TAC \\
5075                            Q.EXISTS_TAC `n` >> REWRITE_TAC []) \\
5076       irule EXTREAL_SUM_IMAGE_MONO \\
5077       SIMP_TAC std_ss [FINITE_COUNT, IN_COUNT] \\
5078       CONJ_TAC >- (rpt STRIP_TAC \\
5079                    Q.PAT_X_ASSUM `!n. suminf (f n) = g n` (REWRITE_TAC o wrap o GSYM) \\
5080                    ASM_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_le_suminf]) \\
5081       DISJ1_TAC >> GEN_TAC >> DISCH_TAC >> STRIP_TAC >|
5082       [ (* goal 1.1 (of 2) *)
5083         MATCH_MP_TAC pos_not_neginf \\
5084         MATCH_MP_TAC EXTREAL_SUM_IMAGE_POS >> RW_TAC std_ss [FINITE_COUNT, IN_COUNT],
5085         (* goal 1.2 (of 2) *)
5086         MATCH_MP_TAC pos_not_neginf \\
5087         Q.PAT_X_ASSUM `!n. suminf (f n) = g n` (REWRITE_TAC o wrap o GSYM) \\
5088         MATCH_MP_TAC ext_suminf_pos >> art [] ],
5089       (* goal 2 (of 2) *)
5090       POP_ASSUM (REWRITE_TAC o wrap o (MATCH_MP ext_suminf_def)) \\
5091       RW_TAC std_ss [sup_le', IN_IMAGE, IN_UNIV] \\
5092      `g = (\n. g n)` by METIS_TAC [] >> POP_ORW \\
5093       Q.PAT_X_ASSUM `!n. suminf (f n) = g n` (REWRITE_TAC o wrap o GSYM) \\
5094       Know `SIGMA (\n. suminf (f n)) (count n) = suminf (\x. SIGMA (\i. f i x) (count n))`
5095       >- (MATCH_MP_TAC ext_suminf_sigma' >> PROVE_TAC []) >> Rewr' \\
5096       (* stage work *)
5097       Know `!j. 0 <= (\x. SIGMA (\i. f i x) (count n)) j`
5098       >- (RW_TAC std_ss [] \\
5099           MATCH_MP_TAC EXTREAL_SUM_IMAGE_POS \\
5100           RW_TAC std_ss [FINITE_COUNT]) \\
5101       DISCH_THEN (REWRITE_TAC o wrap o (MATCH_MP ext_suminf_def))  \\
5102       RW_TAC std_ss [sup_le', IN_IMAGE, IN_UNIV] \\
5103       RW_TAC std_ss [le_sup', IN_IMAGE, IN_UNIV] \\
5104       Know `SIGMA (\x. SIGMA (\i. f i x) (count n)) (count n') =
5105             SIGMA (\x. SIGMA (f x) (count n')) (count n)`
5106       >- (MATCH_MP_TAC EQ_SYM >> MATCH_MP_TAC NESTED_EXTREAL_SUM_IMAGE_REVERSE \\
5107           REWRITE_TAC [FINITE_COUNT, IN_COUNT] \\
5108           rpt GEN_TAC >> STRIP_TAC >> MATCH_MP_TAC pos_not_neginf >> art []) >> Rewr' \\
5109       MATCH_MP_TAC le_trans \\
5110       Q.EXISTS_TAC `SIGMA (\i. SIGMA (f i) (count (MAX n n'))) (count (MAX n n'))` \\
5111       reverse CONJ_TAC >- (POP_ASSUM MATCH_MP_TAC \\
5112                            Q.EXISTS_TAC `MAX n n'` >> REWRITE_TAC []) \\
5113       MATCH_MP_TAC EXTREAL_SUM_IMAGE_SUM_IMAGE_MONO \\
5114       RW_TAC arith_ss [] ])
5115 >> DISCH_TAC
5116 >> Know `!r. r < PosInf ==> ?n. r <= SIGMA (\i. SIGMA (f i) (count n)) (count n)`
5117 >- (rpt STRIP_TAC \\
5118    `!n. SIGMA (\i. SIGMA (f i) (count n)) (count n) =
5119         (\n. SIGMA (\i. SIGMA (f i) (count n)) (count n)) n` by PROVE_TAC [] >> POP_ORW \\
5120     MATCH_MP_TAC sup_le_mono >> BETA_TAC \\
5121     reverse CONJ_TAC >- PROVE_TAC [] \\
5122     GEN_TAC >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_SUM_IMAGE_MONO \\
5123     RW_TAC arith_ss [])
5124 >> DISCH_TAC
5125 >> MATCH_MP_TAC ext_suminf_eq_infty
5126 >> CONJ_TAC >- RW_TAC std_ss [o_DEF, UNCURRY]
5127 >> rpt STRIP_TAC
5128 >> RES_TAC
5129 >> STRIP_ASSUME_TAC (((Q.SPEC `n`) o (MATCH_MP NUM_2D_BIJ_SMALL_SQUARE))
5130                          (ASSUME ``BIJ h univ(:num) (univ(:num) CROSS univ(:num))``))
5131 >> Q.EXISTS_TAC `N`
5132 >> MATCH_MP_TAC le_trans
5133 >> Q.EXISTS_TAC `SIGMA (\i. SIGMA (f i) (count n)) (count n)` >> art []
5134 >> Know `SIGMA (\i. SIGMA (f i) (count n)) (count n) =
5135          SIGMA (\x. f (FST x) (SND x)) ((count n CROSS count n))`
5136 >- (MATCH_MP_TAC EXTREAL_SUM_IMAGE_SUM_IMAGE \\
5137     REWRITE_TAC [FINITE_COUNT] >> DISJ1_TAC \\
5138     GEN_TAC >> DISCH_TAC \\
5139     MATCH_MP_TAC pos_not_neginf >> art []) >> Rewr'
5140 >> Know `SIGMA (UNCURRY f o h) (count N) = SIGMA (UNCURRY f) (IMAGE h (count N))`
5141 >- (MATCH_MP_TAC EQ_SYM >> irule EXTREAL_SUM_IMAGE_IMAGE \\
5142     SIMP_TAC std_ss [FINITE_COUNT, UNCURRY] \\
5143     CONJ_TAC >- (DISJ1_TAC >> GEN_TAC >> DISCH_TAC \\
5144                  MATCH_MP_TAC pos_not_neginf >> art []) \\
5145     MATCH_MP_TAC INJ_IMAGE >> Q.EXISTS_TAC `UNIV` \\
5146     RW_TAC std_ss [INJ_DEF, IN_COUNT, IN_UNIV] \\
5147     PROVE_TAC [BIJ_DEF, INJ_DEF, IN_UNIV]) >> Rewr'
5148 >> Know `UNCURRY f = (\x. f (FST x) (SND x))`
5149 >- (FUN_EQ_TAC >> GEN_TAC >> BETA_TAC >> REWRITE_TAC [UNCURRY]) >> Rewr'
5150 >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_MONO_SET >> art []
5151 >> CONJ_TAC >- (MATCH_MP_TAC FINITE_CROSS >> REWRITE_TAC [FINITE_COUNT])
5152 >> CONJ_TAC >- (MATCH_MP_TAC IMAGE_FINITE >> REWRITE_TAC [FINITE_COUNT])
5153 >> GEN_TAC >> BETA_TAC >> DISCH_TAC >> art []
5154QED
5155
5156Theorem harmonic_series_pow_2 :
5157    ext_suminf (\n. inv (&(SUC n) pow 2)) < PosInf
5158Proof
5159    Q.ABBREV_TAC `f :num -> real = \n. inv (&(SUC n) pow 2)`
5160 >> Suff `(\n. inv (&(SUC n) pow 2)) = Normal o f`
5161 >- (Rewr' >> MATCH_MP_TAC summable_ext_suminf \\
5162     rw [HARMONIC_SERIES_POW_2, Abbr `f`])
5163 >> RW_TAC real_ss [Abbr `f`, o_DEF, FUN_EQ_THM]
5164 >> Know `(0 :real) < &(SUC n) pow 2`
5165 >- (MATCH_MP_TAC REAL_POW_LT >> RW_TAC real_ss []) >> DISCH_TAC
5166 >> `&(SUC n) pow 2 <> (0 :real)` by PROVE_TAC [REAL_LT_IMP_NE]
5167 >> ASM_SIMP_TAC real_ss [extreal_of_num_def, extreal_inv_eq, extreal_pow_def]
5168QED
5169
5170Theorem geometric_series_pow : (* cf. seqTheory.GP, seqTheory.GP_FINITE *)
5171    !x. 0 < x /\ x < 1 ==> ext_suminf (\n. x pow n) = inv (1 - x)
5172Proof
5173    rpt STRIP_TAC
5174 >> Know ‘?r. x = Normal r’
5175 >- (Suff ‘x <> PosInf /\ x <> NegInf’ >- METIS_TAC [extreal_cases] \\
5176     CONJ_TAC >> REWRITE_TAC [lt_infty] >> MATCH_MP_TAC lt_trans >| (* 2 subgoals *)
5177     [ Q.EXISTS_TAC ‘1’  >> rw [extreal_of_num_def],
5178       Q.EXISTS_TAC ‘0’ >> rw [extreal_of_num_def, lt_infty] ])
5179 >> STRIP_TAC
5180 >> POP_ASSUM
5181      (fn th => FULL_SIMP_TAC std_ss [th, extreal_of_num_def, extreal_lt_eq, extreal_sub_def,
5182                                      extreal_pow_def, extreal_11])
5183 >> Know ‘r <> 1’ >- (CCONTR_TAC >> fs [])
5184 >> DISCH_TAC
5185 >> ‘1 - r <> 0’ by rw []
5186 >> rw [extreal_inv_eq]
5187 >> Know ‘inv (1 - r) = suminf (\n. r pow n)’
5188 >- (MATCH_MP_TAC SUM_UNIQ \\
5189     MATCH_MP_TAC GP >> rw [ABS_BOUNDS_LT] \\
5190     MATCH_MP_TAC REAL_LT_TRANS \\
5191     Q.EXISTS_TAC ‘0’ >> rw [])
5192 >> Rewr'
5193 >> HO_MATCH_MP_TAC ext_suminf_suminf
5194 >> STRONG_CONJ_TAC
5195 >- (Q.X_GEN_TAC ‘n’ \\
5196     MATCH_MP_TAC POW_POS \\
5197     MATCH_MP_TAC REAL_LT_IMP_LE >> art [])
5198 >> DISCH_TAC
5199 >> Q.ABBREV_TAC ‘f = \n. Normal (r pow n)’
5200 >> Know ‘!n. 0 <= f n’
5201 >- (rw [Abbr ‘f’, extreal_of_num_def, extreal_le_eq])
5202 >> rw [lt_infty, ext_suminf_def, Abbr ‘f’]
5203 >> Know ‘!n. SIGMA (\n. Normal ((\n. r pow n) n)) (count n) =
5204              Normal (SIGMA (\n. r pow n) (count n))’
5205 >- (Q.X_GEN_TAC ‘n’ \\
5206     MATCH_MP_TAC EXTREAL_SUM_IMAGE_NORMAL \\
5207     REWRITE_TAC [FINITE_COUNT])
5208 >> BETA_TAC >> Rewr'
5209 >> ASM_SIMP_TAC std_ss [REAL_SUM_IMAGE_COUNT, GP_FINITE]
5210 >> MATCH_MP_TAC let_trans
5211 >> Q.EXISTS_TAC ‘Normal ((0 - 1) / (r - 1))’
5212 >> rw [sup_le', lt_infty]
5213 (* stage work *)
5214 >> RW_TAC std_ss [extreal_le_eq, real_div]
5215 >> ONCE_REWRITE_TAC [REAL_MUL_COMM]
5216 >> Know ‘inv (r - 1) * (r pow n - 1) <= inv (r - 1) * -1 <=>
5217          -1 <= r pow n - 1 ’
5218 >- (MATCH_MP_TAC REAL_LE_LMUL_NEG \\
5219     rw [REAL_INV_LT0] \\
5220     Q.PAT_X_ASSUM ‘r < 1’ MP_TAC >> REAL_ARITH_TAC)
5221 >> Rewr'
5222 >> Suff ‘0 <= r pow n’ >- REAL_ARITH_TAC
5223 >> MATCH_MP_TAC POW_POS
5224 >> MATCH_MP_TAC REAL_LT_IMP_LE >> art []
5225QED
5226
5227Theorem pow_half_ser' : (* was: suminf_half_series_ereal *)
5228    ext_suminf (\n. (1 / 2) pow (SUC n)) = 1
5229Proof
5230    rw [extreal_pow]
5231 >> Know ‘suminf (\n. 1 / 2 * (1 / 2) pow n) =
5232          (1 / 2) * suminf (\n. (1 / 2) pow n)’
5233 >- (HO_MATCH_MP_TAC ext_suminf_cmul >> rw [half_between] \\
5234     MATCH_MP_TAC pow_pos_le >> rw [half_between])
5235 >> Rewr'
5236 >> Know ‘suminf (\n. (1 / 2) pow n) = inv (1 - 1 / 2)’
5237 >- (MATCH_MP_TAC geometric_series_pow \\
5238     rw [half_between])
5239 >> Rewr'
5240 >> RW_TAC real_ss [extreal_of_num_def, extreal_inv_eq, ne_02, extreal_mul_def,
5241                    extreal_div_eq, extreal_sub_def, REAL_MUL_RINV]
5242QED
5243
5244Theorem pow_half_ser = REWRITE_RULE [ADD1] pow_half_ser'
5245
5246Theorem pow_half_ser_by_e :
5247    !e. 0 < e /\ e <> PosInf ==> (e = ext_suminf (\n. e * ((1 / 2) pow (n + 1))))
5248Proof
5249    rpt STRIP_TAC
5250 >> Cases_on `e` >> fs [lt_infty]
5251 >> `(\n. Normal r * (1 / 2) pow (n + 1)) = (\n. Normal r * (\n. (1 / 2) pow (n + 1)) n)`
5252        by METIS_TAC []
5253 >> POP_ASSUM (REWRITE_TAC o wrap)
5254 >> Suff `suminf (\n. Normal r * (\n. (1 / 2) pow (n + 1)) n) =
5255                      Normal r * suminf (\n. (1 / 2) pow (n + 1))`
5256 >- (DISCH_THEN (REWRITE_TAC o wrap) \\
5257     REWRITE_TAC [pow_half_ser, mul_rone])
5258 >> MATCH_MP_TAC ext_suminf_cmul_alt
5259 >> CONJ_TAC
5260 >- (MATCH_MP_TAC REAL_LT_IMP_LE \\
5261     PROVE_TAC [extreal_lt_eq, extreal_of_num_def])
5262 >> BETA_TAC
5263 >> CONJ_TAC >- (MATCH_MP_TAC pow_pos_le \\
5264                 PROVE_TAC [half_between])
5265 >> GEN_TAC
5266 >> METIS_TAC [half_not_infty, pow_not_infty, lt_infty]
5267QED
5268
5269Theorem ext_suminf_offset :
5270    !f m. (!n. 0 <= f n) ==>
5271           suminf f = SIGMA f (count m) + suminf (\i. f (i + m))
5272Proof
5273    rpt STRIP_TAC
5274 >> Q.ABBREV_TAC ‘f1 = \n. if n < m then f n else 0’
5275 >> Q.ABBREV_TAC ‘f2 = \n. if m <= n then f n else 0’
5276 >> Know ‘SIGMA f (count m) = SIGMA f1 (count m)’
5277 >- (irule EXTREAL_SUM_IMAGE_EQ >> rw [Abbr ‘f1’] \\
5278     DISJ1_TAC >> rw [pos_not_neginf])
5279 >> Rewr'
5280 (* applying ext_suminf_sum *)
5281 >> Know ‘SIGMA f1 (count m) = suminf f1’
5282 >- (ONCE_REWRITE_TAC [EQ_SYM_EQ] \\
5283     MATCH_MP_TAC ext_suminf_sum >> rw [Abbr ‘f1’])
5284 >> Rewr'
5285 (* applying ext_suminf_eq_shift *)
5286 >> Know ‘suminf (\i. f (i + m)) = suminf f2’
5287 >- (MATCH_MP_TAC ext_suminf_eq_shift \\
5288     Q.EXISTS_TAC ‘m’ >> rw [Abbr ‘f2’])
5289 >> Rewr'
5290 >> MATCH_MP_TAC ext_suminf_add'
5291 >> rw [Abbr ‘f1’, Abbr ‘f2’]
5292 >> fs []
5293QED
5294
5295(* `sup` is the maximal element of any finite non-empty extreal set,
5296    see also le_sup_imp'.
5297 *)
5298Theorem sup_maximal :
5299    !p. FINITE p /\ p <> {} ==> extreal_sup p IN p
5300Proof
5301    Suff `!p. FINITE p ==> p <> {} ==> extreal_sup p IN p` >- rw []
5302 >> HO_MATCH_MP_TAC FINITE_INDUCT
5303 >> RW_TAC std_ss []
5304 >> Cases_on `p = EMPTY` >- fs [sup_sing]
5305 >> Suff `sup (e INSERT p) = max e (sup p)`
5306 >- (Rewr' >> rw [extreal_max_def])
5307 >> RW_TAC std_ss [sup_eq']
5308 >| [ (* goal 1 (of 2) *)
5309      fs [IN_INSERT, le_max] \\
5310      DISJ2_TAC \\
5311      MATCH_MP_TAC le_sup_imp' >> art [],
5312      (* goal 2 (of 2) *)
5313      POP_ASSUM MATCH_MP_TAC \\
5314      fs [IN_INSERT, extreal_max_def] \\
5315      Cases_on `e <= sup p` >> fs [] ]
5316QED
5317
5318(* `inf` is the minimal element of any finite non-empty extreal set.
5319    see also inf_le_imp'.
5320 *)
5321Theorem inf_minimal :
5322    !p. FINITE p /\ p <> {} ==> extreal_inf p IN p
5323Proof
5324    Suff `!p. FINITE p ==> p <> {} ==> extreal_inf p IN p` >- rw []
5325 >> HO_MATCH_MP_TAC FINITE_INDUCT
5326 >> RW_TAC std_ss []
5327 >> Cases_on `p = EMPTY` >- fs [inf_sing]
5328 >> Suff `inf (e INSERT p) = min e (inf p)`
5329 >- (Rewr' >> rw [extreal_min_def])
5330 >> RW_TAC std_ss [inf_eq']
5331 >| [ (* goal 1 (of 2) *)
5332      fs [IN_INSERT, min_le] \\
5333      DISJ2_TAC \\
5334      MATCH_MP_TAC inf_le_imp' >> art [],
5335      (* goal 2 (of 2) *)
5336      POP_ASSUM MATCH_MP_TAC \\
5337      fs [IN_INSERT, extreal_min_def] \\
5338      Cases_on `e <= inf p` >> fs [] ]
5339QED
5340
5341(* `open interval` of extreal sets. c.f. `OPEN_interval` / `CLOSED_interval`
5342   in real_toplogyTheory, `right_open_interval` in real_borelTheory.
5343 *)
5344Definition open_interval_def :
5345    open_interval (a :extreal) b = {x | a < x /\ x < b}
5346End
5347
5348Theorem IN_open_interval :
5349    !a b x. x IN open_interval a b <=> a < x /\ x < b
5350Proof
5351    rw [open_interval_def]
5352QED
5353
5354(* renamed from `open_intervals_set`, needed in borelTheory (lambda0_premeasure) *)
5355Definition open_intervals_def :
5356    open_intervals = {open_interval a b | T}
5357End
5358
5359Definition rational_intervals_def :
5360    rational_intervals = {open_interval a b | a IN Q_set /\ b IN Q_set}
5361End
5362
5363Theorem COUNTABLE_RATIONAL_INTERVALS :
5364    countable rational_intervals
5365Proof
5366    Suff `rational_intervals = IMAGE (\(a,b). open_interval a b) (Q_set CROSS Q_set)`
5367 >- METIS_TAC [cross_countable, Q_COUNTABLE, image_countable]
5368 >> RW_TAC std_ss [rational_intervals_def, IMAGE_DEF, EXTENSION, GSPECIFICATION,
5369                   IN_CROSS]
5370 >> EQ_TAC (* 2 subgoals, same tactics *)
5371 >> DISCH_THEN (Q.X_CHOOSE_THEN ‘y’ MP_TAC)
5372 >> RW_TAC std_ss []
5373 >> Q.EXISTS_TAC ‘y’
5374 >> Cases_on ‘y’ >> FULL_SIMP_TAC std_ss [PAIR_EQ, EXTENSION]
5375QED
5376
5377(* ------------------------------------------------------------------------- *)
5378(*  Finite Product Images (PI) of extreals                                   *)
5379(* ------------------------------------------------------------------------- *)
5380
5381(* old definition:
5382
5383val EXTREAL_PROD_IMAGE_DEF = new_definition
5384  ("EXTREAL_PROD_IMAGE_DEF",
5385  ``EXTREAL_PROD_IMAGE f s = ITSET (\e acc. f e * acc) s (1 :extreal)``);
5386
5387   new definition (based on iterateTheory):
5388 *)
5389Definition ext_product_def :
5390    ext_product = iterate (( * ):extreal->extreal->extreal)
5391End
5392
5393Overload EXTREAL_PROD_IMAGE = “\f s. ext_product s f”
5394Overload PI = “EXTREAL_PROD_IMAGE”
5395
5396val _ = Unicode.unicode_version {u = UTF8.chr 0x220F, tmnm = "PI"};
5397val _ = TeX_notation {hol = UTF8.chr 0x220F, TeX = ("\\HOLTokenPI{}", 1)};
5398val _ = TeX_notation {hol = "PI"           , TeX = ("\\HOLTokenPI{}", 1)};
5399
5400Theorem neutral_mul :
5401    neutral(( * ):extreal->extreal->extreal) = &1
5402Proof
5403    REWRITE_TAC [neutral]
5404 >> MATCH_MP_TAC SELECT_UNIQUE
5405 >> METIS_TAC [mul_lone, mul_rone]
5406QED
5407
5408Theorem monoidal_mul :
5409    monoidal(( * ):extreal->extreal->extreal)
5410Proof
5411    rw [monoidal, neutral_mul, mul_assoc]
5412 >> REWRITE_TAC [Once mul_comm]
5413QED
5414
5415Theorem EXTREAL_PROD_IMAGE_THM :
5416    !f. (EXTREAL_PROD_IMAGE f {} = 1) /\
5417        !e s. FINITE s ==> (EXTREAL_PROD_IMAGE f (e INSERT s) =
5418                            f e * EXTREAL_PROD_IMAGE f (s DELETE e))
5419Proof
5420    Q.X_GEN_TAC ‘f’
5421 >> ASSUME_TAC monoidal_mul
5422 >> rw [ext_product_def, GSYM neutral_mul]
5423 >- rw [ITERATE_CLAUSES]
5424 >> reverse (Cases_on ‘e IN s’)
5425 >- (‘s DELETE e = s’ by METIS_TAC [DELETE_NON_ELEMENT] >> POP_ORW \\
5426     rw [ITERATE_CLAUSES])
5427 >> ‘e INSERT s = e INSERT (s DELETE e)’ by SET_TAC [] >> POP_ORW
5428 >> rw [ITERATE_CLAUSES]
5429QED
5430
5431Theorem EXTREAL_PROD_IMAGE_EMPTY[simp]:   !f. EXTREAL_PROD_IMAGE f {} = 1
5432Proof
5433    SRW_TAC [] [EXTREAL_PROD_IMAGE_THM]
5434QED
5435
5436Theorem EXTREAL_PROD_IMAGE_SING[simp]:   !f e. EXTREAL_PROD_IMAGE f {e} = f e
5437Proof
5438    SRW_TAC [] [EXTREAL_PROD_IMAGE_THM, mul_rone]
5439QED
5440
5441Theorem EXTREAL_PROD_IMAGE_PROPERTY:
5442    !f e s. FINITE s ==> (EXTREAL_PROD_IMAGE f (e INSERT s) =
5443                          f e * EXTREAL_PROD_IMAGE f (s DELETE e))
5444Proof
5445    PROVE_TAC [EXTREAL_PROD_IMAGE_THM]
5446QED
5447
5448Theorem EXTREAL_PROD_IMAGE_PAIR:
5449    !f a b. a <> b ==> (EXTREAL_PROD_IMAGE f {a; b} = f a * f b)
5450Proof
5451    RW_TAC std_ss []
5452 >> `FINITE {b}` by PROVE_TAC [FINITE_SING]
5453 >> POP_ASSUM (MP_TAC o (Q.SPECL [`f`, `a`]) o (MATCH_MP EXTREAL_PROD_IMAGE_PROPERTY))
5454 >> RW_TAC std_ss []
5455 >> Know `{b} DELETE a = {b}`
5456 >- (RW_TAC std_ss [EXTENSION, NOT_IN_EMPTY, IN_DELETE, IN_SING] \\
5457     EQ_TAC >> rpt STRIP_TAC >> fs []) >> Rewr'
5458 >> REWRITE_TAC [EXTREAL_PROD_IMAGE_SING]
5459QED
5460
5461(* NOTE: removed ‘FINITE s’ due to iterateTheory *)
5462Theorem EXTREAL_PROD_IMAGE_EQ :
5463    !s f f'. (!x. x IN s ==> (f x = f' x)) ==>
5464             (EXTREAL_PROD_IMAGE f s = EXTREAL_PROD_IMAGE f' s)
5465Proof
5466    rw [ext_product_def]
5467 >> irule ITERATE_EQ
5468 >> rw [monoidal_mul]
5469QED
5470
5471Theorem EXTREAL_PROD_IMAGE_DISJOINT_UNION :
5472    !s s'. FINITE s /\ FINITE s' /\ DISJOINT s s' ==>
5473           !f. (EXTREAL_PROD_IMAGE f (s UNION s') =
5474                EXTREAL_PROD_IMAGE f s * EXTREAL_PROD_IMAGE f s')
5475Proof
5476    rw [ext_product_def]
5477 >> irule ITERATE_UNION
5478 >> rw [monoidal_mul]
5479QED
5480
5481(* NOTE: removed ‘FINITE s’ due to iterateTheory *)
5482Theorem EXTREAL_PROD_IMAGE_IMAGE :
5483    !s f'. INJ f' s (IMAGE f' s) ==>
5484           !f. EXTREAL_PROD_IMAGE f (IMAGE f' s) = EXTREAL_PROD_IMAGE (f o f') s
5485Proof
5486    rw [ext_product_def, INJ_DEF]
5487 >> irule ITERATE_IMAGE
5488 >> rw [monoidal_mul]
5489QED
5490
5491Theorem EXTREAL_PROD_IMAGE_COUNT :
5492    !f. (EXTREAL_PROD_IMAGE f (count 2) = f 0 * f 1) /\
5493        (EXTREAL_PROD_IMAGE f (count 3) = f 0 * f 1 * f 2) /\
5494        (EXTREAL_PROD_IMAGE f (count 4) = f 0 * f 1 * f 2 * f 3) /\
5495        (EXTREAL_PROD_IMAGE f (count 5) = f 0 * f 1 * f 2 * f 3 * f 4)
5496Proof
5497    Q.X_GEN_TAC ‘f’
5498 >> `count 2 = {0;1} /\
5499     count 3 = {0;1;2} /\
5500     count 4 = {0;1;2;3} /\
5501     count 5 = {0;1;2;3;4}`
5502       by RW_TAC real_ss [EXTENSION, IN_COUNT, IN_INSERT, IN_SING]
5503 >> `{1:num} DELETE 0 = {1}` by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING]
5504 >> `{2:num} DELETE 1 = {2}` by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING]
5505 >> `{3:num} DELETE 2 = {3}` by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING]
5506 >> `{4:num} DELETE 3 = {4}` by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING]
5507 >> `{2:num; 3} DELETE 1 = {2;3}`
5508        by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING, IN_INSERT]
5509 >> `{3:num; 4} DELETE 2 = {3;4}`
5510        by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING, IN_INSERT]
5511 >> `{2:num; 3; 4} DELETE 1 = {2;3;4}`
5512        by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING, IN_INSERT]
5513 >> `{1:num; 2} DELETE 0 = {1;2}`
5514        by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING, IN_INSERT]
5515 >> `{1:num; 2; 3} DELETE 0 = {1;2;3}`
5516        by RW_TAC real_ss [EXTENSION, IN_DELETE,IN_SING,IN_INSERT]
5517 >> `{1:num; 2; 3; 4} DELETE 0 = {1;2;3;4}`
5518        by RW_TAC real_ss [EXTENSION, IN_DELETE, IN_SING, IN_INSERT]
5519 >> ASM_SIMP_TAC real_ss [FINITE_SING, FINITE_INSERT, EXTREAL_PROD_IMAGE_PROPERTY,
5520                          EXTREAL_PROD_IMAGE_SING, IN_INSERT, NOT_IN_EMPTY,
5521                          mul_assoc]
5522QED
5523
5524(* ------------------------------------------------------------------------- *)
5525(*  Maximal values of a sequence of functions at the same point              *)
5526(* ------------------------------------------------------------------------- *)
5527
5528Definition max_fn_seq_def :
5529   (max_fn_seq g 0       x = g 0 x) /\
5530   (max_fn_seq g (SUC n) x = max (max_fn_seq g n x) (g (SUC n) x))
5531End
5532
5533Theorem max_fn_seq_0[simp] :
5534    !g. max_fn_seq g 0 = g 0
5535Proof
5536    rw [FUN_EQ_THM, max_fn_seq_def]
5537QED
5538
5539Theorem max_fn_seq_cong :
5540    !f g x. (!n. f n x = g n x) ==> !n. max_fn_seq f n x = max_fn_seq g n x
5541Proof
5542    rpt GEN_TAC >> STRIP_TAC
5543 >> Induct_on ‘n’
5544 >> rw [max_fn_seq_def]
5545QED
5546
5547(* cf. real_topologyTheory.SUP_INSERT. For extreal, ‘bounded‘ is not needed. *)
5548Theorem sup_insert :
5549    !x s. sup (x INSERT s) = if s = {} then x else max x (sup s)
5550Proof
5551    rpt STRIP_TAC
5552 >> Cases_on ‘s = {}’ >- rw [sup_sing]
5553 >> rw [sup_eq', le_max, max_le]
5554 >| [ rw [le_refl] (* goal 1 (of 3) *),
5555      rw [le_sup'] (* goal 2 (of 3) *),
5556      rw [sup_le'] (* goal 3 (of 3) *) ]
5557QED
5558
5559Theorem max_fn_seq_alt_sup :
5560    !f x n. max_fn_seq f n x = sup (IMAGE (\i. f i x) (count (SUC n)))
5561Proof
5562    NTAC 2 GEN_TAC
5563 >> Induct_on ‘n’ >- rw [max_fn_seq_def, sup_sing, COUNT_ONE]
5564 >> RW_TAC std_ss [max_fn_seq_def]
5565 >> KILL_TAC
5566 >> Q.ABBREV_TAC ‘A = IMAGE (\i. f i x) (count (SUC n))’
5567 >> ONCE_REWRITE_TAC [COUNT_SUC]
5568 >> rw [IMAGE_INSERT]
5569 >> ‘A <> {}’ by (rw [Abbr ‘A’, Once EXTENSION])
5570 >> rw [sup_insert, Once max_comm]
5571QED
5572
5573(* An analog of ‘max_le’ *)
5574Theorem max_fn_seq_le :
5575    !f x y n. max_fn_seq f n x <= y <=> !i. i <= n ==> f i x <= y
5576Proof
5577    NTAC 3 GEN_TAC
5578 >> Induct_on ‘n’ >> rw [max_fn_seq_def]
5579 >> rw [max_le]
5580 >> KILL_TAC
5581 >> EQ_TAC >> rw []
5582 >> ‘i = SUC n \/ i <= n’ by rw [] >- rw []
5583 >> FIRST_X_ASSUM MATCH_MP_TAC >> art []
5584QED
5585
5586Theorem lt_max_fn_seq :
5587    !f x y n. x < max_fn_seq f n y <=> ?i. i <= n /\ x < f i y
5588Proof
5589    NTAC 3 GEN_TAC
5590 >> Induct_on ‘n’ >> rw [max_fn_seq_def, lt_max]
5591 >> EQ_TAC >> rw []
5592 >| [ (* goal 1 (of 3) *)
5593      Q.EXISTS_TAC ‘i’ >> rw [],
5594      (* goal 2 (of 3) *)
5595      Q.EXISTS_TAC ‘SUC n’ >> rw [],
5596      (* goal 3 (of 3) *)
5597     ‘i = SUC n \/ i <= n’ by rw [] >- rw [] \\
5598      DISJ1_TAC >> Q.EXISTS_TAC ‘i’ >> rw [] ]
5599QED
5600
5601Theorem max_fn_seq_mono :
5602    !g n x. max_fn_seq g n x <= max_fn_seq g (SUC n) x
5603Proof
5604    RW_TAC std_ss [max_fn_seq_def, extreal_max_def, le_refl]
5605QED
5606
5607(* ------------------------------------------------------------------------- *)
5608(*  Positive and negative parts of functions (moved from borelTheory)        *)
5609(* ------------------------------------------------------------------------- *)
5610
5611Definition fn_plus_def:   (* f^+ *)
5612    fn_plus (f :'a -> extreal) = (\x. if 0 < f x then f x else 0)
5613End
5614
5615Overload TC = ``fn_plus``(* relationTheory *)
5616
5617Definition fn_minus_def:   (* f^- *)
5618    fn_minus (f :'a -> extreal) = (\x. if f x < 0 then ~(f x) else 0)
5619End
5620
5621val _ = add_rule { fixity = Suffix 2100,
5622                   block_style = (AroundEachPhrase, (Portable.CONSISTENT,0)),
5623                   paren_style = ParoundPrec,
5624                   pp_elements = [TOK "^-"],
5625                   term_name = "fn_minus"};
5626
5627val _ = Unicode.unicode_version {u = Unicode.UChar.sup_minus, tmnm = "fn_minus"};
5628val _ = TeX_notation {hol = Unicode.UChar.sup_minus,
5629                      TeX = ("\\HOLTokenSupMinus{}", 1)};
5630val _ = TeX_notation {hol = "^-", TeX = ("\\HOLTokenSupMinus{}", 1)};
5631
5632(* alternative definitions of fn_plus and fn_minus using max/min *)
5633Theorem FN_PLUS_ALT :
5634    !f. fn_plus f = (\x. max (f x) 0)
5635Proof
5636    RW_TAC std_ss [fn_plus_def, extreal_max_def]
5637 >> FUN_EQ_TAC >> GEN_TAC >> BETA_TAC
5638 >> Cases_on `0 < f x`
5639 >- (`~(f x <= 0)` by PROVE_TAC [let_antisym] >> fs [])
5640 >> `f x <= 0` by PROVE_TAC [extreal_lt_def]
5641 >> fs []
5642QED
5643
5644(* !f. fn_plus f = (\x. max 0 (f x)) *)
5645Theorem FN_PLUS_ALT' = ONCE_REWRITE_RULE [max_comm] FN_PLUS_ALT
5646
5647Theorem fn_plus : (* original definition *)
5648    !f x. fn_plus f x = max 0 (f x)
5649Proof
5650    RW_TAC std_ss [FN_PLUS_ALT']
5651QED
5652
5653Theorem FN_MINUS_ALT :
5654    !f. fn_minus f = (\x. -min (f x) 0)
5655Proof
5656    RW_TAC std_ss [fn_minus_def, extreal_min_def]
5657 >> FUN_EQ_TAC >> GEN_TAC >> BETA_TAC
5658 >> Cases_on `f x < 0`
5659 >- (`f x <= 0` by PROVE_TAC [lt_imp_le] >> fs [])
5660 >> fs []
5661 >> `0 <= f x` by PROVE_TAC [extreal_lt_def]
5662 >> Cases_on `f x <= 0`
5663 >- (`f x = 0` by PROVE_TAC [le_antisym] >> fs [neg_0])
5664 >> fs [neg_0]
5665QED
5666
5667(* |- !f. fn_minus f = (\x. -min 0 (f x)) *)
5668Theorem FN_MINUS_ALT' = ONCE_REWRITE_RULE [min_comm] FN_MINUS_ALT;
5669
5670Theorem fn_minus : (* original definition *)
5671    !f x. fn_minus f x = -min 0 (f x)
5672Proof
5673    RW_TAC std_ss [FN_MINUS_ALT']
5674QED
5675
5676Theorem FN_DECOMP:   !f x. f x = fn_plus f x - fn_minus f x
5677Proof
5678    RW_TAC std_ss [fn_plus_def, fn_minus_def]
5679 >- METIS_TAC [lt_antisym]
5680 >- REWRITE_TAC [sub_rzero]
5681 >- (`0 - -f x = 0 + f x` by METIS_TAC [sub_rneg, extreal_of_num_def] \\
5682     POP_ORW >> REWRITE_TAC [add_lzero])
5683 >> REWRITE_TAC [sub_rzero]
5684 >> METIS_TAC [extreal_lt_def, le_antisym]
5685QED
5686
5687Theorem FN_DECOMP':   !f. f = (\x. fn_plus f x - fn_minus f x)
5688Proof
5689    METIS_TAC [FN_DECOMP]
5690QED
5691
5692(* `fn_plus f x + fn_minus f x` is always defined (same reason as above) *)
5693Theorem FN_ABS :
5694    !f x. (abs o f) x = fn_plus f x + fn_minus f x
5695Proof
5696    RW_TAC std_ss [o_DEF, fn_plus_def, fn_minus_def, add_rzero, add_lzero]
5697 >> Q.ABBREV_TAC `e = f x` (* 4 subgoals *)
5698 >| [ (* goal 1 (of 4) *)
5699      METIS_TAC [lt_antisym],
5700      (* goal 2 (of 4) *)
5701      Cases_on `e` >- METIS_TAC [extreal_of_num_def, lt_infty]
5702      >- REWRITE_TAC [extreal_abs_def] \\
5703      REWRITE_TAC [extreal_abs_def, extreal_11] \\
5704     `0 <= r` by METIS_TAC [extreal_of_num_def, extreal_lt_eq, REAL_LT_IMP_LE] \\
5705      METIS_TAC [abs],
5706      (* goal 3 (of 4) *)
5707      Cases_on `e` >- REWRITE_TAC [extreal_abs_def, extreal_ainv_def]
5708      >- METIS_TAC [extreal_of_num_def, lt_infty] \\
5709      REWRITE_TAC [extreal_abs_def, extreal_ainv_def, extreal_11] \\
5710     `r < 0` by METIS_TAC [extreal_of_num_def, extreal_lt_eq] \\
5711      METIS_TAC [real_lte, abs],
5712      (* goal 4 (of 4) *)
5713     `e = 0` by METIS_TAC [extreal_lt_def, le_antisym] \\
5714      PROVE_TAC [abs_0] ]
5715QED
5716
5717Theorem FN_ABS' :
5718    !f. (abs o f) = (\x. fn_plus f x + fn_minus f x)
5719Proof
5720    METIS_TAC [FN_ABS]
5721QED
5722
5723Theorem FN_PLUS_POS :
5724    !g x. 0 <= (fn_plus g) x
5725Proof
5726    RW_TAC real_ss [fn_plus_def, FUN_EQ_THM, lt_imp_le, le_refl]
5727QED
5728
5729Theorem FN_MINUS_POS :
5730    !g x. 0 <= (fn_minus g) x
5731Proof
5732    RW_TAC real_ss [fn_minus_def, FUN_EQ_THM, le_refl]
5733 >> METIS_TAC [le_neg, lt_imp_le, neg_0]
5734QED
5735
5736Theorem FN_PLUS_POS_ID :
5737    !g. (!x. 0 <= g x) ==> ((fn_plus g) = g)
5738Proof
5739    RW_TAC real_ss [fn_plus_def,FUN_EQ_THM]
5740 >> Cases_on `g x = 0` >- METIS_TAC []
5741 >> METIS_TAC [le_lt]
5742QED
5743
5744Theorem FN_PLUS_REDUCE[simp] :
5745    !f x. 0 <= f x ==> (fn_plus f x = f x)
5746Proof
5747    RW_TAC std_ss [fn_plus_def]
5748 >> METIS_TAC [le_lt]
5749QED
5750
5751Theorem FN_PLUS_REDUCE' :
5752    !f x. f x <= 0 ==> (fn_plus f x = 0)
5753Proof
5754    RW_TAC std_ss [fn_plus_def]
5755 >> METIS_TAC [let_antisym]
5756QED
5757
5758Theorem FN_MINUS_REDUCE[simp] :
5759    !f x. 0 <= f x ==> (fn_minus f x = 0)
5760Proof
5761    RW_TAC std_ss [fn_minus_def]
5762 >> PROVE_TAC [let_antisym]
5763QED
5764
5765Theorem FN_MINUS_REDUCE' :
5766    !f x. f x <= 0 ==> (fn_minus f x = -f x)
5767Proof
5768    RW_TAC std_ss [fn_minus_def]
5769 >> REWRITE_TAC [Once EQ_SYM_EQ, neg_eq0]
5770 >> METIS_TAC [le_lt]
5771QED
5772
5773(* don't put it into simp sets, ‘o’ may be eliminated *)
5774Theorem FN_PLUS_ABS_SELF :
5775    !f. fn_plus (abs o f) = abs o f
5776Proof
5777    RW_TAC bool_ss [FUN_EQ_THM]
5778 >> MATCH_MP_TAC FN_PLUS_REDUCE
5779 >> RW_TAC std_ss [o_DEF, abs_pos]
5780QED
5781Theorem fn_plus_abs = FN_PLUS_ABS_SELF
5782
5783(* don't put it into simp sets, ‘o’ may be eliminated *)
5784Theorem FN_MINUS_ABS_ZERO :
5785    !f. fn_minus (abs o f) = \x. 0
5786Proof
5787    RW_TAC bool_ss [FUN_EQ_THM]
5788 >> MATCH_MP_TAC FN_MINUS_REDUCE
5789 >> RW_TAC std_ss [o_DEF, abs_pos]
5790QED
5791Theorem fn_minus_abs = FN_MINUS_ABS_ZERO
5792
5793Theorem FN_PLUS_NEG_ZERO :
5794    !g. (!x. g x <= 0) ==> (fn_plus g = (\x. 0))
5795Proof
5796    RW_TAC real_ss [fn_plus_def, FUN_EQ_THM]
5797 >> `~(0 < g x)` by PROVE_TAC [extreal_lt_def]
5798 >> fs []
5799QED
5800
5801Theorem FN_MINUS_POS_ZERO :
5802    !g. (!x. 0 <= g x) ==> (fn_minus g = (\x. 0))
5803Proof
5804    RW_TAC real_ss [fn_minus_def, FUN_EQ_THM]
5805 >> Cases_on `g x = 0` >- METIS_TAC [neg_0]
5806 >> `0 < g x` by METIS_TAC [lt_le]
5807 >> METIS_TAC [extreal_lt_def]
5808QED
5809
5810Theorem FN_PLUS_ZERO[simp] :
5811    fn_plus (\x. 0) = (\x. 0)
5812Proof
5813    MATCH_MP_TAC FN_PLUS_NEG_ZERO
5814 >> RW_TAC std_ss [le_refl]
5815QED
5816
5817Theorem FN_MINUS_ZERO[simp] :
5818    fn_minus (\x. 0) = (\x. 0)
5819Proof
5820    MATCH_MP_TAC FN_MINUS_POS_ZERO
5821 >> RW_TAC std_ss [le_refl]
5822QED
5823
5824Theorem FN_MINUS_TO_PLUS :
5825    !f. fn_minus (\x. -(f x)) = fn_plus f
5826Proof
5827    RW_TAC std_ss [fn_plus_def, fn_minus_def, neg_neg]
5828 >> `!x. -f x < 0 <=> 0 < f x` by PROVE_TAC [neg_0, lt_neg]
5829 >> POP_ORW >> REWRITE_TAC []
5830QED
5831
5832Theorem FN_PLUS_TO_MINUS :
5833    !f. fn_plus (\x. -(f x)) = fn_minus f
5834Proof
5835    RW_TAC std_ss [fn_plus_def, fn_minus_def, neg_neg]
5836 >> `!x. 0 < -f x <=> f x < 0` by PROVE_TAC [neg_0, lt_neg]
5837 >> POP_ORW >> REWRITE_TAC []
5838QED
5839
5840Theorem FN_PLUS_NOT_INFTY :
5841    !f x. f x <> PosInf ==> fn_plus f x <> PosInf
5842Proof
5843    RW_TAC std_ss [fn_plus_def]
5844 >> Cases_on `0 < f x` >- PROVE_TAC []
5845 >> PROVE_TAC [extreal_not_infty, extreal_of_num_def]
5846QED
5847
5848Theorem FN_MINUS_NOT_INFTY :
5849    !f x. f x <> NegInf ==> fn_minus f x <> PosInf
5850Proof
5851    RW_TAC std_ss [fn_minus_def]
5852 >> Cases_on `f x < 0`
5853 >- PROVE_TAC [extreal_ainv_def, neg_neg]
5854 >> PROVE_TAC [extreal_not_infty, extreal_of_num_def]
5855QED
5856
5857Theorem FN_PLUS_CMUL:
5858    !f c. (0 <= c ==> (fn_plus (\x. Normal c * f x) = (\x. Normal c * fn_plus f x))) /\
5859          (c <= 0 ==> (fn_plus (\x. Normal c * f x) = (\x. -Normal c * fn_minus f x)))
5860Proof
5861    RW_TAC std_ss [fn_plus_def,fn_minus_def,FUN_EQ_THM]
5862 >- (Cases_on `0 < f x`
5863     >- METIS_TAC [let_mul, extreal_of_num_def, extreal_le_def, extreal_lt_def, le_antisym]
5864     >> RW_TAC std_ss [mul_rzero]
5865     >> METIS_TAC [mul_le, extreal_lt_def, extreal_le_def, extreal_of_num_def, lt_imp_le,
5866                   le_antisym])
5867 >> RW_TAC std_ss [mul_rzero, neg_mul2]
5868 >- METIS_TAC [mul_le, extreal_of_num_def, extreal_le_def, extreal_lt_def, lt_imp_le,
5869               le_antisym, mul_comm]
5870 >> METIS_TAC [le_mul_neg, extreal_of_num_def, extreal_le_def, lt_imp_le, extreal_lt_def,
5871               le_antisym]
5872QED
5873
5874(* NOTE: This (new) lemma is more general than FN_PLUS_CMUL_full because sometimes ‘c’
5875   depends on ‘x’. But the proof is the same.
5876 *)
5877Theorem fn_plus_cmul :
5878    !f c x. (0 <= c ==> fn_plus (\x. c * f x) x = c * fn_plus f x) /\
5879            (c <= 0 ==> fn_plus (\x. c * f x) x = -c * fn_minus f x)
5880Proof
5881    rpt GEN_TAC
5882 >> Cases_on `c`
5883 >- (SIMP_TAC std_ss [le_infty, extreal_not_infty, extreal_of_num_def] \\
5884     RW_TAC std_ss [fn_plus_def, fn_minus_def] >| (* 4 subgoals *)
5885     [ (* goal 1 (of 4) *)
5886       REWRITE_TAC [neg_mul2],
5887       (* goal 2 (of 4) *)
5888      `0 <= f x` by PROVE_TAC [extreal_lt_def] \\
5889      `NegInf <= 0` by PROVE_TAC [le_infty] \\
5890      `NegInf * f x <= 0` by PROVE_TAC [mul_le2] \\
5891       PROVE_TAC [let_antisym],
5892       (* goal 3 (of 4) *)
5893      `NegInf < 0` by PROVE_TAC [lt_infty, extreal_of_num_def] \\
5894      `0 < NegInf * f x` by PROVE_TAC [lt_mul_neg],
5895       (* goal 4 (of 4) *)
5896       REWRITE_TAC [mul_rzero] ])
5897 >- (SIMP_TAC std_ss [le_infty, extreal_not_infty, extreal_of_num_def] \\
5898     RW_TAC std_ss [fn_plus_def] >| (* 3 subgoals *)
5899     [ (* goal 1 (of 3) *)
5900      `f x <= 0` by PROVE_TAC [extreal_lt_def] \\
5901       fs [le_lt] \\
5902      `0 < PosInf` by PROVE_TAC [lt_infty, extreal_of_num_def] \\
5903      `PosInf * f x < 0` by PROVE_TAC [mul_lt] \\
5904       PROVE_TAC [lt_antisym],
5905       (* goal 2 (of 3) *)
5906      `0 < PosInf` by PROVE_TAC [lt_infty, extreal_of_num_def] \\
5907      `0 < PosInf * f x` by PROVE_TAC [lt_mul],
5908       (* goal 3 (of 3) *)
5909       REWRITE_TAC [mul_rzero] ])
5910 >> rpt STRIP_TAC
5911 >| [ (* goal 1 (of 2) *)
5912     `0 <= r` by PROVE_TAC [extreal_le_eq, extreal_of_num_def] \\
5913      METIS_TAC [FN_PLUS_CMUL],
5914      (* goal 2 (of 2) *)
5915     `r <= 0` by PROVE_TAC [extreal_le_eq, extreal_of_num_def] \\
5916      METIS_TAC [FN_PLUS_CMUL] ]
5917QED
5918
5919Theorem FN_PLUS_CMUL_full :
5920    !f c. (0 <= c ==> (fn_plus (\x. c * f x) = (\x. c * fn_plus f x))) /\
5921          (c <= 0 ==> (fn_plus (\x. c * f x) = (\x. -c * fn_minus f x)))
5922Proof
5923    RW_TAC std_ss [FUN_EQ_THM, fn_plus_cmul]
5924QED
5925
5926Theorem FN_MINUS_CMUL:
5927    !f c. (0 <= c ==> (fn_minus (\x. Normal c * f x) = (\x. Normal c * fn_minus f x))) /\
5928          (c <= 0 ==> (fn_minus (\x. Normal c * f x) = (\x. -Normal c * fn_plus f x)))
5929Proof
5930    RW_TAC std_ss [fn_plus_def,fn_minus_def,FUN_EQ_THM]
5931 >- (RW_TAC std_ss [mul_rzero, mul_rneg, neg_eq0]
5932     >- METIS_TAC [le_mul, extreal_of_num_def, extreal_le_def, extreal_lt_def, lt_imp_le,
5933                   le_antisym]
5934     >> METIS_TAC [mul_le, extreal_of_num_def, extreal_le_def, lt_imp_le, extreal_lt_def,
5935                   le_antisym, neg_eq0])
5936 >> RW_TAC std_ss [mul_rzero, neg_eq0, mul_lneg, neg_0]
5937 >- METIS_TAC [le_mul_neg, extreal_of_num_def, extreal_le_def, extreal_lt_def, lt_imp_le,
5938               le_antisym]
5939 >> METIS_TAC [mul_le, extreal_of_num_def, extreal_le_def, lt_imp_le, extreal_lt_def,
5940               le_antisym, neg_eq0, mul_comm]
5941QED
5942
5943Theorem fn_minus_cmul :
5944    !f c x. (0 <= c ==> fn_minus (\x. c * f x) x = c * fn_minus f x) /\
5945            (c <= 0 ==> fn_minus (\x. c * f x) x = -c * fn_plus f x)
5946Proof
5947    rpt GEN_TAC
5948 >> Cases_on `c`
5949 >- (SIMP_TAC std_ss [le_infty, extreal_not_infty, extreal_of_num_def] \\
5950     RW_TAC std_ss [fn_plus_def, fn_minus_def] >| (* 4 subgoals *)
5951     [ (* goal 1 (of 4) *)
5952       REWRITE_TAC [GSYM mul_lneg],
5953       (* goal 2 (of 4) *)
5954      `f x <= 0` by PROVE_TAC [extreal_lt_def] \\
5955      `NegInf <= 0` by PROVE_TAC [le_infty] \\
5956      `0 <= NegInf * f x` by PROVE_TAC [le_mul_neg] \\
5957       PROVE_TAC [let_antisym],
5958       (* goal 3 (of 4) *)
5959      `NegInf < 0` by PROVE_TAC [lt_infty, extreal_of_num_def] \\
5960      `NegInf * f x < 0` by PROVE_TAC [mul_lt2],
5961       (* goal 4 (of 4) *)
5962       REWRITE_TAC [mul_rzero] ])
5963 >- (SIMP_TAC std_ss [le_infty, extreal_not_infty, extreal_of_num_def] \\
5964     RW_TAC std_ss [fn_minus_def] >| (* 4 subgoals *)
5965     [ (* goal 1 (of 4) *)
5966       REWRITE_TAC [GSYM mul_rneg],
5967       (* goal 2 (of 4) *)
5968      `0 <= f x` by PROVE_TAC [extreal_lt_def] \\
5969      `0 <= PosInf` by PROVE_TAC [le_infty] \\
5970      `0 <= PosInf * f x` by PROVE_TAC [le_mul] \\
5971       PROVE_TAC [let_antisym],
5972       (* goal 3 (of 4) *)
5973      `0 < PosInf` by PROVE_TAC [lt_infty, extreal_of_num_def] \\
5974      `PosInf * f x < 0` by PROVE_TAC [mul_lt],
5975       (* goal 3 (of 4) *)
5976       REWRITE_TAC [mul_rzero] ])
5977 >> rpt STRIP_TAC
5978 >| [ (* goal 1 (of 2) *)
5979     `0 <= r` by PROVE_TAC [extreal_le_eq, extreal_of_num_def] \\
5980      METIS_TAC [FN_MINUS_CMUL],
5981      (* goal 2 (of 2) *)
5982     `r <= 0` by PROVE_TAC [extreal_le_eq, extreal_of_num_def] \\
5983      METIS_TAC [FN_MINUS_CMUL] ]
5984QED
5985
5986Theorem FN_MINUS_CMUL_full :
5987    !f c. (0 <= c ==> (fn_minus (\x. c * f x) = (\x. c * fn_minus f x))) /\
5988          (c <= 0 ==> (fn_minus (\x. c * f x) = (\x. -c * fn_plus f x)))
5989Proof
5990    RW_TAC std_ss [FUN_EQ_THM, fn_minus_cmul]
5991QED
5992
5993Theorem fn_plus_fmul :
5994    !f c x. 0 <= c x ==> fn_plus (\x. c x * f x) x = c x * fn_plus f x
5995Proof
5996    rpt GEN_TAC >> DISCH_TAC
5997 >> simp [fn_plus_def]
5998 >> Cases_on `0 < f x`
5999 >- (`0 <= c x * f x` by PROVE_TAC [let_mul] \\
6000     fs [le_lt])
6001 >> `f x <= 0` by PROVE_TAC [extreal_lt_def]
6002 >> `c x * f x <= 0` by PROVE_TAC [mul_le]
6003 >> `~(0 < c x * f x)` by PROVE_TAC [extreal_lt_def]
6004 >> fs [mul_rzero]
6005QED
6006
6007Theorem FN_PLUS_FMUL :
6008    !f c. (!x. 0 <= c x) ==> fn_plus (\x. c x * f x) = (\x. c x * fn_plus f x)
6009Proof
6010    RW_TAC std_ss [FUN_EQ_THM, fn_plus_fmul]
6011QED
6012
6013Theorem fn_minus_fmul :
6014    !f c x. 0 <= c x ==> fn_minus (\x. c x * f x) x = c x * fn_minus f x
6015Proof
6016    rpt GEN_TAC >> DISCH_TAC
6017 >> simp [fn_minus_def]
6018 >> Cases_on `0 < f x`
6019 >- (`0 <= c x * f x` by PROVE_TAC [let_mul] \\
6020     `~(c x * f x < 0)` by PROVE_TAC [extreal_lt_def] \\
6021     `~(f x < 0)` by PROVE_TAC [lt_antisym] \\
6022     fs [mul_rzero])
6023 >> `f x <= 0` by PROVE_TAC [extreal_lt_def]
6024 >> `c x * f x <= 0` by PROVE_TAC [mul_le]
6025 >> `~(0 < c x * f x)` by PROVE_TAC [extreal_lt_def]
6026 >> fs [le_lt, lt_refl, mul_rzero, neg_0]
6027 >- REWRITE_TAC [GSYM mul_rneg]
6028 >> fs [entire, neg_0]
6029QED
6030
6031Theorem FN_MINUS_FMUL :
6032    !f c. (!x. 0 <= c x) ==> fn_minus (\x. c x * f x) = (\x. c x * fn_minus f x)
6033Proof
6034    RW_TAC std_ss [FUN_EQ_THM, fn_minus_fmul]
6035QED
6036
6037Theorem FN_PLUS_ADD_LE:
6038    !f g x. fn_plus (\x. f x + g x) x <= (fn_plus f x) + (fn_plus g x)
6039Proof
6040    RW_TAC real_ss [fn_plus_def, add_rzero, add_lzero, le_refl, le_add2]
6041 >> METIS_TAC [le_refl, extreal_lt_def, le_add2, add_lzero, add_rzero, lt_imp_le]
6042QED
6043
6044(* more antecedents added: no mixing of PosInf and NegInf *)
6045Theorem FN_MINUS_ADD_LE:
6046    !f g x. (f x <> NegInf) /\ (g x <> NegInf) \/
6047            (f x <> PosInf) /\ (g x <> PosInf) ==>
6048            fn_minus (\x. f x + g x) x <= (fn_minus f x) + (fn_minus g x)
6049Proof
6050    rpt GEN_TAC
6051 >> DISCH_TAC
6052 >> MP_TAC (BETA_RULE (Q.SPECL [`\x. -f x`, `\x. -g x`, `x`] FN_PLUS_ADD_LE))
6053 >> Suff `fn_plus (\x. -f x + -g x) x = fn_minus (\x. f x + g x) x`
6054 >- (Rewr' >> REWRITE_TAC [FN_PLUS_TO_MINUS])
6055 >> SIMP_TAC std_ss [fn_plus_def, fn_minus_def]
6056 >> Know `-f x + -g x = -(f x + g x)`
6057 >- (MATCH_MP_TAC EQ_SYM >> MATCH_MP_TAC neg_add >> art []) >> Rewr
6058 >> `0 < -(f x + g x) <=> f x + g x < 0` by PROVE_TAC [neg_0, lt_neg] >> POP_ORW
6059 >> REWRITE_TAC []
6060QED
6061
6062Theorem FN_PLUS_LE_ABS :
6063    !f x. fn_plus f x <= abs (f x)
6064Proof
6065    rpt GEN_TAC >> REWRITE_TAC [SIMP_RULE std_ss [o_DEF] FN_ABS]
6066 >> ACCEPT_TAC
6067      (((REWRITE_RULE [le_refl, add_rzero, FN_MINUS_POS]) o
6068        (Q.SPECL [`fn_plus f x`, `fn_plus f x`, `0`, `fn_minus f x`])) le_add2)
6069QED
6070
6071Theorem FN_MINUS_LE_ABS :
6072    !f x. fn_minus f x <= abs (f x)
6073Proof
6074    rpt GEN_TAC >> REWRITE_TAC [SIMP_RULE std_ss [o_DEF] FN_ABS]
6075 >> ACCEPT_TAC
6076      (((REWRITE_RULE [le_refl, add_lzero, FN_PLUS_POS]) o
6077        (Q.SPECL [`0`, `fn_plus f x`, `fn_minus f x`, `fn_minus f x`])) le_add2)
6078QED
6079
6080(* A balance between fn_plus and fn_minus *)
6081Theorem FN_PLUS_INFTY_IMP :
6082    !f x. (fn_plus f x = PosInf) ==> (fn_minus f x = 0)
6083Proof
6084    rpt STRIP_TAC
6085 >> Suff ‘f x = PosInf’
6086 >- (DISCH_TAC >> MATCH_MP_TAC FN_MINUS_REDUCE \\
6087     POP_ORW >> REWRITE_TAC [extreal_of_num_def, extreal_le_def])
6088 >> CCONTR_TAC
6089 >> Suff ‘fn_plus f x <> PosInf’ >- PROVE_TAC []
6090 >> Q.PAT_X_ASSUM ‘fn_plus f x = PosInf’ K_TAC
6091 >> RW_TAC std_ss [fn_plus_def]
6092 >> PROVE_TAC [extreal_not_infty, extreal_of_num_def]
6093QED
6094
6095Theorem FN_MINUS_INFTY_IMP :
6096    !f x. (fn_minus f x = PosInf) ==> (fn_plus f x = 0)
6097Proof
6098    rpt STRIP_TAC
6099 >> Suff ‘f x = NegInf’
6100 >- (DISCH_TAC \\
6101     RW_TAC std_ss [fn_plus_def, FUN_EQ_THM] \\
6102     fs [lt_infty, extreal_of_num_def])
6103 >> CCONTR_TAC
6104 >> Suff ‘fn_minus f x <> PosInf’ >- PROVE_TAC []
6105 >> Q.PAT_X_ASSUM ‘fn_minus f x = PosInf’ K_TAC
6106 >> reverse (RW_TAC std_ss [fn_minus_def])
6107 >- PROVE_TAC [extreal_not_infty, extreal_of_num_def]
6108 >> CCONTR_TAC >> fs []
6109 >> METIS_TAC [neg_neg, extreal_ainv_def]
6110QED
6111
6112(* ******************************************* *)
6113(*   Non-negative functions (not very useful)  *)
6114(* ******************************************* *)
6115
6116Definition nonneg_def:
6117    nonneg (f :'a -> extreal) = !x. 0 <= f x
6118End
6119
6120Theorem nonneg_abs:   !f. nonneg (abs o f)
6121Proof
6122    RW_TAC std_ss [o_DEF, nonneg_def, abs_pos]
6123QED
6124
6125Theorem nonneg_fn_abs:   !f. nonneg f ==> (abs o f = f)
6126Proof
6127    RW_TAC std_ss [nonneg_def, o_DEF, FUN_EQ_THM, abs_refl]
6128QED
6129
6130Theorem nonneg_fn_plus:   !f. nonneg f ==> (fn_plus f = f)
6131Proof
6132    RW_TAC std_ss [nonneg_def, fn_plus_def]
6133 >> FUN_EQ_TAC
6134 >> RW_TAC std_ss []
6135 >> PROVE_TAC [le_lt]
6136QED
6137
6138Theorem nonneg_fn_minus:   !f. nonneg f ==> (fn_minus f = (\x. 0))
6139Proof
6140    RW_TAC std_ss [nonneg_def, fn_minus_def]
6141 >> FUN_EQ_TAC
6142 >> RW_TAC std_ss [extreal_lt_def]
6143QED
6144
6145(* ------------------------------------------------------------------------- *)
6146(*  Indicator functions                                                      *)
6147(* ------------------------------------------------------------------------- *)
6148
6149(* `indicator_fn s` maps x to 0 or 1 when x IN or NOTIN s,
6150
6151   The new definition is based on the real-valued iterateTheory.indicator:
6152 *)
6153Definition indicator_fn :
6154    indicator_fn s = Normal o indicator s
6155End
6156
6157Theorem normal_indicator :
6158    !s x. Normal (indicator s x) = indicator_fn s x
6159Proof
6160    rw [indicator_fn, o_DEF]
6161QED
6162
6163(* The old definition now becomes an equivalent theorem *)
6164Theorem indicator_fn_def :
6165    !s. indicator_fn s = \x. if x IN s then (1 :extreal) else (0 :extreal)
6166Proof
6167    rw [indicator, indicator_fn, extreal_of_num_def, o_DEF, FUN_EQ_THM]
6168 >> Cases_on ‘x IN s’ >> rw []
6169QED
6170
6171(* MATHEMATICAL DOUBLE-STRUCK DIGIT ONE *)
6172val _ = Unicode.unicode_version {u = UTF8.chr 0x1D7D9, tmnm = "indicator_fn"};
6173val _ = TeX_notation {hol = UTF8.chr 0x1D7D9, TeX = ("\\HOLTokenOne{}", 1)};
6174val _ = TeX_notation {hol = "indicator_fn",   TeX = ("\\HOLTokenOne{}", 1)};
6175
6176Theorem DROP_INDICATOR_FN :
6177    !s x. indicator_fn s x = if x IN s then 1 else 0
6178Proof
6179    rw [indicator_fn, extreal_of_num_def, DROP_INDICATOR]
6180QED
6181
6182Theorem INDICATOR_FN_POS :
6183    !s x. 0 <= indicator_fn s x
6184Proof
6185    rw [indicator_fn, extreal_of_num_def, extreal_le_eq, DROP_INDICATOR_POS_LE]
6186QED
6187
6188Theorem ABS_INDICATOR_FN[simp] :
6189    !s x. abs (indicator_fn s x) = indicator_fn s x
6190Proof
6191    rw [abs_refl, INDICATOR_FN_POS]
6192QED
6193
6194Theorem INDICATOR_FN_LE_1 :
6195    !s x. indicator_fn s x <= 1
6196Proof
6197    rw [indicator_fn, extreal_of_num_def, extreal_le_eq, DROP_INDICATOR_LE_1]
6198QED
6199
6200Theorem INDICATOR_FN_NOT_INFTY:
6201    !s x. indicator_fn s x <> NegInf /\ indicator_fn s x <> PosInf
6202Proof
6203    RW_TAC std_ss []
6204 >- (MATCH_MP_TAC pos_not_neginf >> REWRITE_TAC [INDICATOR_FN_POS])
6205 >> Cases_on `x IN s`
6206 >> ASM_SIMP_TAC std_ss [indicator_fn_def, extreal_of_num_def, extreal_not_infty]
6207QED
6208
6209(* "advanced" lemmas/theorems should have lower-case names *)
6210Theorem indicator_fn_normal :
6211    !s x. ?r. (indicator_fn s x = Normal r) /\ 0 <= r /\ r <= 1
6212Proof
6213    rpt STRIP_TAC
6214 >> `?r. indicator_fn s x = Normal r`
6215       by METIS_TAC [extreal_cases, INDICATOR_FN_NOT_INFTY]
6216 >> Q.EXISTS_TAC `r` >> art []
6217 >> METIS_TAC [INDICATOR_FN_POS, INDICATOR_FN_LE_1, extreal_le_eq,
6218               extreal_of_num_def]
6219QED
6220
6221Theorem INDICATOR_FN_SING_1:   !x y. (x = y) ==> (indicator_fn {x} y = 1)
6222Proof
6223    RW_TAC std_ss [indicator_fn_def, IN_SING]
6224QED
6225
6226Theorem INDICATOR_FN_SING_0:   !x y. x <> y ==> (indicator_fn {x} y = 0)
6227Proof
6228    RW_TAC std_ss [indicator_fn_def, IN_SING]
6229QED
6230
6231Theorem INDICATOR_FN_EMPTY[simp] :
6232    !x. indicator_fn {} x = 0
6233Proof
6234    RW_TAC std_ss [indicator_fn_def, NOT_IN_EMPTY]
6235QED
6236
6237Theorem INDICATOR_FN_UNIV :
6238    !x. indicator_fn UNIV (x :'a) = 1
6239Proof
6240    rw [indicator_fn_def]
6241QED
6242
6243(* Properties of the indicator function [1, p.14] *)
6244Theorem INDICATOR_FN_INTER:
6245    !A B. indicator_fn (A INTER B) = (\t. (indicator_fn A t) * (indicator_fn B t))
6246Proof
6247    RW_TAC std_ss [FUN_EQ_THM]
6248 >> `indicator_fn (A INTER B) t = if t IN (A INTER B) then 1 else 0`
6249      by METIS_TAC [indicator_fn_def]
6250 >> RW_TAC std_ss [indicator_fn_def, mul_lone, IN_INTER, mul_lzero]
6251 >> FULL_SIMP_TAC std_ss []
6252QED
6253
6254Theorem INDICATOR_FN_MUL_INTER:
6255    !A B. (\t. (indicator_fn A t) * (indicator_fn B t)) = (\t. indicator_fn (A INTER B) t)
6256Proof
6257    RW_TAC std_ss [FUN_EQ_THM]
6258 >> `indicator_fn (A INTER B) t = if t IN (A INTER B) then 1 else 0`
6259       by METIS_TAC [indicator_fn_def]
6260 >> RW_TAC std_ss [indicator_fn_def, mul_lone, IN_INTER, mul_lzero]
6261 >> FULL_SIMP_TAC real_ss []
6262QED
6263
6264Theorem INDICATOR_FN_INTER_MIN:
6265    !A B. indicator_fn (A INTER B) = (\t. min (indicator_fn A t) (indicator_fn B t))
6266Proof
6267    RW_TAC std_ss [FUN_EQ_THM]
6268 >> `indicator_fn (A INTER B) t = if t IN (A INTER B) then 1 else 0`
6269      by METIS_TAC [indicator_fn_def]
6270 >> fs [indicator_fn_def, IN_INTER]
6271 >> Cases_on `t IN A` >> Cases_on `t IN B`
6272 >> fs [extreal_of_num_def, extreal_min_def, extreal_le_eq]
6273QED
6274
6275Theorem INDICATOR_FN_DIFF:
6276    !A B. indicator_fn (A DIFF B) = (\t. indicator_fn A t - indicator_fn (A INTER B) t)
6277Proof
6278    RW_TAC std_ss [FUN_EQ_THM]
6279 >> `indicator_fn (A DIFF B) t = if t IN (A DIFF B) then 1 else 0`
6280      by METIS_TAC [indicator_fn_def]
6281 >> fs [indicator_fn_def, IN_DIFF, IN_INTER]
6282 >> Cases_on `t IN A` >> Cases_on `t IN B` >> fs [sub_rzero]
6283 >> MATCH_MP_TAC EQ_SYM
6284 >> MATCH_MP_TAC sub_refl
6285 >> PROVE_TAC [extreal_of_num_def, extreal_not_infty]
6286QED
6287
6288Theorem INDICATOR_FN_DIFF_SPACE:
6289    !A B sp. A SUBSET sp /\ B SUBSET sp ==>
6290            (indicator_fn (A INTER (sp DIFF B)) =
6291             (\t. indicator_fn A t - indicator_fn (A INTER B) t))
6292Proof
6293    RW_TAC std_ss [FUN_EQ_THM]
6294 >> `indicator_fn (A DIFF B) t = if t IN (A DIFF B) then 1 else 0`
6295      by METIS_TAC [indicator_fn_def]
6296 >> fs [indicator_fn_def, IN_DIFF, IN_INTER]
6297 >> Cases_on `t IN A` >> Cases_on `t IN B` >> fs [SUBSET_DEF, sub_rzero]
6298 >> MATCH_MP_TAC EQ_SYM
6299 >> MATCH_MP_TAC sub_refl
6300 >> PROVE_TAC [extreal_of_num_def, extreal_not_infty]
6301QED
6302
6303Theorem INDICATOR_FN_UNION_MAX:
6304    !A B. indicator_fn (A UNION B) = (\t. max (indicator_fn A t) (indicator_fn B t))
6305Proof
6306    RW_TAC std_ss [FUN_EQ_THM]
6307 >> `indicator_fn (A UNION B) t = if t IN (A UNION B) then 1 else 0`
6308      by METIS_TAC [indicator_fn_def]
6309 >> fs [indicator_fn_def, IN_UNION]
6310 >> Cases_on `t IN A` >> Cases_on `t IN B`
6311 >> fs [extreal_max_def, extreal_le_eq, extreal_of_num_def]
6312QED
6313
6314Theorem INDICATOR_FN_UNION_MIN:
6315    !A B. indicator_fn (A UNION B) = (\t. min (indicator_fn A t + indicator_fn B t) 1)
6316Proof
6317    RW_TAC std_ss [FUN_EQ_THM]
6318 >> `indicator_fn (A UNION B) t = if t IN (A UNION B) then 1 else 0`
6319      by METIS_TAC [indicator_fn_def]
6320 >> fs [indicator_fn_def, IN_UNION]
6321 >> Cases_on `t IN A` >> Cases_on `t IN B`
6322 >> fs [extreal_max_def, extreal_add_def, extreal_of_num_def, extreal_min_def, extreal_le_eq]
6323QED
6324
6325Theorem INDICATOR_FN_UNION:
6326    !A B. indicator_fn (A UNION B) =
6327          (\t. indicator_fn A t + indicator_fn B t - indicator_fn (A INTER B) t)
6328Proof
6329    RW_TAC std_ss [FUN_EQ_THM]
6330 >> `indicator_fn (A INTER B) t = if t IN (A INTER B) then 1 else 0`
6331      by METIS_TAC [indicator_fn_def]
6332 >> `indicator_fn (A UNION B) t = if t IN (A UNION B) then 1 else 0`
6333      by METIS_TAC [indicator_fn_def]
6334 >> fs [indicator_fn_def, IN_UNION, IN_INTER]
6335 >> Cases_on `t IN A` >> Cases_on `t IN B` >> fs [add_lzero, add_rzero, mul_rzero, sub_rzero]
6336 >> fs [extreal_add_def, extreal_sub_def, extreal_of_num_def]
6337QED
6338
6339Theorem INDICATOR_FN_MONO :
6340    !s t x. s SUBSET t ==> indicator_fn s x <= indicator_fn t x
6341Proof
6342    rpt STRIP_TAC
6343 >> Cases_on ‘x IN s’
6344 >- (‘x IN t’ by PROVE_TAC [SUBSET_DEF] \\
6345     rw [indicator_fn_def, le_refl])
6346 >> ‘indicator_fn s x = 0’ by METIS_TAC [indicator_fn_def] >> POP_ORW
6347 >> REWRITE_TAC [INDICATOR_FN_POS]
6348QED
6349
6350Theorem INDICATOR_FN_CROSS :
6351    !s t x y. indicator_fn (s CROSS t) (x,y) = indicator_fn s x *
6352                                               indicator_fn t y
6353Proof
6354    rw [indicator_fn_def]
6355 >> PROVE_TAC []
6356QED
6357
6358Theorem indicator_fn_split :
6359    !(r:num->bool) s (b:num->('a->bool)).
6360       FINITE r /\ (BIGUNION (IMAGE b r) = s) /\
6361       (!i j. i IN r /\ j IN r /\ i <> j ==> DISJOINT (b i) (b j)) ==>
6362       !a. a SUBSET s ==>
6363          (indicator_fn a = (\x. SIGMA (\i. indicator_fn (a INTER (b i)) x) r))
6364Proof
6365    Suff `!r. FINITE r ==>
6366            (\r. !s (b:num->('a->bool)).
6367             FINITE r /\
6368             (BIGUNION (IMAGE b r) = s) /\
6369             (!i j. i IN r /\ j IN r /\ i <> j ==> DISJOINT (b i) (b j)) ==>
6370             !a. a SUBSET s ==>
6371                 ((indicator_fn a) =
6372                  (\x. SIGMA (\i. indicator_fn (a INTER (b i)) x) r))) r`
6373 >- METIS_TAC []
6374 >> MATCH_MP_TAC FINITE_INDUCT
6375 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_EMPTY, IMAGE_EMPTY, BIGUNION_EMPTY,
6376                   SUBSET_EMPTY, indicator_fn_def, NOT_IN_EMPTY,
6377                   FINITE_INSERT, IMAGE_INSERT, DELETE_NON_ELEMENT,
6378                   IN_INSERT, BIGUNION_INSERT]
6379 >> Q.PAT_X_ASSUM `!b. P ==> !a. Q ==> (x = y)`
6380      (MP_TAC o Q.ISPEC `(b :num -> 'a -> bool)`)
6381 >> RW_TAC std_ss [SUBSET_DEF]
6382 >> POP_ASSUM (MP_TAC o Q.ISPEC `a DIFF ((b :num -> 'a -> bool) e)`)
6383 >> Know `(!x. x IN a DIFF b e ==> x IN BIGUNION (IMAGE b s))`
6384 >- METIS_TAC [SUBSET_DEF, IN_UNION, IN_DIFF]
6385 >> RW_TAC std_ss [FUN_EQ_THM]
6386 >> `!i. i IN e INSERT s ==> (\i. if x IN a INTER b i then 1 else 0) i <> NegInf`
6387      by METIS_TAC [extreal_of_num_def, extreal_not_infty]
6388 >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY]
6389 >> Know `SIGMA (\i. (if x IN a INTER b i then 1 else 0)) s =
6390          SIGMA (\i. (if x IN (a DIFF b e) INTER b i then 1 else 0)) s`
6391 >- (`!i. i IN s ==> (\i. if x IN a INTER b i then 1 else 0) i <> NegInf`
6392      by METIS_TAC [extreal_of_num_def,extreal_not_infty] \\
6393     `!i. i IN s ==> (\i. if x IN (a DIFF b e) INTER b i then 1 else 0) i <> NegInf`
6394      by METIS_TAC [extreal_of_num_def,extreal_not_infty] \\
6395     FULL_SIMP_TAC std_ss [(Once o UNDISCH o Q.ISPEC `(s :num -> bool)`)
6396                               EXTREAL_SUM_IMAGE_IN_IF] \\
6397     FULL_SIMP_TAC std_ss [(Q.SPEC `(\i. if x IN (a DIFF b e) INTER b i then 1 else 0)`
6398                            o UNDISCH o Q.ISPEC `(s :num -> bool)`)
6399                               EXTREAL_SUM_IMAGE_IN_IF] \\
6400     MATCH_MP_TAC (METIS_PROVE [] ``!f x y z. (x = y) ==> (f x z = f y z)``) \\
6401     RW_TAC std_ss [FUN_EQ_THM, IN_INTER, IN_DIFF] \\
6402     FULL_SIMP_TAC real_ss [GSYM DELETE_NON_ELEMENT, DISJOINT_DEF, IN_INTER,
6403                            NOT_IN_EMPTY, EXTENSION, GSPECIFICATION] \\
6404     RW_TAC real_ss [extreal_of_num_def] >> METIS_TAC []) >> STRIP_TAC
6405 >> `SIGMA (\i. if x IN a INTER b i then 1 else 0) s = (if x IN a DIFF b e then 1 else 0)`
6406      by METIS_TAC []
6407 >> POP_ORW
6408 >> RW_TAC real_ss [IN_INTER, IN_DIFF, EXTREAL_SUM_IMAGE_ZERO, add_rzero, add_lzero]
6409 >> FULL_SIMP_TAC std_ss []
6410 >> `x IN BIGUNION (IMAGE b s)` by METIS_TAC [SUBSET_DEF,IN_UNION]
6411 >> FULL_SIMP_TAC std_ss [IN_BIGUNION_IMAGE]
6412 >> `s = {x'} UNION (s DIFF {x'})` by METIS_TAC [UNION_DIFF, SUBSET_DEF, IN_SING]
6413 >> POP_ORW
6414 >> `FINITE {x'} /\ FINITE (s DIFF {x'})` by METIS_TAC [FINITE_SING, FINITE_DIFF]
6415 >> `DISJOINT {x'} (s DIFF {x'})` by METIS_TAC [EXTENSION, IN_DISJOINT, IN_DIFF, IN_SING]
6416 >> `!i. (\i. if x IN b i then 1 else 0) i <> NegInf`
6417       by METIS_TAC [extreal_of_num_def,extreal_not_infty]
6418 >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_DISJOINT_UNION]
6419 >> RW_TAC std_ss [EXTREAL_SUM_IMAGE_SING]
6420 >> Suff `SIGMA (\i. if x IN b i then 1 else 0) (s DIFF {x'}) = 0`
6421 >- METIS_TAC [add_rzero]
6422 >> FULL_SIMP_TAC std_ss [(Once o UNDISCH o Q.ISPEC `(s :num -> bool) DIFF {x'}`)
6423                              EXTREAL_SUM_IMAGE_IN_IF]
6424 >> Suff `(\i. if i IN s DIFF {x'} then if x IN b i then 1 else 0 else 0) = (\x. 0)`
6425 >- RW_TAC std_ss [EXTREAL_SUM_IMAGE_ZERO]
6426 >> RW_TAC std_ss [FUN_EQ_THM, IN_DIFF, IN_SING]
6427 >> METIS_TAC [IN_SING, IN_DIFF, IN_DISJOINT]
6428QED
6429
6430Theorem indicator_fn_suminf :
6431    !a x. (!m n. m <> n ==> DISJOINT (a m) (a n)) ==>
6432          suminf (\i. indicator_fn (a i) x) =
6433          indicator_fn (BIGUNION (IMAGE a univ(:num))) x
6434Proof
6435    rpt STRIP_TAC
6436 >> Know `!n. 0 <= (\i. indicator_fn (a i) x) n`
6437 >- RW_TAC std_ss [INDICATOR_FN_POS]
6438 >> DISCH_THEN (MP_TAC o (MATCH_MP ext_suminf_def)) >> Rewr'
6439 >> RW_TAC std_ss [sup_eq', IN_UNIV, IN_IMAGE]
6440 >- (Cases_on `~(x IN BIGUNION (IMAGE a univ(:num)))`
6441     >- (FULL_SIMP_TAC std_ss [IN_BIGUNION_IMAGE, IN_UNIV] \\
6442         RW_TAC std_ss [indicator_fn_def, EXTREAL_SUM_IMAGE_ZERO, FINITE_COUNT, le_refl, le_01]) \\
6443     FULL_SIMP_TAC std_ss [IN_BIGUNION_IMAGE, IN_UNIV, indicator_fn_def] \\
6444     reverse (RW_TAC std_ss []) >- METIS_TAC [] \\
6445    `!n. n <> x' ==> ~(x IN a n)` by METIS_TAC [DISJOINT_DEF, EXTENSION, IN_INTER, NOT_IN_EMPTY] \\
6446     Cases_on `~(x' IN count n)`
6447     >- (`SIGMA (\i. if x IN a i then 1 else 0) (count n) = 0`
6448            by (MATCH_MP_TAC EXTREAL_SUM_IMAGE_0 \\
6449                RW_TAC real_ss [FINITE_COUNT] >> METIS_TAC []) \\
6450         RW_TAC std_ss [le_01]) \\
6451    `count n = ((count n) DELETE x') UNION {x'}`
6452        by (RW_TAC std_ss [EXTENSION, IN_DELETE, IN_UNION, IN_SING, IN_COUNT] \\
6453            METIS_TAC []) >> POP_ORW \\
6454    `DISJOINT ((count n) DELETE x') ({x'})`
6455        by RW_TAC std_ss [DISJOINT_DEF, EXTENSION,IN_INTER, NOT_IN_EMPTY, IN_SING, IN_DELETE] \\
6456    `!n. (\i. if x IN a i then 1 else 0) n <> NegInf` by RW_TAC std_ss [num_not_infty] \\
6457     FULL_SIMP_TAC std_ss [FINITE_COUNT, FINITE_DELETE, FINITE_SING,
6458                           EXTREAL_SUM_IMAGE_DISJOINT_UNION, EXTREAL_SUM_IMAGE_SING] \\
6459     Suff `SIGMA (\i. if x IN a i then 1 else 0) (count n DELETE x') = 0`
6460     >- RW_TAC std_ss [add_lzero, le_refl] \\
6461     MATCH_MP_TAC EXTREAL_SUM_IMAGE_0 \\
6462     RW_TAC std_ss [FINITE_COUNT, FINITE_DELETE] \\
6463     METIS_TAC [IN_DELETE])
6464 >> Know `!n. SIGMA (\i. indicator_fn (a i) x) (count n) <= y`
6465 >- (RW_TAC std_ss [] >> POP_ASSUM MATCH_MP_TAC \\
6466     Q.EXISTS_TAC `n` >> REWRITE_TAC []) >> DISCH_TAC
6467 >> reverse (RW_TAC std_ss [indicator_fn_def, IN_BIGUNION_IMAGE, IN_UNIV])
6468 >- (`0 <= SIGMA (\i. indicator_fn (a i) x) (count 0)`
6469        by RW_TAC std_ss [COUNT_ZERO, EXTREAL_SUM_IMAGE_EMPTY, le_refl] \\
6470     METIS_TAC [le_trans])
6471 >> rename1 `x IN a x''`
6472 >> Suff `SIGMA (\i. indicator_fn (a i) x) (count (SUC x'')) = 1`
6473 >- METIS_TAC []
6474 >> `!i. (\i. indicator_fn (a i) x) i <> NegInf`
6475        by RW_TAC std_ss [indicator_fn_def, num_not_infty]
6476 >> FULL_SIMP_TAC std_ss [EXTREAL_SUM_IMAGE_PROPERTY, FINITE_COUNT, COUNT_SUC]
6477 >> Suff `SIGMA (\i. indicator_fn (a i) x) (count x'' DELETE x'') = 0`
6478 >- RW_TAC std_ss [indicator_fn_def, add_rzero]
6479 >> `!n. n <> x'' ==> ~(x IN a n)` by METIS_TAC [DISJOINT_DEF,EXTENSION,IN_INTER,NOT_IN_EMPTY]
6480 >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_0
6481 >> FULL_SIMP_TAC std_ss [FINITE_COUNT, FINITE_DELETE, IN_COUNT, IN_DELETE, indicator_fn_def]
6482QED
6483
6484Theorem INDICATOR_FN_ABS[simp] :
6485    !s. abs o (indicator_fn s) = indicator_fn s
6486Proof
6487    GEN_TAC >> FUN_EQ_TAC
6488 >> RW_TAC std_ss [o_DEF]
6489 >> REWRITE_TAC [abs_refl, INDICATOR_FN_POS]
6490QED
6491
6492Theorem INDICATOR_FN_ABS_MUL :
6493    !f s. abs o (\x. f x * indicator_fn s x) = (\x. (abs o f) x * indicator_fn s x)
6494Proof
6495    RW_TAC std_ss [o_DEF, abs_mul]
6496 >> FUN_EQ_TAC
6497 >> RW_TAC std_ss []
6498 >> Suff `abs (indicator_fn s x) = indicator_fn s x` >- rw []
6499 >> rw [abs_refl, INDICATOR_FN_POS]
6500QED
6501
6502Theorem fn_plus_mul_indicator :
6503    !f s. fn_plus (\x. f x * indicator_fn s x) =
6504          (\x. fn_plus f x * indicator_fn s x)
6505Proof
6506    rpt GEN_TAC
6507 >> ONCE_REWRITE_TAC [mul_comm]
6508 >> MATCH_MP_TAC (Q.SPECL [‘f’, ‘indicator_fn s’] FN_PLUS_FMUL)
6509 >> GEN_TAC
6510 >> REWRITE_TAC [INDICATOR_FN_POS]
6511QED
6512
6513Theorem fn_minus_mul_indicator :
6514    !f s. fn_minus (\x. f x * indicator_fn s x) =
6515          (\x. fn_minus f x * indicator_fn s x)
6516Proof
6517    rpt GEN_TAC
6518 >> ONCE_REWRITE_TAC [mul_comm]
6519 >> MATCH_MP_TAC (Q.SPECL [‘f’, ‘indicator_fn s’] FN_MINUS_FMUL)
6520 >> GEN_TAC
6521 >> REWRITE_TAC [INDICATOR_FN_POS]
6522QED
6523
6524Theorem normal_mul_indicator :
6525    !c s x. Normal c * indicator_fn s x = Normal (c * indicator s x)
6526Proof
6527    rw [indicator_fn_def, indicator]
6528 >> simp [extreal_of_num_def]
6529QED
6530
6531(* ------------------------------------------------------------------------- *)
6532(* univ(:extreal) is metrizable                                              *)
6533(* ------------------------------------------------------------------------- *)
6534
6535Definition extreal_dist_def :
6536    extreal_dist (Normal x) (Normal y) = dist (bounded_metric mr1) (x,y) /\
6537    extreal_dist  PosInf     PosInf    = 0 /\
6538    extreal_dist  NegInf     NegInf    = 0 /\
6539    extreal_dist  _          _         = 1
6540End
6541
6542(* ‘extreal_dist’ is a valid metric *)
6543Theorem extreal_dist_ismet :
6544    ismet (UNCURRY extreal_dist)
6545Proof
6546    RW_TAC std_ss [ismet]
6547 >- (Cases_on ‘x’ >> Cases_on ‘y’ \\
6548     rw [extreal_dist_def, bounded_metric_thm, MR1_DEF] \\
6549     EQ_TAC >> rw [] \\
6550     fs [REAL_DIV_ZERO] \\
6551     rename1 ‘1 + abs (a - b)’ \\
6552     Suff ‘0 < 1 + abs (a - b)’ >- METIS_TAC [REAL_LT_IMP_NE] \\
6553     MATCH_MP_TAC REAL_LTE_TRANS \\
6554     Q.EXISTS_TAC ‘1’ >> rw [])
6555 >> Know ‘!a (b :real). dist (bounded_metric mr1) (a,b) <= 2’
6556 >- (rpt GEN_TAC \\
6557     MATCH_MP_TAC REAL_LE_TRANS >> Q.EXISTS_TAC ‘1’ >> rw [] \\
6558     MATCH_MP_TAC REAL_LT_IMP_LE >> rw [bounded_metric_lt_1])
6559 >> DISCH_TAC
6560 >> Cases_on ‘x’ >> Cases_on ‘y’ >> Cases_on ‘z’
6561 >> rw [extreal_dist_def, METRIC_POS]
6562 >> rename1 ‘dist (bounded_metric mr1) (x,z) <=
6563             dist (bounded_metric mr1) (y,x) + dist (bounded_metric mr1) (y,z)’
6564 >> ‘dist (bounded_metric mr1) (y,x) = dist (bounded_metric mr1) (x,y)’
6565      by PROVE_TAC [METRIC_SYM]
6566 >> rw [METRIC_TRIANGLE]
6567QED
6568
6569(* Thus ‘mtop extreal_mr1’ will be a possible topology of all extreals, and
6570  ‘open_in (mtop extreal_mr1)’ is the set of all extreal-valued "open" sets
6571  (w.r.t. ‘extreal_mr1’).
6572 *)
6573Definition extreal_mr1_def :
6574    extreal_mr1 = metric (UNCURRY extreal_dist)
6575End
6576
6577(* Use this theorem to actually calculate the "distance" between two extreals *)
6578Theorem extreal_mr1_thm :
6579    dist extreal_mr1 = UNCURRY extreal_dist
6580Proof
6581    METIS_TAC [extreal_mr1_def, extreal_dist_ismet, metric_tybij]
6582QED
6583
6584(* |- !x y. dist mr1 (x,y) = abs (x - y) *)
6585Theorem mr1_def[local] = ONCE_REWRITE_RULE [ABS_SUB] MR1_DEF
6586
6587Theorem extreal_dist_normal :
6588    !x y. extreal_dist (Normal x) (Normal y) = abs (x - y) / (1 + abs (x - y))
6589Proof
6590    rw [extreal_dist_def, bounded_metric_thm, mr1_def]
6591QED
6592
6593Theorem extreal_dist_normal' :
6594    !x y. extreal_dist (Normal x) (Normal y) = 1 - inv (1 + abs (x - y))
6595Proof
6596    rw [extreal_dist_def, bounded_metric_thm, bounded_metric_alt, mr1_def]
6597QED
6598
6599(* Use this theorem to calculate the "distance" between two normal extreals *)
6600Theorem extreal_mr1_normal :
6601    !x y. dist extreal_mr1 (Normal x,Normal y) = abs (x - y) / (1 + abs (x - y))
6602Proof
6603    rw [extreal_mr1_thm, extreal_dist_normal]
6604QED
6605
6606Theorem extreal_mr1_normal' :
6607    !x y. dist extreal_mr1 (Normal x,Normal y) = 1 - inv (1 + abs (x - y))
6608Proof
6609    rw [extreal_mr1_thm, extreal_dist_normal']
6610QED
6611
6612Theorem extreal_mr1_lt_1 :
6613    !x y. dist extreal_mr1 (Normal x,Normal y) < 1
6614Proof
6615    rw [extreal_mr1_thm, extreal_dist_normal']
6616 >> Suff ‘0 < inv (1 + abs (x - y))’ >- REAL_ARITH_TAC
6617 >> MATCH_MP_TAC REAL_INV_POS
6618 >> Q_TAC (TRANS_TAC REAL_LTE_TRANS) ‘1’ >> simp []
6619QED
6620
6621Theorem extreal_mr1_le_1 :
6622    !x y. dist extreal_mr1 (x,y) <= 1
6623Proof
6624    rpt GEN_TAC
6625 >> Cases_on ‘x’ >> Cases_on ‘y’
6626 >> rw [extreal_mr1_thm, extreal_dist_def]
6627 >> MATCH_MP_TAC REAL_LT_IMP_LE
6628 >> rw [bounded_metric_lt_1]
6629QED
6630
6631Theorem extreal_mr1_eq_1[simp] :
6632    dist extreal_mr1 (Normal r,PosInf) = 1 /\
6633    dist extreal_mr1 (Normal r,NegInf) = 1 /\
6634    dist extreal_mr1 (PosInf,Normal r) = 1 /\
6635    dist extreal_mr1 (NegInf,Normal r) = 1 /\
6636    dist extreal_mr1 (PosInf,NegInf) = 1 /\
6637    dist extreal_mr1 (NegInf,PosInf) = 1
6638Proof
6639    simp [extreal_mr1_thm, extreal_dist_def]
6640QED
6641
6642Theorem dist_triangle_add :
6643    !x1 y1 x2 y2. dist extreal_mr1 (x1 + y1,x2 + y2) <=
6644                  dist extreal_mr1 (x1,x2) + dist extreal_mr1 (y1,y2)
6645Proof
6646    rpt GEN_TAC
6647 >> Cases_on ‘x1 = PosInf’
6648 >- (Cases_on ‘y1 = PosInf’
6649     >- (simp [extreal_add_def] \\
6650         Cases_on ‘x2 = PosInf’
6651         >- (simp [MDIST_REFL] \\
6652             Cases_on ‘y2 = PosInf’ >- simp [MDIST_REFL, extreal_add_def] \\
6653             Cases_on ‘y2 = NegInf’ >- simp [extreal_mr1_le_1] \\
6654            ‘?r. y2 = Normal r’ by METIS_TAC [extreal_cases] \\
6655             simp [extreal_add_def, MDIST_REFL, MDIST_POS_LE]) \\
6656         Cases_on ‘x2 = NegInf’
6657         >- (simp [] \\
6658             Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6659             simp [REAL_LE_ADDR, MDIST_POS_LE, extreal_mr1_le_1]) \\
6660        ‘?r. x2 = Normal r’ by METIS_TAC [extreal_cases] \\
6661         simp [] \\
6662         Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6663         simp [REAL_LE_ADDR, MDIST_POS_LE, extreal_mr1_le_1]) \\
6664     Cases_on ‘y1 = NegInf’
6665     >- (simp [] \\
6666         Cases_on ‘x2 = PosInf’
6667         >- (simp [MDIST_REFL] \\
6668             Cases_on ‘y2 = PosInf’ >- simp [extreal_mr1_le_1] \\
6669             Cases_on ‘y2 = NegInf’ >- simp [MDIST_REFL, extreal_add_def] \\
6670            ‘?r. y2 = Normal r’ by METIS_TAC [extreal_cases] \\
6671             simp [extreal_add_def, extreal_mr1_le_1]) \\
6672         Cases_on ‘x2 = NegInf’
6673         >- (simp [] \\
6674             Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6675             simp [REAL_LE_ADDR, MDIST_POS_LE, extreal_mr1_le_1]) \\
6676        ‘?r. x2 = Normal r’ by METIS_TAC [extreal_cases] \\
6677         simp [] \\
6678         Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6679         simp [REAL_LE_ADDR, MDIST_POS_LE, extreal_mr1_le_1]) \\
6680    ‘?r. y1 = Normal r’ by METIS_TAC [extreal_cases] \\
6681     simp [extreal_add_def] \\
6682     Cases_on ‘y2 = PosInf’
6683     >- (simp [] \\
6684         Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6685         simp [REAL_LE_ADDL, MDIST_POS_LE, extreal_mr1_le_1]) \\
6686     Cases_on ‘y2 = NegInf’
6687     >- (simp [] \\
6688         Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6689         simp [REAL_LE_ADDL, MDIST_POS_LE, extreal_mr1_le_1]) \\
6690    ‘?z. y2 = Normal z’ by METIS_TAC [extreal_cases] >> POP_ORW \\
6691     Cases_on ‘x2 = NegInf’
6692     >- (simp [] \\
6693         Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6694         simp [REAL_LE_ADDR, MDIST_POS_LE, extreal_mr1_le_1]) \\
6695     Cases_on ‘x2 = PosInf’ >- simp [extreal_add_def, MDIST_POS_LE] \\
6696    ‘?a. x2 = Normal a’ by METIS_TAC [extreal_cases] \\
6697     simp [] \\
6698     Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6699     simp [REAL_LE_ADDR, MDIST_POS_LE, extreal_mr1_le_1])
6700 >> Cases_on ‘x1 = NegInf’
6701 >- (POP_ORW \\
6702     Cases_on ‘x2 = PosInf’
6703     >- (simp [] \\
6704         Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6705         simp [REAL_LE_ADDR, MDIST_POS_LE, extreal_mr1_le_1]) \\
6706     Cases_on ‘x2 = NegInf’
6707     >- (simp [MDIST_REFL] \\
6708         Cases_on ‘y1 = PosInf’
6709         >- (POP_ORW \\
6710             Cases_on ‘y2 = PosInf’ >- simp [MDIST_REFL] \\
6711             Cases_on ‘y2 = NegInf’ >- simp [extreal_mr1_le_1] \\
6712            ‘?r. y2 = Normal r’ by METIS_TAC [extreal_cases] \\
6713             simp [extreal_mr1_le_1]) \\
6714         Cases_on ‘y1 = NegInf’
6715         >- (simp [extreal_add_def] \\
6716             Cases_on ‘y2 = PosInf’ >- simp [extreal_mr1_le_1] \\
6717             Cases_on ‘y2 = NegInf’ >- simp [extreal_add_def] \\
6718            ‘?r. y2 = Normal r’ by METIS_TAC [extreal_cases] \\
6719             simp [extreal_add_def, extreal_mr1_le_1]) \\
6720        ‘?r. y1 = Normal r’ by METIS_TAC [extreal_cases] \\
6721         simp [extreal_add_def] \\
6722         Cases_on ‘y2 = PosInf’ >- simp [extreal_mr1_le_1] \\
6723         Cases_on ‘y2 = NegInf’ >- simp [extreal_mr1_le_1] \\
6724        ‘?z. y2 = Normal z’ by METIS_TAC [extreal_cases] \\
6725         simp [extreal_add_def, MDIST_REFL, MDIST_POS_LE]) \\
6726    ‘?r. x2 = Normal r’ by METIS_TAC [extreal_cases] >> POP_ORW \\
6727     simp [] \\
6728     Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6729     simp [REAL_LE_ADDR, MDIST_POS_LE, extreal_mr1_le_1])
6730 >> ‘?a. x1 = Normal a’ by METIS_TAC [extreal_cases] >> POP_ORW
6731 >> Cases_on ‘x2 = PosInf’
6732 >- (simp [] \\
6733     Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6734     simp [REAL_LE_ADDR, MDIST_POS_LE, extreal_mr1_le_1])
6735 >> Cases_on ‘x2 = NegInf’
6736 >- (simp [] \\
6737     Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6738     simp [REAL_LE_ADDR, MDIST_POS_LE, extreal_mr1_le_1])
6739 >> ‘?c. x2 = Normal c’ by METIS_TAC [extreal_cases] >> POP_ORW
6740 >> Cases_on ‘y1 = PosInf’
6741 >- (simp [extreal_add_def] \\
6742     Cases_on ‘y2 = PosInf’ >- simp [extreal_add_def, MDIST_POS_LE] \\
6743     Cases_on ‘y2 = NegInf’
6744     >- (simp [] \\
6745         Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6746         simp [REAL_LE_ADDL, MDIST_POS_LE, extreal_mr1_le_1]) \\
6747    ‘?r. y2 = Normal r’ by METIS_TAC [extreal_cases] \\
6748     simp [] \\
6749     Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6750     simp [REAL_LE_ADDL, MDIST_POS_LE, extreal_mr1_le_1])
6751 >> Cases_on ‘y1 = NegInf’
6752 >- (simp [extreal_add_def] \\
6753     Cases_on ‘y2 = PosInf’
6754     >- (simp [] \\
6755         Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6756         simp [REAL_LE_ADDL, MDIST_POS_LE, extreal_mr1_le_1]) \\
6757     Cases_on ‘y2 = NegInf’ >- simp [extreal_add_def, MDIST_REFL, MDIST_POS_LE] \\
6758    ‘?z. y2 = Normal z’ by METIS_TAC [extreal_cases] \\
6759     simp [] \\
6760     Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘1’ \\
6761     simp [REAL_LE_ADDL, MDIST_POS_LE, extreal_mr1_le_1])
6762 >> ‘?b. y1 = Normal b’ by METIS_TAC [extreal_cases] >> POP_ORW
6763 >> Cases_on ‘y2 = PosInf’ >- simp [extreal_add_def, MDIST_POS_LE]
6764 >> Cases_on ‘y2 = NegInf’ >- simp [extreal_add_def, MDIST_POS_LE]
6765 >> ‘?d. y2 = Normal d’ by METIS_TAC [extreal_cases] >> POP_ORW
6766 >> KILL_TAC
6767 >> simp [extreal_add_def, extreal_mr1_thm, extreal_dist_normal']
6768 >> qmatch_abbrev_tac ‘_ <= _ - x + (_ - y :real)’
6769 >> simp [REAL_ARITH “1 - x + (1 - y) = 1 - (x + y - (1 :real))”]
6770 >> REWRITE_TAC [REAL_LE_SUB_CANCEL1]
6771 >> REWRITE_TAC [REAL_ADD2_SUB2]
6772 >> qunabbrevl_tac [‘x’, ‘y’]
6773 >> Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘inv (1 + abs (a - c) + abs (b - d))’
6774 >> reverse CONJ_TAC
6775 >- (MATCH_MP_TAC REAL_INV_LE_ANTIMONO_IMPR \\
6776     CONJ_TAC
6777     >- (REWRITE_TAC [GSYM REAL_ADD_ASSOC] \\
6778         MATCH_MP_TAC REAL_LTE_ADD >> simp [REAL_LE_ADD, ABS_POS]) \\
6779     CONJ_TAC
6780     >- (MATCH_MP_TAC REAL_LTE_ADD >> simp [ABS_POS]) \\
6781     REWRITE_TAC [GSYM REAL_ADD_ASSOC, REAL_LE_LADD] \\
6782     REWRITE_TAC [ABS_TRIANGLE])
6783 >> qmatch_abbrev_tac ‘_ <= inv (1 + x + (y :real))’
6784 >> REWRITE_TAC [REAL_LE_SUB_RADD]
6785 >> REWRITE_TAC [REAL_INV_1OVER]
6786 >> Know ‘0 < 1 + x /\ 0 < 1 + y’
6787 >- (CONJ_TAC \\ (* 2 subgoals, same tactics *)
6788     MATCH_MP_TAC REAL_LTE_ADD >> simp [Abbr ‘x’, Abbr ‘y’, ABS_POS])
6789 >> STRIP_TAC
6790 >> ‘1 + x <> 0 /\ 1 + y <> 0’ by PROVE_TAC [REAL_LT_IMP_NE]
6791 >> ASM_SIMP_TAC real_ss [RAT_LEMMA2]
6792 >> ASM_SIMP_TAC real_ss [GSYM REAL_MUL_ASSOC, GSYM REAL_INV_MUL]
6793 >> ‘1 / (1 + x + y) + 1 = 1 / (1 + x + y) + 1 / 1’ by simp [] >> POP_ORW
6794 >> Know ‘0 < 1 + x + y’
6795 >- (REWRITE_TAC [GSYM REAL_ADD_ASSOC] \\
6796     MATCH_MP_TAC REAL_LTE_ADD \\
6797     simp [Abbr ‘x’, Abbr ‘y’, REAL_LE_ADD, ABS_POS])
6798 >> DISCH_TAC
6799 >> ‘0 < (1 :real)’ by simp []
6800 >> ASM_SIMP_TAC std_ss [RAT_LEMMA2]
6801 >> ‘1 + x + y <> 0’ by PROVE_TAC [REAL_LT_IMP_NE]
6802 >> simp [REAL_ADD_ASSOC]
6803 >> ‘1 + y + 1 + x = 2 + x + (y :real)’ by REAL_ARITH_TAC >> POP_ORW
6804 >> qabbrev_tac ‘z = 2 + x + y’
6805 >> MATCH_MP_TAC REAL_LE_RMUL_IMP
6806 >> ‘0 <= x /\ 0 <= y’ by simp [Abbr ‘x’, Abbr ‘y’, ABS_POS]
6807 >> CONJ_TAC
6808 >- (simp [Abbr ‘z’, GSYM REAL_ADD_ASSOC] \\
6809     MATCH_MP_TAC REAL_LE_ADD >> simp [] \\
6810     MATCH_MP_TAC REAL_LE_ADD >> simp [])
6811 >> simp [REAL_LDISTRIB, REAL_RDISTRIB, GSYM REAL_ADD_ASSOC]
6812 >> REWRITE_TAC [Once REAL_ADD_COMM]
6813 >> simp []
6814 >> MATCH_MP_TAC REAL_LE_MUL >> art []
6815QED
6816
6817(* cf. real_topologyTheory.euclidean_def *)
6818Definition ext_euclidean_def :
6819    ext_euclidean = mtop extreal_mr1
6820End
6821
6822Theorem topspace_ext_euclidean :
6823    topspace ext_euclidean = UNIV
6824Proof
6825    rw [TOPSPACE_MTOP, ext_euclidean_def]
6826QED
6827
6828Theorem mspace_extreal_mr1 :
6829    mspace extreal_mr1 = UNIV
6830Proof
6831    rw [mspace, GSYM ext_euclidean_def, topspace_ext_euclidean]
6832QED
6833
6834(* ------------------------------------------------------------------------- *)
6835(* Limits of extreal functions ('a -> extreal) and continuous functions      *)
6836(* ------------------------------------------------------------------------- *)
6837
6838Definition ext_tendsto :
6839    ext_tendsto = limit ext_euclidean
6840End
6841Overload "-->" = “ext_tendsto”
6842
6843Theorem ext_tendsto_def :
6844    !f l net. ext_tendsto f l net <=>
6845             !e. &0 < e ==> eventually (\x. dist extreal_mr1 (f(x),l) < e) net
6846Proof
6847    rw [ext_tendsto, ext_euclidean_def, limit, TOPSPACE_MTOP]
6848 >> EQ_TAC >> rpt STRIP_TAC
6849 >- (Q.PAT_X_ASSUM ‘!u. open_in (mtop extreal_mr1) u /\ l IN u ==> P’
6850       (MP_TAC o Q.SPEC ‘mball extreal_mr1 (l,e)’) \\
6851     simp [OPEN_IN_MBALL, IN_MBALL, mspace_extreal_mr1] \\
6852     rw [MDIST_REFL, Once METRIC_SYM])
6853 >> fs [OPEN_IN_MTOPOLOGY, mspace_extreal_mr1]
6854 >> Q.PAT_X_ASSUM ‘!x. x IN u ==> P’ (MP_TAC o Q.SPEC ‘l’) >> rw []
6855 >> Q.PAT_X_ASSUM ‘!e. 0 < e ==> P’  (MP_TAC o Q.SPEC ‘r’) >> rw []
6856 >> MATCH_MP_TAC EVENTUALLY_MONO
6857 >> Q.EXISTS_TAC ‘\x. dist extreal_mr1 (f x,l) < r’ >> rw []
6858 >> fs [SUBSET_DEF, IN_MBALL, mspace_extreal_mr1]
6859 >> FIRST_X_ASSUM MATCH_MP_TAC
6860 >> rw [Once METRIC_SYM]
6861QED
6862
6863(* see EXTREAL_LIM which corresponds real_topologyTheory.LIM_DEF *)
6864Definition extreal_lim_def :
6865    extreal_lim net f = @l. ext_tendsto f l net
6866End
6867Overload lim = “extreal_lim”
6868
6869Theorem EXTREAL_LIM :
6870    !(f :'a -> extreal) l net.
6871       (f --> l) net <=>
6872        trivial_limit net \/
6873        !e. &0 < e ==> ?y. (?x. netord(net) x y) /\
6874                           !x. netord(net) x y ==> dist extreal_mr1(f(x),l) < e
6875Proof
6876    rw [ext_tendsto_def, eventually] >> PROVE_TAC []
6877QED
6878
6879Theorem EXTREAL_LIM_CONST :
6880    !net (a :extreal). ((\x. a) --> a) net
6881Proof
6882    rw [EXTREAL_LIM, trivial_limit, MDIST_REFL]
6883 >> METIS_TAC []
6884QED
6885
6886(* NOTE: This proof is derived from real_topologyTheory.LIM_ADD *)
6887Theorem EXTREAL_LIM_ADD :
6888    !net:('a)net f g l (m :extreal).
6889       (f --> l) net /\ (g --> m) net ==> ((\x. f(x) + g(x)) --> (l + m)) net
6890Proof
6891  REPEAT GEN_TAC THEN REWRITE_TAC[EXTREAL_LIM] THEN
6892  ASM_CASES_TAC ``trivial_limit (net:('a)net)`` THEN
6893  ASM_SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN
6894  DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
6895  FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN
6896  ASM_REWRITE_TAC[REAL_LT_HALF1] THEN
6897  qabbrev_tac ‘dist' = dist extreal_mr1’ \\
6898  Know `!x y. (dist'(f x, l) < e / 2:real) =
6899              (\x. (dist'(f x, l) < e / 2:real)) x` THENL
6900  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
6901  Know `!x y. (dist'(g x, m) < e / 2:real) =
6902              (\x. (dist'(g x, m) < e / 2:real)) x` THENL
6903  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
6904  DISCH_THEN(MP_TAC o MATCH_MP NET_DILEMMA) THEN BETA_TAC THEN
6905  STRIP_TAC THEN EXISTS_TAC ``c:'a`` THEN CONJ_TAC THENL [METIS_TAC [], ALL_TAC] THEN
6906  GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN REPEAT STRIP_TAC THEN
6907  FULL_SIMP_TAC std_ss [] THEN MATCH_MP_TAC REAL_LET_TRANS THEN
6908  Q.EXISTS_TAC `dist' (f x', l) + dist' (g x', m)` THEN
6909  reverse CONJ_TAC
6910  >- METIS_TAC[REAL_LT_HALF1, REAL_LT_ADD2, GSYM REAL_HALF_DOUBLE] \\
6911  simp [Abbr ‘dist'’, dist_triangle_add]
6912QED
6913
6914(* Name convention: "EXTREAL_" + (theorem name as in real_topologyTheory)
6915
6916   e.g. cf. LIM_SEQUENTIALLY for EXTREAL_LIM_SEQUENTIALLY below:
6917 *)
6918Theorem EXTREAL_LIM_SEQUENTIALLY :
6919    !(f :num -> extreal) l. (f --> l) sequentially <=>
6920          !e. &0 < e ==> ?N. !n. N <= n ==> dist extreal_mr1 (f n,l) < e
6921Proof
6922    rw [ext_tendsto_def, EVENTUALLY_SEQUENTIALLY] >> PROVE_TAC []
6923QED
6924
6925Theorem EXTREAL_LIM_EVENTUALLY :
6926    !net (f :'a -> extreal) l. eventually (\x. f x = l) net ==> (f --> l) net
6927Proof
6928    rw [eventually, EXTREAL_LIM] >> PROVE_TAC [METRIC_SAME]
6929QED
6930
6931Theorem lim_sequentially_imp_extreal_lim :
6932    !f l. (f --> l) sequentially ==> (Normal o f --> Normal l) sequentially
6933Proof
6934    RW_TAC std_ss [LIM_SEQUENTIALLY, EXTREAL_LIM_SEQUENTIALLY,
6935                   extreal_mr1_normal, dist]
6936 >> ‘1 <= e \/ e < 1’ by PROVE_TAC [REAL_LET_TOTAL]
6937 >- (Q.EXISTS_TAC ‘0’ >> rw [] \\
6938     MATCH_MP_TAC REAL_LTE_TRANS >> Q.EXISTS_TAC ‘1’ >> art [] \\
6939     MATCH_MP_TAC REAL_LT_1 >> rw [])
6940 >> Q.PAT_X_ASSUM ‘!e. 0 < e ==> P’ (MP_TAC o Q.SPEC ‘e / (1 - e)’)
6941 >> Know ‘0 < e / (1 - e)’
6942 >- (MATCH_MP_TAC REAL_LT_DIV >> rw [REAL_SUB_LT])
6943 >> RW_TAC std_ss []
6944 >> Q.EXISTS_TAC ‘N’ >> rw []
6945 >> Q.PAT_X_ASSUM ‘!n. N <= n ==> P’ (MP_TAC o Q.SPEC ‘n’)
6946 >> RW_TAC std_ss []
6947 >> Q.ABBREV_TAC ‘x = abs (f n - l)’
6948 >> ‘0 <= x’ by METIS_TAC [ABS_POS]
6949 >> Know ‘x / (1 + x) < e <=> x < e * (1 + x)’
6950 >- (MATCH_MP_TAC REAL_LT_LDIV_EQ \\
6951     MATCH_MP_TAC REAL_LTE_TRANS \\
6952     Q.EXISTS_TAC ‘1’ >> rw [REAL_LE_ADDR])
6953 >> Rewr'
6954 >> rw [REAL_ADD_LDISTRIB, GSYM REAL_LT_SUB_RADD]
6955 >> ‘x - e * x = 1 * x - e * x’ by rw [] >> POP_ORW
6956 >> REWRITE_TAC [GSYM REAL_SUB_RDISTRIB]
6957 >> Suff ‘x < e / (1 - e) <=> x * (1 - e) < e’ >- PROVE_TAC [REAL_MUL_COMM]
6958 >> MATCH_MP_TAC REAL_LT_RDIV_EQ
6959 >> rw [REAL_SUB_LT]
6960QED
6961
6962Theorem extreal_lim_sequentially_imp_real_lim[local] :
6963    !f l. (?N. !n. N <= n ==> f n <> PosInf /\ f n <> NegInf) /\
6964          l <> PosInf /\ l <> NegInf /\ (f --> l) sequentially ==>
6965          (real o f --> real l) sequentially
6966Proof
6967    RW_TAC std_ss [LIM_SEQUENTIALLY, EXTREAL_LIM_SEQUENTIALLY, dist]
6968 >> Q.PAT_X_ASSUM ‘!e. 0 < e ==> P’ (MP_TAC o Q.SPEC ‘e / (1 + e)’)
6969 >> ‘e <> 0’ by PROVE_TAC [REAL_LT_IMP_NE]
6970 >> Know ‘0 < 1 + e’
6971 >- (MATCH_MP_TAC REAL_LT_TRANS \\
6972     Q.EXISTS_TAC ‘1’ >> rw [])
6973 >> DISCH_TAC
6974 >> ‘1 + e <> 0’ by PROVE_TAC [REAL_LT_IMP_NE]
6975 >> ‘0 < e / (1 + e)’ by PROVE_TAC [REAL_LT_DIV]
6976 >> RW_TAC std_ss []
6977 >> Q.ABBREV_TAC ‘M = MAX N N'’
6978 >> Q.EXISTS_TAC ‘M’
6979 >> RW_TAC std_ss []
6980 >> Q.PAT_X_ASSUM ‘!n. N' <= n ==> P’ (MP_TAC o Q.SPEC ‘n’)
6981 >> Know ‘N' <= n’
6982 >- (MATCH_MP_TAC LESS_EQ_TRANS \\
6983     Q.EXISTS_TAC ‘M’ >> rw [Abbr ‘M’])
6984 >> ‘?r. l = Normal r’ by METIS_TAC [extreal_cases] >> POP_ORW
6985 >> Q.PAT_X_ASSUM ‘!n. N <= n ==> P’ (MP_TAC o Q.SPEC ‘n’)
6986 >> Know ‘N <= n’
6987 >- (MATCH_MP_TAC LESS_EQ_TRANS \\
6988     Q.EXISTS_TAC ‘M’ >> rw [Abbr ‘M’])
6989 >> RW_TAC std_ss []
6990 >> ‘?z. f n = Normal z’ by METIS_TAC [extreal_cases]
6991 >> POP_ASSUM (fn th => fs [th, extreal_mr1_normal])
6992 >> Q.ABBREV_TAC ‘y = e / (1 + e)’
6993 >> Know ‘e = y / (1 - y)’
6994 >- (rw [Abbr ‘y’] \\
6995     Know ‘1 - e / (1 + e) = (1 + e) / (1 + e) - e / (1 + e)’
6996     >- (Suff ‘(1 + e) / (1 + e) = 1’ >- rw [] \\
6997         MATCH_MP_TAC REAL_DIV_REFL >> art []) >> Rewr' \\
6998     rw [REAL_DIV_SUB, REAL_ADD_SUB_ALT, GSYM REAL_INV_1OVER, REAL_INV_INV])
6999 >> Rewr'
7000 >> Q.ABBREV_TAC ‘a = abs (z - r)’
7001 >> Know ‘a < y / (1 - y) <=> a * (1 - y) < y’
7002 >- (MATCH_MP_TAC REAL_LT_RDIV_EQ \\
7003     rw [REAL_SUB_LT, Abbr ‘y’])
7004 >> Rewr'
7005 >> rw [REAL_SUB_LDISTRIB, REAL_LT_SUB_RADD]
7006 >> ‘y + a * y = (1 + a) * y’ by REAL_ARITH_TAC >> POP_ORW
7007 >> Suff ‘a / (1 + a) < y <=> a < y * (1 + a)’ >- PROVE_TAC [REAL_MUL_COMM]
7008 >> MATCH_MP_TAC REAL_LT_LDIV_EQ
7009 >> MATCH_MP_TAC REAL_LTE_TRANS
7010 >> Q.EXISTS_TAC ‘1’ >> rw [Abbr ‘a’]
7011QED
7012
7013Theorem extreal_lim_sequentially_eq :
7014    !f l. (?N. !n. N <= n ==> f n <> PosInf /\ f n <> NegInf) /\
7015          l <> PosInf /\ l <> NegInf ==>
7016         ((f --> l) sequentially <=> (real o f --> real l) sequentially)
7017Proof
7018    rpt STRIP_TAC
7019 >> EQ_TAC >> STRIP_TAC
7020 >- (MATCH_MP_TAC extreal_lim_sequentially_imp_real_lim >> rw [] \\
7021     Q.EXISTS_TAC ‘N’ >> rw [])
7022 (* applying lim_sequentially_imp_extreal_lim *)
7023 >> ‘?r. l = Normal r’ by METIS_TAC [extreal_cases]
7024 >> POP_ASSUM (fn th => fs [th, real_normal])
7025 >> Q.ABBREV_TAC ‘g = Normal o real o f’
7026 >> Know ‘(g --> Normal r) sequentially’
7027 >- (Q.UNABBREV_TAC ‘g’ \\
7028     MATCH_MP_TAC lim_sequentially_imp_extreal_lim >> art [])
7029 >> rw [EXTREAL_LIM_SEQUENTIALLY]
7030 >> Q.PAT_X_ASSUM ‘!e. 0 < e ==> P’ (MP_TAC o Q.SPEC ‘e’)
7031 >> RW_TAC std_ss []
7032 >> Q.ABBREV_TAC ‘M = MAX N N'’
7033 >> Q.EXISTS_TAC ‘M’ >> rw []
7034 >> Suff ‘f n = g n’
7035 >- (Rewr' >> FIRST_X_ASSUM MATCH_MP_TAC \\
7036     MATCH_MP_TAC LESS_EQ_TRANS >> Q.EXISTS_TAC ‘M’ >> rw [Abbr ‘M’])
7037 >> rw [Abbr ‘g’, Once EQ_SYM_EQ]
7038 >> MATCH_MP_TAC normal_real
7039 >> Suff ‘N <= n’ >- rw []
7040 >> MATCH_MP_TAC LESS_EQ_TRANS
7041 >> Q.EXISTS_TAC ‘M’ >> rw [Abbr ‘M’]
7042QED
7043
7044Theorem extreal_lim_sequentially_eq' :
7045    !f r. (?N. !n. N <= n ==> f n <> PosInf /\ f n <> NegInf) ==>
7046         ((f --> Normal r) sequentially <=> (real o f --> r) sequentially)
7047Proof
7048    rpt STRIP_TAC
7049 >> MP_TAC (Q.SPECL [‘f’, ‘Normal r’] extreal_lim_sequentially_eq)
7050 >> rw [real_normal]
7051 >> POP_ASSUM MATCH_MP_TAC
7052 >> Q.EXISTS_TAC ‘N’ >> rw []
7053QED
7054
7055(* ------------------------------------------------------------------------- *)
7056(*  Various definitions of bounded and continuous functions                  *)
7057(* ------------------------------------------------------------------------- *)
7058
7059Definition ext_continuous_def :
7060    ext_continuous (f :'a -> extreal) net <=> ext_tendsto f (f (netlimit net)) net
7061End
7062
7063Definition ext_continuous_on_def :
7064    ext_continuous_on f s <=> !x. x IN s ==> ext_continuous f (at x within s)
7065End
7066
7067(* Use ‘ext_bounded (IMAGE f UNIV)’ to say a function f is bounded (on UNIV) *)
7068Definition ext_bounded_def :
7069    ext_bounded s <=> ?a. a <> PosInf /\ !x. x IN s ==> abs x <= a
7070End
7071
7072Theorem ext_bounded_alt :
7073    !s. ext_bounded s <=> ?k. 0 <= k /\ !x. x IN s ==> abs x <= Normal k
7074Proof
7075    rw [ext_bounded_def]
7076 >> reverse EQ_TAC >> rw []
7077 >- (Q.EXISTS_TAC ‘Normal k’ >> rw [])
7078 >> Cases_on ‘s = {}’
7079 >- (rw [] >> Q.EXISTS_TAC ‘0’ >> rw [])
7080 >> Know ‘0 <= a’
7081 >- (fs [GSYM MEMBER_NOT_EMPTY] \\
7082     Q_TAC (TRANS_TAC le_trans) ‘abs x’ >> rw [abs_pos])
7083 >> DISCH_TAC
7084 >> ‘a <> NegInf’ by rw [pos_not_neginf]
7085 >> ‘?k. a = Normal k /\ 0 <= k’
7086       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_le_eq]
7087 >> Q.EXISTS_TAC ‘k’ >> rw []
7088QED
7089
7090Theorem sup_normal' :
7091    !s. ext_bounded s /\ s <> {} ==> Normal (sup (s o Normal)) = sup s
7092Proof
7093    rw [ext_bounded_alt]
7094 >> MATCH_MP_TAC sup_normal
7095 >> Q.EXISTS_TAC ‘k’
7096 >> MATCH_MP_TAC sup_bounded_alt >> art []
7097QED
7098
7099(* NOTE: “sup (s :real set)” doesn't exist (i.e. unspecified) when “s = {}” *)
7100Theorem sup_image_normal :
7101    !s. s <> {} /\ bounded s ==> sup (IMAGE Normal s) = Normal (sup s)
7102Proof
7103    Q.X_GEN_TAC ‘t’ >> rw [bounded_alt]
7104 >> qabbrev_tac ‘s = IMAGE Normal t’
7105 >> MP_TAC (Q.SPEC ‘s’ sup_normal')
7106 >> impl_tac
7107 >- (reverse CONJ_TAC >- rw [Once EXTENSION, NOT_IN_EMPTY, Abbr ‘s’] \\
7108     rw [ext_bounded_def, Abbr ‘s’] \\
7109     Q.EXISTS_TAC ‘Normal a’ >> rw [] \\
7110     simp [extreal_abs_def, extreal_le_eq])
7111 >> DISCH_THEN (REWRITE_TAC o wrap o SYM)
7112 >> AP_TERM_TAC
7113 >> simp [Abbr ‘s’, o_DEF, IN_APP, ETA_AX]
7114QED
7115
7116(* NOTE: This is the general definition actually used in converge_in_dist_def *)
7117Definition bounded_continuous_def :
7118    bounded_continuous top (f :'a -> real) <=>
7119    continuous_map (top,euclidean) f /\ bounded (IMAGE f UNIV)
7120End
7121Overload C_b = “bounded_continuous”
7122
7123Theorem IN_bounded_continuous :
7124    !top f. f IN C_b top <=>
7125            continuous_map (top,euclidean) f /\ bounded (IMAGE f UNIV)
7126Proof
7127    REWRITE_TAC [IN_APP, bounded_continuous_def]
7128QED
7129
7130Theorem continuous_map_normal :
7131    continuous_map (euclidean,ext_euclidean) Normal
7132Proof
7133    rw [euclidean_def, ext_euclidean_def, METRIC_CONTINUOUS_MAP, MSPACE]
7134 >> Cases_on ‘1 <= e’
7135 >- (Q.EXISTS_TAC ‘1’ >> rw [] \\
7136     Q_TAC (TRANS_TAC REAL_LTE_TRANS) ‘1’ >> art [] \\
7137     simp [extreal_mr1_lt_1])
7138 >> fs [REAL_NOT_LE]
7139 >> simp [extreal_mr1_normal', GSYM dist_def, dist]
7140 >> ‘!x. 1 - inv (1 + abs (a - x)) < e <=> 1 - e < inv (1 + abs (a - x))’
7141      by REAL_ARITH_TAC >> POP_ORW
7142 >> ‘1 - e <> 0’ by REAL_ASM_ARITH_TAC
7143 >> ‘1 - e = inv (inv (1 - e))’ by simp [REAL_INVINV]
7144 >> POP_ORW
7145 >> Know ‘!x. inv (inv (1 - e)) < inv (1 + abs (a - x)) <=>
7146              1 + abs (a - x) < inv (1 - e)’
7147 >- (Q.X_GEN_TAC ‘x’ \\
7148     MATCH_MP_TAC REAL_INV_LT_ANTIMONO \\
7149     CONJ_TAC >- (MATCH_MP_TAC REAL_INV_POS >> simp [REAL_SUB_LT]) \\
7150     Q_TAC (TRANS_TAC REAL_LTE_TRANS) ‘1’ >> simp [])
7151 >> Rewr'
7152 >> ‘!x. 1 + abs (a - x) < inv (1 - e) <=> abs (a - x) < inv (1 - e) - 1’
7153      by REAL_ARITH_TAC >> POP_ORW
7154 >> Q.EXISTS_TAC ‘inv (1 - e) - 1’ >> simp [REAL_SUB_LT]
7155 >> REAL_ASM_ARITH_TAC
7156QED
7157
7158Theorem continuous_map_real :
7159    continuous_map (ext_euclidean,euclidean) real
7160Proof
7161    rw [euclidean_def, ext_euclidean_def, METRIC_CONTINUOUS_MAP, MSPACE,
7162        GSYM dist_def, dist]
7163 >> Cases_on ‘a = PosInf’
7164 >- (POP_ASSUM (simp o wrap) \\
7165     Q.EXISTS_TAC ‘1’ >> rw [] \\
7166     Cases_on ‘x = PosInf’ >- simp [] \\
7167     Cases_on ‘x = NegInf’ >- simp [] \\
7168    ‘?r. x = Normal r’ by METIS_TAC [extreal_cases] >> fs [])
7169 >> Cases_on ‘a = NegInf’
7170 >- (POP_ASSUM (simp o wrap) \\
7171     Q.EXISTS_TAC ‘1’ >> rw [] \\
7172     Cases_on ‘x = PosInf’ >- simp [] \\
7173     Cases_on ‘x = NegInf’ >- simp [] \\
7174    ‘?r. x = Normal r’ by METIS_TAC [extreal_cases] >> fs [])
7175 (* stage work *)
7176 >> ‘?r. a = Normal r’ by METIS_TAC [extreal_cases]
7177 >> POP_ASSUM (simp o wrap)
7178 >> Suff ‘?d. 0 < d /\ d < 1 /\
7179              !y. dist extreal_mr1 (Normal r,Normal y) < d ==> abs (r - y) < e’
7180 >- (STRIP_TAC \\
7181     Q.EXISTS_TAC ‘d’ >> rw [] \\
7182    ‘dist extreal_mr1 (Normal r,x) < 1’ by PROVE_TAC [REAL_LT_TRANS] \\
7183    ‘dist extreal_mr1 (Normal r,x) <> 1’ by PROVE_TAC [REAL_LT_IMP_NE] \\
7184     Cases_on ‘x = PosInf’ >- fs [] \\
7185     Cases_on ‘x = NegInf’ >- fs [] \\
7186    ‘?z. x = Normal z’ by METIS_TAC [extreal_cases] \\
7187     POP_ASSUM (fs o wrap))
7188 >> simp [extreal_mr1_normal']
7189 (* NOTE: Below we try to prove a serious of inequations to obtain the
7190    expression of “d” by the existing value “e”.
7191  *)
7192 >> ‘!d y. 1 - inv (1 + abs (r - y)) < d <=> 1 - d < inv (1 + abs (r - y))’
7193      by REAL_ARITH_TAC >> POP_ORW
7194 >> Know ‘!(d :real). d < 1 ==> 1 - d = inv (inv (1 - d))’
7195 >- (rpt STRIP_TAC \\
7196     SYM_TAC >> MATCH_MP_TAC REAL_INVINV \\
7197     REAL_ASM_ARITH_TAC)
7198 >> DISCH_TAC
7199 >> Know ‘!d y. d < 1 ==>
7200               (inv (inv (1 - d)) < inv (1 + abs (r - y)) <=>
7201                1 + abs (r - y) < inv (1 - d))’
7202 >- (rpt STRIP_TAC \\
7203     MATCH_MP_TAC REAL_INV_LT_ANTIMONO \\
7204     CONJ_TAC >- (MATCH_MP_TAC REAL_INV_POS >> simp [REAL_SUB_LT]) \\
7205     Q_TAC (TRANS_TAC REAL_LTE_TRANS) ‘1’ >> simp [])
7206 >> DISCH_TAC
7207 >> ‘!d y. 1 + abs (r - y) < inv (1 - d) <=> abs (r - y) < inv (1 - d) - 1’
7208      by REAL_ARITH_TAC
7209 >> Know ‘!d. inv (1 - d) - 1 = e <=> inv (1 - d) = e + 1’
7210 >- REAL_ARITH_TAC
7211 >> Know ‘e + 1 = inv (inv (e + 1))’
7212 >- (SYM_TAC >> MATCH_MP_TAC REAL_INVINV \\
7213     Q.PAT_X_ASSUM ‘0 < e’ MP_TAC >> REAL_ARITH_TAC)
7214 >> Rewr'
7215 >> simp [REAL_INV_INJ]
7216 >> ‘!d. 1 - d = inv (e + 1) <=> d = 1 - inv (e + 1)’ by REAL_ARITH_TAC
7217 >> POP_ORW
7218 >> DISCH_TAC
7219 (* stage work *)
7220 >> qabbrev_tac ‘d = 1 - inv (e + 1)’
7221 >> Q.EXISTS_TAC ‘d’
7222 >> CONJ_TAC
7223 >- (simp [Abbr ‘d’, REAL_SUB_LT] \\
7224     MATCH_MP_TAC REAL_INV_GT1 >> simp [])
7225 >> CONJ_ASM1_TAC
7226 >- (qunabbrev_tac ‘d’ \\
7227     Suff ‘0 < inv (e + 1)’ >- REAL_ARITH_TAC \\
7228     MATCH_MP_TAC REAL_INV_POS \\
7229     Q_TAC (TRANS_TAC REAL_LT_TRANS) ‘1’ >> simp [])
7230 >> Q.X_GEN_TAC ‘y’
7231 >> Q.PAT_X_ASSUM ‘!d. d < 1 ==> 1 - d = inv (inv (1 - d))’
7232      (MP_TAC o Q.SPEC ‘d’)
7233 >> impl_tac >- art []
7234 >> Rewr'
7235 >> Q.PAT_X_ASSUM ‘!d y. d < 1 ==> (inv (inv (1 - d)) < inv (1 + abs (r - y)) <=> _)’
7236      (MP_TAC o Q.SPECL [‘d’, ‘y’])
7237 >> impl_tac >- art []
7238 >> Rewr'
7239 >> Q.PAT_X_ASSUM ‘!d y. 1 + abs (r - y) < inv (1 - d) <=> _’
7240      (MP_TAC o Q.SPECL [‘d’, ‘y’])
7241 >> Rewr'
7242 >> Q.PAT_X_ASSUM ‘!d. inv (1 - d) - 1 = e <=> _’ (MP_TAC o Q.SPEC ‘d’)
7243 >> simp []
7244QED
7245
7246(* NOTE: “|- Lipschitz_continuous_map (extreal_mr1,mr1) real” doesn't hold *)
7247Theorem Lipschitz_continuous_map_normal :
7248     Lipschitz_continuous_map (mr1,extreal_mr1) Normal
7249Proof
7250    rw [Lipschitz_continuous_map_def, GSYM dist_def, dist]
7251 >> Q.EXISTS_TAC ‘1’ >> rw []
7252 >> rw [extreal_mr1_normal]
7253 >> MATCH_MP_TAC REAL_LE_LDIV
7254 >> qabbrev_tac ‘z = abs (x - y)’
7255 >> simp [REAL_LDISTRIB]
7256 >> Q_TAC (TRANS_TAC REAL_LTE_TRANS) ‘1’ >> rw [Abbr ‘z’]
7257QED
7258
7259(* ------------------------------------------------------------------------- *)
7260(*  Preliminary for Radon-Nikodym Theorem                                    *)
7261(* ------------------------------------------------------------------------- *)
7262
7263Definition seq_sup_def :
7264   (seq_sup P 0       = @r. r IN P /\ sup P < r + 1) /\
7265   (seq_sup P (SUC n) = @r. r IN P /\ sup P < r + Normal ((1 / 2) pow (SUC n)) /\
7266                           (seq_sup P n) < r /\ r < sup P)
7267End
7268
7269Theorem EXTREAL_SUP_SEQ :
7270   !P. (?x. P x) /\ (?z. z <> PosInf /\ !x. P x ==> x <= z) ==>
7271        ?x. (!n. x n IN P) /\ (!n. x n <= x (SUC n)) /\ (sup (IMAGE x UNIV) = sup P)
7272Proof
7273  RW_TAC std_ss []
7274  >> Cases_on `?z. P z /\ (z = sup P)`
7275  >- (Q.EXISTS_TAC `(\i. sup P)`
7276      >> RW_TAC std_ss [le_refl,SPECIFICATION]
7277      >> `IMAGE (\i:num. sup P) UNIV = (\i. i = sup P)`
7278           by RW_TAC std_ss [EXTENSION,IN_IMAGE,IN_UNIV,IN_ABS]
7279      >> RW_TAC std_ss [sup_const])
7280  >> Cases_on `!x. P x ==> (x = NegInf)`
7281  >- (`sup P = NegInf` by METIS_TAC [sup_const_alt]
7282      >> Q.EXISTS_TAC `(\n. NegInf)`
7283      >> FULL_SIMP_TAC std_ss [le_refl]
7284      >> RW_TAC std_ss []
7285      >- METIS_TAC []
7286      >> METIS_TAC [UNIV_NOT_EMPTY,sup_const_over_set])
7287  >> FULL_SIMP_TAC std_ss []
7288  >> Q.EXISTS_TAC `seq_sup P`
7289  >> FULL_SIMP_TAC std_ss []
7290  >> `sup P <> PosInf` by METIS_TAC [sup_le,lt_infty,let_trans]
7291  >> `!x. P x ==> x < sup P` by METIS_TAC [lt_le,le_sup_imp]
7292  >> `!e. 0 < e ==> ?x. P x /\ sup P < x + e`
7293       by (RW_TAC std_ss [] >> MATCH_MP_TAC sup_lt_epsilon >> METIS_TAC [])
7294  >> `!n. 0:real < (1 / 2) pow n` by METIS_TAC [HALF_POS,REAL_POW_LT]
7295  >> `!n. 0 < Normal ((1 / 2) pow n)` by METIS_TAC [extreal_lt_eq,extreal_of_num_def]
7296  >> `!n. seq_sup P n IN P`
7297      by (Induct
7298          >- (RW_TAC std_ss [seq_sup_def]
7299              >> SELECT_ELIM_TAC
7300              >> RW_TAC std_ss []
7301              >> METIS_TAC [lt_01,SPECIFICATION])
7302          >> RW_TAC std_ss [seq_sup_def]
7303          >> SELECT_ELIM_TAC
7304          >> RW_TAC std_ss []
7305          >> `?x. P x /\ seq_sup P n < x` by METIS_TAC [sup_lt,SPECIFICATION]
7306          >> rename1 `seq_sup P n < x2`
7307          >> `?x. P x /\ sup P < x + Normal ((1 / 2) pow (SUC n))` by METIS_TAC []
7308          >> rename1 `sup P < x3 + _`
7309          >> Q.EXISTS_TAC `max x2 x3`
7310          >> RW_TAC std_ss [extreal_max_def,SPECIFICATION]
7311          >- (`x3 < x2` by FULL_SIMP_TAC std_ss [GSYM extreal_lt_def]
7312              >> `x3 +  Normal ((1 / 2) pow (SUC n)) <= x2 +  Normal ((1 / 2) pow (SUC n))`
7313                  by METIS_TAC [lt_radd,lt_le,extreal_not_infty]
7314              >> METIS_TAC [lte_trans])
7315          >> METIS_TAC [lte_trans])
7316  >> `!n. seq_sup P n <= seq_sup P (SUC n)`
7317      by (RW_TAC std_ss [seq_sup_def]
7318          >> SELECT_ELIM_TAC
7319          >> RW_TAC std_ss []
7320          >- (`?x. P x /\ seq_sup P n < x` by METIS_TAC [sup_lt,SPECIFICATION]
7321              >> rename1 `sup_sup P n < x2`
7322              >> `?x. P x /\ sup P < x + Normal ((1 / 2) pow (SUC n))` by METIS_TAC []
7323              >> rename1 `sup P < x3 + _`
7324              >> Q.EXISTS_TAC `max x2 x3`
7325              >> RW_TAC std_ss [extreal_max_def,SPECIFICATION]
7326              >- (`x3 < x2` by FULL_SIMP_TAC std_ss [GSYM extreal_lt_def]
7327                  >> `x3 + Normal ((1 / 2) pow (SUC n)) <= x2 + Normal ((1 / 2) pow (SUC n))`
7328                      by METIS_TAC [lt_radd,lt_le,extreal_not_infty]
7329                  >> METIS_TAC [lte_trans])
7330              >> METIS_TAC [lte_trans])
7331          >> METIS_TAC [lt_le])
7332  >> RW_TAC std_ss []
7333  >> `!n. sup P <= seq_sup P n + Normal ((1 / 2) pow n)`
7334      by (Induct
7335          >- (RW_TAC std_ss [seq_sup_def,pow,GSYM extreal_of_num_def]
7336              >> SELECT_ELIM_TAC
7337              >> RW_TAC std_ss []
7338              >- METIS_TAC [lt_01,SPECIFICATION]
7339              >> METIS_TAC [lt_le])
7340          >> RW_TAC std_ss [seq_sup_def]
7341          >> SELECT_ELIM_TAC
7342          >> RW_TAC std_ss []
7343          >- (`?x. P x /\ seq_sup P n < x` by METIS_TAC [sup_lt,SPECIFICATION]
7344              >> rename1 `sup_sup P n < x2`
7345              >> `?x. P x /\ sup P < x + Normal ((1 / 2) pow (SUC n))` by METIS_TAC []
7346              >> rename1 `sup P < x3 + _`
7347              >> Q.EXISTS_TAC `max x2 x3`
7348              >> RW_TAC std_ss [extreal_max_def,SPECIFICATION]
7349              >- (`x3 < x2` by FULL_SIMP_TAC std_ss [GSYM extreal_lt_def]
7350                  >> `x3 + Normal ((1 / 2) pow (SUC n)) <= x2 + Normal ((1 / 2) pow (SUC n))`
7351                      by METIS_TAC [lt_radd,lt_le,extreal_not_infty]
7352                  >> METIS_TAC [lte_trans])
7353              >> METIS_TAC [lte_trans])
7354          >> METIS_TAC [lt_le])
7355  >> RW_TAC std_ss [sup_eq]
7356  >- (POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
7357      >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
7358      >> METIS_TAC [SPECIFICATION,lt_le])
7359  >> MATCH_MP_TAC le_epsilon
7360  >> RW_TAC std_ss []
7361  >> `e <> NegInf` by METIS_TAC [lt_infty,extreal_of_num_def,lt_trans]
7362  >> `?r. e = Normal r` by METIS_TAC [extreal_cases]
7363  >> FULL_SIMP_TAC std_ss []
7364  >> `?n. Normal ((1 / 2) pow n) < Normal r` by METIS_TAC [EXTREAL_ARCH_POW2_INV]
7365  >> MATCH_MP_TAC le_trans
7366  >> Q.EXISTS_TAC `seq_sup P n + Normal ((1 / 2) pow n)`
7367  >> RW_TAC std_ss []
7368  >> MATCH_MP_TAC le_add2
7369  >> FULL_SIMP_TAC std_ss [lt_le]
7370  >> Q.PAT_X_ASSUM `!z. IMAGE (seq_sup P) UNIV z ==> z <= y` MATCH_MP_TAC
7371  >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
7372  >> RW_TAC std_ss [IN_UNIV,IN_IMAGE]
7373  >> METIS_TAC []
7374QED
7375
7376Theorem EXTREAL_SUP_FUN_SEQ_IMAGE :
7377    !(P:extreal->bool) (P':('a->extreal)->bool) f.
7378       (?x. P x) /\ (?z. z <> PosInf /\ !x. P x ==> x <= z) /\ (P = IMAGE f P')
7379           ==> ?g. (!n:num. g n IN P') /\
7380                   (sup (IMAGE (\n. f (g n)) UNIV) = sup P)
7381Proof
7382  rpt STRIP_TAC
7383  >> `?y. (!n. y n IN P) /\ (!n. y n <= y (SUC n)) /\ (sup (IMAGE y UNIV) = sup P)`
7384     by METIS_TAC [EXTREAL_SUP_SEQ]
7385  >> Q.EXISTS_TAC `(\n. @r. (r IN P') /\ (f r  = y n))`
7386  >> `(\n. f (@(r :'a -> extreal). r IN (P' :('a -> extreal) -> bool) /\
7387                                  ((f :('a -> extreal) -> extreal) r = (y :num -> extreal) n))) = y`
7388  by (rw [FUN_EQ_THM] >> SELECT_ELIM_TAC
7389      >> RW_TAC std_ss []
7390      >> METIS_TAC [IN_IMAGE])
7391  >> ASM_SIMP_TAC std_ss []
7392  >> RW_TAC std_ss []
7393  >> SELECT_ELIM_TAC
7394  >> RW_TAC std_ss []
7395  >> METIS_TAC [IN_IMAGE]
7396QED
7397
7398Theorem EXTREAL_SUP_FUN_SEQ_MONO_IMAGE :
7399    !f (P :extreal->bool) (P' :('a->extreal)->bool).
7400       (?x. P x) /\ (?z. z <> PosInf /\ !x. P x ==> x <= z) /\ (P = IMAGE f P') /\
7401       (!g1 g2. (g1 IN P' /\ g2 IN P' /\ (!x. g1 x <= g2 x))  ==> f g1 <= f g2) /\
7402       (!g1 g2. g1 IN P' /\ g2 IN P' ==> (\x. max (g1 x) (g2 x)) IN P')
7403      ==>
7404       ?g. (!n. g n IN P') /\ (!x n. g n x <= g (SUC n) x) /\
7405           (sup (IMAGE (\n. f (g n)) UNIV) = sup P)
7406Proof
7407    rpt STRIP_TAC
7408  >> `?g. (!n:num. g n IN P') /\ (sup (IMAGE (\n. f (g n)) UNIV) = sup P)`
7409      by METIS_TAC [EXTREAL_SUP_FUN_SEQ_IMAGE]
7410  >> Q.EXISTS_TAC `max_fn_seq g`
7411  >> `!n. max_fn_seq g n IN P'`
7412      by (Induct
7413          >- (`max_fn_seq g 0 = g 0` by RW_TAC std_ss [FUN_EQ_THM,max_fn_seq_def]
7414              >> METIS_TAC [])
7415              >> `max_fn_seq g (SUC n) = (\x. max (max_fn_seq g n x) (g (SUC n) x))`
7416                  by RW_TAC std_ss [FUN_EQ_THM,max_fn_seq_def]
7417              >> RW_TAC std_ss []
7418              >> METIS_TAC [])
7419  >> `!g n x. max_fn_seq g n x <= max_fn_seq g (SUC n) x`
7420      by RW_TAC real_ss [max_fn_seq_def,extreal_max_def,le_refl]
7421  >> CONJ_TAC >- RW_TAC std_ss []
7422  >> CONJ_TAC >- RW_TAC std_ss []
7423  >> `!n. (!x. g n x <= max_fn_seq g n x)`
7424      by (Induct >- RW_TAC std_ss [max_fn_seq_def,le_refl]
7425          >> METIS_TAC [le_max2,max_fn_seq_def])
7426  >> `!n. f (g n) <= f (max_fn_seq g n)` by METIS_TAC []
7427  >> `sup (IMAGE (\n. f (g n)) UNIV) <= sup (IMAGE (\n. f (max_fn_seq g n)) UNIV)`
7428      by (MATCH_MP_TAC sup_le_sup_imp
7429          >> RW_TAC std_ss []
7430          >> POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
7431          >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
7432          >> Q.EXISTS_TAC `f (max_fn_seq g n)`
7433          >> RW_TAC std_ss []
7434          >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
7435          >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
7436          >> METIS_TAC [])
7437  >> `sup (IMAGE (\n. f (max_fn_seq g n)) UNIV) <= sup P`
7438      by (RW_TAC std_ss [sup_le]
7439          >> POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [GSYM SPECIFICATION])
7440          >> RW_TAC std_ss [IN_IMAGE,IN_UNIV]
7441          >> MATCH_MP_TAC le_sup_imp
7442          >> ONCE_REWRITE_TAC [GSYM SPECIFICATION]
7443          >> RW_TAC std_ss [IN_IMAGE]
7444          >> METIS_TAC [])
7445  >> METIS_TAC [le_antisym]
7446QED
7447
7448(************************************************************************)
7449(*   Miscellaneous Results (generally for use in descendent theories)   *)
7450(************************************************************************)
7451
7452(*  I add these results at the end
7453      in order to manipulate the simplifier without breaking anything
7454      - Jared Yeager                                                    *)
7455
7456Theorem normal_minus1:
7457    Normal (-1) = -1
7458Proof
7459    rw [extreal_of_num_def, extreal_ainv_def]
7460QED
7461
7462Theorem extreal_le_simps[simp]:
7463    (!x y. Normal x <= Normal y <=> x <= y) /\
7464    (!x. NegInf <= x <=> T) /\ (!x. x <= PosInf <=> T) /\
7465    (!x. Normal x <= NegInf <=> F) /\
7466    (!x. PosInf <= Normal x <=> F) /\
7467    (PosInf <= NegInf <=> F)
7468Proof
7469    rw[extreal_le_def] >> Cases_on ‘x’ >> simp[extreal_le_def]
7470QED
7471
7472Theorem extreal_lt_simps[simp]:
7473    (!x y. Normal x < Normal y <=> x < y) /\
7474    (!x. x < NegInf <=> F) /\ (!x. PosInf < x <=> F) /\
7475    (!x. Normal x < PosInf <=> T) /\
7476    (!x. NegInf < Normal x <=> T) /\
7477    (NegInf < PosInf <=> T)
7478Proof
7479    simp[extreal_lt_eq] >> rw[extreal_lt_def]
7480QED
7481
7482Theorem extreal_0_simps[simp]:
7483    (0 <= PosInf <=> T) /\ (0 < PosInf <=> T) /\
7484    (PosInf <= 0 <=> F) /\ (PosInf < 0 <=> F) /\
7485    (0 = PosInf <=> F) /\ (PosInf = 0 <=> F) /\
7486    (0 <= NegInf <=> F) /\ (0 < NegInf <=> F) /\
7487    (NegInf <= 0 <=> T) /\ (NegInf < 0 <=> T) /\
7488    (0 = NegInf <=> F) /\ (NegInf = 0 <=> F) /\
7489    (!r. 0 <= Normal r <=> 0 <= r) /\
7490    (!r. 0 < Normal r <=> 0 < r) /\ (!r. 0 = Normal r <=> r = 0) /\
7491    (!r. Normal r <= 0 <=> r <= 0) /\
7492    (!r. Normal r < 0 <=> r < 0) /\ (!r. Normal r = 0 <=> r = 0)
7493Proof
7494    simp[GSYM normal_0]
7495QED
7496
7497Theorem extreal_1_simps[simp]:
7498    (1 <= PosInf <=> T) /\ (1 < PosInf <=> T) /\ (PosInf <= 1 <=> F) /\
7499    (PosInf < 1 <=> F) /\ (1 = PosInf <=> F) /\ (PosInf = 1 <=> F) /\
7500    (1 <= NegInf <=> F) /\ (1 < NegInf <=> F) /\ (NegInf <= 1 <=> T) /\
7501    (NegInf < 1 <=> T) /\ (1 = NegInf <=> F) /\ (NegInf = 1 <=> F) /\
7502    (!r. 1 <= Normal r <=> 1 <= r) /\
7503    (!r. 1 < Normal r <=> 1 < r) /\ (!r. 1 = Normal r <=> r = 1) /\
7504    (!r. Normal r <= 1 <=> r <= 1) /\
7505    (!r. Normal r < 1 <=> r < 1) /\ (!r. Normal r = 1 <=> r = 1)
7506Proof
7507    simp[GSYM normal_1]
7508QED
7509
7510(* do NOT add to a simpset, way too much overhead *)
7511Theorem ineq_imp:
7512    (!x:extreal y. x < y ==> ~(y < x)) /\ (!x:extreal y. x < y ==> x <> y) /\
7513    (!x:extreal y. x < y ==> ~(y <= x)) /\ (!x:extreal y. x < y ==> x <= y) /\
7514    (!x:extreal y. x <= y ==> ~(y < x))
7515Proof
7516    rw[] >> Cases_on ‘x’ >> Cases_on ‘y’ >> fs[SF realSimps.REAL_ARITH_ss]
7517QED
7518
7519Theorem fn_plus_alt:
7520    !f. fn_plus f = (λx. if 0 <= f x then f x else (0: extreal))
7521Proof
7522    rw[fn_plus_def,FUN_EQ_THM] >> qspecl_then [‘f x’,‘0’] assume_tac lt_total >>
7523    FULL_SIMP_TAC bool_ss [] >> simp[ineq_imp]
7524QED
7525
7526Theorem extreal_pow_alt:
7527    (!x:extreal. x pow 0 = 1) /\
7528    (!n x:extreal. x pow (SUC n) = x pow n * x)
7529Proof
7530    simp[pow_0,ADD1,pow_add,pow_1]
7531QED
7532
7533Theorem sqrt_real :
7534  !x. 0 <= x ==> real (sqrt x) = sqrt (real x)
7535Proof
7536  rpt STRIP_TAC
7537  >> ‘x <> NegInf’ by METIS_TAC [extreal_0_simps, lt_trans]
7538  >> Cases_on ‘x = PosInf’
7539  >- (gs [extreal_sqrt_def, real_def, GSYM SQRT_0])
7540  >> ‘?r. x = Normal r’ by METIS_TAC [extreal_cases]
7541  >> gs [real_normal, extreal_sqrt_def, normal_real]
7542  >> METIS_TAC [extreal_cases, real_normal]
7543QED
7544
7545(*** EXTREAL_SUM_IMAGE Theorems ***)
7546
7547Theorem EXTREAL_SUM_IMAGE_ALT_FOLDR:
7548    !f s. FINITE s ==>
7549          EXTREAL_SUM_IMAGE f s =
7550          FOLDR (λe acc. f e + acc) 0x (REVERSE (SET_TO_LIST s))
7551Proof
7552    simp[EXTREAL_SUM_IMAGE_DEF,ITSET_TO_FOLDR]
7553QED
7554
7555Theorem EXTREAL_SUM_IMAGE_EQ':
7556    !f g s. FINITE s /\ (!x. x IN s ==> f x = g x) ==>
7557            EXTREAL_SUM_IMAGE f s = EXTREAL_SUM_IMAGE g s: extreal
7558Proof
7559    rw[] >> simp[EXTREAL_SUM_IMAGE_ALT_FOLDR] >> irule FOLDR_CONG >> rw[]
7560QED
7561
7562Theorem EXTREAL_SUM_IMAGE_MONO':
7563    !f g s. FINITE s /\ (!x. x IN s ==> f x <= g x) ==>
7564            EXTREAL_SUM_IMAGE f s <= EXTREAL_SUM_IMAGE g s: extreal
7565Proof
7566    ‘!f g l. (!e. MEM e l ==> f e <= g e) ==>
7567      (FOLDR (λe acc. f e + acc) 0x l <= FOLDR (λe acc. g e + acc) 0x l)’
7568        suffices_by rw[EXTREAL_SUM_IMAGE_ALT_FOLDR] >>
7569    Induct_on ‘l’ >> rw[FOLDR] >> irule le_add2 >> simp[]
7570QED
7571
7572Theorem EXTREAL_SUM_IMAGE_COUNT_ZERO[simp]:
7573    !f. EXTREAL_SUM_IMAGE f (count 0) = 0:extreal
7574Proof
7575    simp[COUNT_ZERO]
7576QED
7577
7578Theorem EXTREAL_SUM_IMAGE_COUNT_ONE[simp]:
7579    !f. EXTREAL_SUM_IMAGE f (count 1) = f 0:extreal
7580Proof
7581    simp[COUNT_ONE]
7582QED
7583
7584Theorem EXTREAL_SUM_IMAGE_COUNT_SUC:
7585    !f n. (!m. m <= n ==> f m <> NegInf) \/ (!m. m <= n ==> f m <> PosInf) ==>
7586          EXTREAL_SUM_IMAGE f (count (SUC n)) =
7587         (EXTREAL_SUM_IMAGE f (count n)) + f n:extreal
7588Proof
7589    rw[] >> ‘count (SUC n) = (count n) UNION {n}’ by fs[count_def,EXTENSION]
7590 >> rw[] >> pop_assum kall_tac
7591 >> ‘EXTREAL_SUM_IMAGE f (count n UNION {n}) =
7592     EXTREAL_SUM_IMAGE f (count n) + EXTREAL_SUM_IMAGE f {n}’
7593       suffices_by fs[EXTREAL_SUM_IMAGE_SING]
7594 >> irule EXTREAL_SUM_IMAGE_DISJOINT_UNION >> simp[]
7595QED
7596
7597Theorem EXTREAL_SUM_IMAGE_CDIV :
7598  !s. FINITE s ==>
7599      !f c. ((!x. x IN s ==> f x <> NegInf) \/ (!x. x IN s ==> f x <> PosInf)) /\
7600            c <> 0 ==> SIGMA (λx. f x / Normal c) s = SIGMA f s / Normal c
7601Proof
7602   rw [extreal_div_def, extreal_inv_def, Once mul_comm]
7603 >> ‘SIGMA f s * Normal (inv c) = Normal (inv c) *  ∑ f s’ by rw [mul_comm]
7604 >> POP_ORW
7605 >> irule EXTREAL_SUM_IMAGE_CMUL
7606 >> art []
7607QED
7608
7609Theorem EXTREAL_SUM_IMAGE_ABS_TRIANGLE :
7610    !f s. FINITE s ==> abs (SIGMA f s) <= SIGMA (λx. abs (f x)) s
7611Proof
7612    ‘!f l. (!x. MEM x l ==> T) ==>
7613           abs (FOLDR (λe acc. f e + acc) 0x l) <=
7614           FOLDR (λe acc. abs (f e) + acc) 0x l’
7615      suffices_by rw [EXTREAL_SUM_IMAGE_ALT_FOLDR]
7616 >> Induct_on ‘l’ >> rw[listTheory.FOLDR]
7617 >> ‘abs (f h + FOLDR (λe acc. f e + acc) 0x l)
7618     <= abs (f h) + abs (FOLDR (λe acc. f e + acc) 0x l)’
7619      by (irule abs_triangle_full >> simp[])
7620 >> ‘abs (FOLDR (λe acc. f e + acc) 0x l)
7621     <= FOLDR (λe acc. abs (f e) + acc) 0x l’ by simp[]
7622 >> ‘abs (f h) + abs (FOLDR (λe acc. f e + acc) 0x l)
7623     <= abs (f h) + FOLDR (λe acc. abs (f e) + acc) 0x l’ by (irule le_add2 >> simp[])
7624 >> METIS_TAC [le_trans]
7625QED
7626
7627Theorem EXTREAL_SUM_IMAGE_ABS_LE :
7628    !f g s. FINITE s /\ (!x. x IN s ==> abs (f x) <= g x) ==>
7629            abs (SIGMA f s) <= SIGMA g s
7630Proof
7631    rpt STRIP_TAC
7632 >> ‘abs (SIGMA f s) <= SIGMA (λx. abs (f x)) s’
7633      by (irule EXTREAL_SUM_IMAGE_ABS_TRIANGLE >> rw[])
7634 >> ‘(!x. x IN s ==> (λx. abs (f x)) x <= g x)’ by simp[]
7635 >> ‘SIGMA (λx. abs (f x)) s <= SIGMA g s’ by (irule EXTREAL_SUM_IMAGE_MONO' >> rw[])
7636 >> METIS_TAC [le_trans]
7637QED
7638
7639Theorem EXTREAL_SUM_IMAGE_REAL :
7640    !s f. FINITE s ==>
7641          (!x. x IN s ==> f x <> NegInf) /\ (!x. x IN s ==> f x <> PosInf) ==>
7642          SIGMA (λx. real (f x)) s = real (SIGMA f s)
7643Proof
7644    Induct_on ‘CARD s’ >> rw [o_DEF]
7645 >- (‘s = {}’ by METIS_TAC [CARD_EQ_0] \\
7646     gs [EXTREAL_SUM_IMAGE_EMPTY, real_0])
7647 >> MP_TAC (Q.SPEC ‘f’ EXTREAL_SUM_IMAGE_THM)
7648 >> Cases_on ‘s = {}’ >> rw [EXTREAL_SUM_IMAGE_EMPTY, real_0]
7649 >> fs [GSYM MEMBER_NOT_EMPTY]
7650 >> Q.ABBREV_TAC ‘t = s DELETE x’
7651 >> Q.PAT_X_ASSUM ‘!e s'. _’ (STRIP_ASSUME_TAC o Q.SPECL [‘x’, ‘t’])
7652 >> gs [FINITE_DELETE, Abbr ‘t’]
7653 >> ‘SIGMA f s = f x + SIGMA f (s DELETE x)’
7654       by (POP_ASSUM MATCH_MP_TAC >> METIS_TAC [])
7655 >> gs []
7656 >> Q.ABBREV_TAC ‘t = s DELETE x’
7657 >> Q.PAT_X_ASSUM ‘!s. v = CARD s ==> _’ (STRIP_ASSUME_TAC o Q.SPEC ‘t’)
7658 >> ‘v = CARD t’ by rw [Abbr ‘t’, CARD_DELETE] >> gs []
7659 >> Q.PAT_X_ASSUM ‘!f. FINITE t ==> _’ (STRIP_ASSUME_TAC o Q.SPEC ‘f’)
7660 >> ‘FINITE t’ by rw [Abbr ‘t’, FINITE_DELETE] >> gs []
7661 >> ‘s = x INSERT t’ by rw [Abbr ‘t’, INSERT_DELETE]
7662 >> POP_ORW
7663 >> MP_TAC (Q.SPECL [‘f x’, ‘SIGMA f t’] add_real)
7664 >> impl_tac
7665 >- (‘f x <> PosInf /\ f x <> NegInf’ by METIS_TAC [] >> simp [] \\
7666     ‘SIGMA f t = SIGMA f s - f x’ by (fs [] >> METIS_TAC [GSYM add_sub2]) \\
7667     POP_ORW \\
7668     ‘SIGMA f s <> PosInf /\ SIGMA f s <> NegInf’
7669        by METIS_TAC [EXTREAL_SUM_IMAGE_NOT_INFTY] \\
7670     rw [sub_not_infty])
7671 >> Rewr
7672 >> MP_TAC (Q.SPEC ‘λx. real (f x)’ REAL_SUM_IMAGE_THM)
7673 >> rw [Abbr ‘t’, REAL_SUM_IMAGE_EMPTY]
7674 >> POP_ASSUM (STRIP_ASSUME_TAC o Q.SPECL [‘x’, ‘s’])
7675 >> gs [o_DEF, ABSORPTION]
7676QED
7677
7678(*** EXTREAL_PROD_IMAGE Theorems ***)
7679
7680Theorem EXTREAL_PROD_IMAGE_NOT_INFTY:
7681    !f s. FINITE s /\ (!x. x IN s ==> f x <> NegInf /\ f x <> PosInf) ==>
7682        EXTREAL_PROD_IMAGE f s <> NegInf /\ EXTREAL_PROD_IMAGE f s <> PosInf
7683Proof
7684    strip_tac >> simp[Once $ GSYM AND_IMP_INTRO] >> Induct_on ‘s’ >> CONJ_TAC
7685    >- simp[EXTREAL_PROD_IMAGE_EMPTY,SYM normal_1] >>
7686    NTAC 5 strip_tac >> fs[EXTREAL_PROD_IMAGE_PROPERTY,DELETE_NON_ELEMENT_RWT] >>
7687    Cases_on ‘f e’ >> Cases_on ‘EXTREAL_PROD_IMAGE f s’ >> rfs[extreal_mul_def]
7688QED
7689
7690Theorem EXTREAL_PROD_IMAGE_NORMAL:
7691    !f s. FINITE s ==>
7692          EXTREAL_PROD_IMAGE (λx. Normal (f x)) s = Normal (REAL_PROD_IMAGE f s)
7693Proof
7694    strip_tac >> Induct_on ‘s’ >>
7695    rw [EXTREAL_PROD_IMAGE_THM,REAL_PROD_IMAGE_THM,DELETE_NON_ELEMENT_RWT,
7696        extreal_mul_def,normal_1]
7697QED
7698
7699Theorem EXTREAL_PROD_IMAGE_0:
7700    !f s. FINITE s /\ (?x. x IN s /\ f x = 0) ==> EXTREAL_PROD_IMAGE f s = 0
7701Proof
7702    NTAC 2 strip_tac >> simp[GSYM AND_IMP_INTRO] >> Induct_on ‘s’ >>
7703    rw[EXTREAL_PROD_IMAGE_THM,DELETE_NON_ELEMENT_RWT] >- fs[] >>
7704    DISJ2_TAC >> first_x_assum irule >> qexists_tac ‘x’ >> simp[]
7705QED
7706
7707Theorem EXTREAL_PROD_IMAGE_1:
7708    !f s. FINITE s /\ (!x. x IN s ==> f x = 1) ==> EXTREAL_PROD_IMAGE f s = 1
7709Proof
7710    NTAC 2 strip_tac >> simp[GSYM AND_IMP_INTRO] >> Induct_on ‘s’ >>
7711    rw[EXTREAL_PROD_IMAGE_THM,DELETE_NON_ELEMENT_RWT]
7712QED
7713
7714Theorem EXTREAL_PROD_IMAGE_ONE:
7715    !s. FINITE s ==> EXTREAL_PROD_IMAGE (λx. 1) s = 1x
7716Proof
7717    Induct_on ‘s’
7718 >> simp[EXTREAL_PROD_IMAGE_EMPTY,EXTREAL_PROD_IMAGE_PROPERTY,DELETE_NON_ELEMENT_RWT]
7719QED
7720
7721Theorem EXTREAL_PROD_IMAGE_POS:
7722    !f s. FINITE s /\ (!x. x IN s ==> 0 <= f x) ==> 0 <= EXTREAL_PROD_IMAGE f s
7723Proof
7724    strip_tac >> simp[GSYM AND_IMP_INTRO] >> Induct_on ‘s’ >>
7725    rw[EXTREAL_PROD_IMAGE_THM,DELETE_NON_ELEMENT_RWT] >> irule le_mul >> simp[]
7726QED
7727
7728Theorem EXTREAL_PROD_IMAGE_MONO:
7729    !f g s. FINITE s /\ (!x. x IN s ==> 0 <= f x /\ f x <= g x) ==>
7730        EXTREAL_PROD_IMAGE f s <= EXTREAL_PROD_IMAGE g s
7731Proof
7732    NTAC 2 strip_tac >> simp[GSYM AND_IMP_INTRO] >> Induct_on ‘s’ >>
7733    rw[EXTREAL_PROD_IMAGE_THM,DELETE_NON_ELEMENT_RWT] >> irule le_mul2 >>
7734    simp[EXTREAL_PROD_IMAGE_POS]
7735QED
7736
7737Theorem EXTREAL_PROD_IMAGE_COUNT_ZERO[simp]:
7738    !f. EXTREAL_PROD_IMAGE f (count 0) = 1x
7739Proof
7740    simp[COUNT_ZERO]
7741QED
7742
7743Theorem EXTREAL_PROD_IMAGE_COUNT_ONE[simp]:
7744    !f. EXTREAL_PROD_IMAGE f (count 1) = f 0: extreal
7745Proof
7746    simp[COUNT_ONE]
7747QED
7748
7749Theorem EXTREAL_PROD_IMAGE_COUNT_SUC:
7750    !f n. EXTREAL_PROD_IMAGE f (count (SUC n)) =
7751          EXTREAL_PROD_IMAGE f (count n) * f n: extreal
7752Proof
7753    rw[] >> qspecl_then [‘f’,‘n’,‘count n’] assume_tac EXTREAL_PROD_IMAGE_PROPERTY >>
7754    rfs[] >> simp[mul_comm] >> pop_assum $ SUBST1_TAC o SYM >>
7755    ‘count (SUC n) = n INSERT count n’ suffices_by simp[] >> simp[EXTENSION]
7756QED
7757
7758Theorem EXTREAL_PROD_IMAGE_SUPPORT :
7759  !s t f. FINITE s /\ FINITE t /\
7760          s SUBSET t /\ (!x. x IN t DIFF s ==> f x = 1) ==> PI f t = PI f s
7761Proof
7762  rpt STRIP_TAC
7763  >> ‘t = s UNION (t DIFF s)’ by rw [UNION_DIFF] >> POP_ORW
7764  >> Know ‘PI f (s UNION (t DIFF s)) = PI f s * PI f (t DIFF s)’
7765  >- (irule EXTREAL_PROD_IMAGE_DISJOINT_UNION >> simp [DISJOINT_DIFF]) >> Rewr
7766  >> Know ‘PI f (t DIFF s) = 1’
7767  >- (Know ‘PI f (t DIFF s) = PI (λi. 1) (t DIFF s)’
7768      >- (MATCH_MP_TAC EXTREAL_PROD_IMAGE_EQ >> fs []) >> Rewr \\
7769      irule EXTREAL_PROD_IMAGE_1 >> fs []) >> Rewr >> rw [mul_rone]
7770QED
7771
7772Theorem EXTREAL_PROD_IMAGE_SUPPORT' :
7773  !s t f. FINITE t /\ FINITE s /\ s SUBSET t ==>
7774          PI (λx. if x IN s then f x else (1 :extreal)) t = PI f s
7775Proof
7776  rpt STRIP_TAC
7777  >> MP_TAC (Q.SPECL [‘s’, ‘t’, ‘λx. if x IN s then f x else 1’]
7778                     EXTREAL_PROD_IMAGE_SUPPORT)
7779  >> simp [] >> Rewr
7780  >> MATCH_MP_TAC EXTREAL_PROD_IMAGE_EQ >> METIS_TAC []
7781QED
7782
7783(*** Miscellany Within Miscellany ***)
7784
7785Theorem ext_suminf_sing_general:
7786    !m r. 0 <= r ==> suminf (λn. if n = m then r else 0) = r
7787Proof
7788    rw[] >> ‘!n. 0 <= (λn. if n = m then r else 0) n’ by rw[] >> fs[ext_suminf_def] >>
7789    ‘(λn. EXTREAL_SUM_IMAGE (λn. if n = m then r else 0) (count n)) =
7790      (λn. if n < SUC m then 0 else r)’ by (
7791        rw[FUN_EQ_THM] >> Induct_on ‘n’ >> simp[] >>
7792        (qspecl_then [‘(λn. if n = m then r else 0)’,‘n’] assume_tac) EXTREAL_SUM_IMAGE_COUNT_SUC >>
7793        rfs[pos_not_neginf] >> pop_assum kall_tac >>
7794        map_every (fn tm => Cases_on tm >> simp[]) [‘n < m’,‘n = m’]) >>
7795    simp[] >> pop_assum kall_tac >> rw[IMAGE_DEF,sup_eq] >- rw[] >>
7796    pop_assum irule >> qexists_tac ‘SUC m’ >> simp[]
7797QED
7798
7799Theorem ext_suminf_nested:
7800    !f. (!m n. 0 <= f m n) ==>
7801        suminf (λn. suminf (λm. f m n)) = suminf (λm. suminf (λn. f m n))
7802Proof
7803    rw[] >>
7804    map_every (fn tms => qspecl_then tms assume_tac ext_suminf_2d_full)
7805        [[‘λm n. f m n’,‘(λm. suminf (λn. f m n))’,‘num_to_pair’],
7806        [‘λn m. f m n’,‘(λn. suminf (λm. f m n))’,‘SWAP o num_to_pair’]] >>
7807    rfs[BIJ_NUM_TO_PAIR,INST_TYPE [alpha |-> “:num”,beta |-> “:num”] BIJ_SWAP,BIJ_COMPOSE,SF SFY_ss] >>
7808    NTAC 2 $ pop_assum $ SUBST1_TAC o SYM >> irule ext_suminf_eq >>
7809    rw[o_DEF] >> Cases_on `num_to_pair n` >> simp[SWAP_def]
7810QED
7811
7812Theorem exp_mono_le[simp]:
7813    !x:extreal y. exp x <= exp y <=> x <= y
7814Proof
7815    rw[] >> Cases_on ‘x’ >> Cases_on ‘y’ >> simp[extreal_exp_def,EXP_MONO_LE]
7816    >- (simp[EXP_POS_LE])
7817    >- (simp[GSYM real_lt,EXP_POS_LT])
7818QED
7819
7820Theorem pow_even_le:
7821    !n. EVEN n ==> !x. 0 <= x pow n
7822Proof
7823    rw[] >> Cases_on ‘0 <= x’ >- simp[pow_pos_le]
7824 >> fs[GSYM extreal_lt_def] >> simp[le_lt,pow_pos_even]
7825QED
7826
7827Theorem pow_ainv_odd:
7828    !n. ODD n ==> !x. -x pow n = -(x pow n)
7829Proof
7830    rw[] >> qspecl_then [‘n’,‘-1’,‘x’] mp_tac pow_mul >> simp[GSYM neg_minus1] >>
7831    ‘-1 pow n = -1’ suffices_by simp[GSYM neg_minus1] >> completeInduct_on ‘n’ >>
7832    NTAC 2 (Cases_on ‘n’ >> fs[extreal_pow_alt,ODD] >> rename [‘ODD n’])
7833 >> simp[GSYM neg_minus1]
7834QED
7835
7836Theorem pow_ainv_even:
7837    !n. EVEN n ==> !x. -x pow n = x pow n
7838Proof
7839    rw[] >> qspecl_then [‘n’,‘-1’,‘x’] mp_tac pow_mul >> simp[GSYM neg_minus1] >>
7840    ‘-1 pow n = 1’ suffices_by simp[] >> completeInduct_on ‘n’ >>
7841    NTAC 2 (Cases_on ‘n’ >> fs[extreal_pow_alt,EVEN] >> rename [‘EVEN n’])
7842 >> simp[GSYM neg_minus1]
7843QED
7844
7845Theorem pow_abs :
7846  !c n. abs (c pow n) = (abs c) pow n
7847Proof
7848  rpt STRIP_TAC
7849  >> Cases_on ‘c = PosInf’ >- (gs [] \\
7850                               Cases_on ‘n = 0’  >- (gs [abs_refl, extreal_1_simps]) \\
7851                               gs [extreal_pow_def, extreal_abs_def])
7852  >> Cases_on ‘c = NegInf’ >- (gs [] \\
7853                               Cases_on ‘n = 0’ >- (gs [abs_refl, extreal_1_simps]) \\
7854                               Cases_on ‘EVEN n’ >- (gs [extreal_pow_def, extreal_abs_def]) \\
7855                               gs [extreal_pow_def, extreal_abs_def])
7856  >> ‘?r. c = Normal r’ by METIS_TAC [extreal_cases] >> POP_ORW
7857  >> ‘Normal r pow n = Normal (r pow n)’ by rw [extreal_pow_def] >> POP_ORW
7858  >> ‘abs (Normal (r pow n)) = Normal (abs (r pow n))’ by rw [extreal_abs_def] >> POP_ORW
7859  >> ‘abs (Normal r) = Normal (abs r)’ by rw [extreal_abs_def] >> POP_ORW
7860  >> ‘Normal (abs r) pow n = Normal ((abs r) pow n)’ by rw [extreal_pow_def]
7861  >> METIS_TAC [extreal_11, POW_ABS]
7862QED
7863
7864Theorem sub_le_sub_imp:
7865    !w x y z. w <= x /\ z <= y ==> w - y <= x - z
7866Proof
7867    rw[] >> irule le_trans >> qexists_tac ‘x - y’ >> simp[le_lsub_imp,le_rsub_imp]
7868QED
7869
7870Theorem le_negl:
7871    !x y. -x <= y <=> -y <= x
7872Proof
7873    rw[] >> ‘-x <= - -y <=> -y <= x’ suffices_by simp[] >> simp[le_neg,Excl "neg_neg"]
7874QED
7875
7876Theorem le_negr:
7877    !x y. x <= -y <=> y <= -x
7878Proof
7879    rw[] >> ‘- -x <= -y <=> y <= -x’ suffices_by simp[] >> simp[le_neg,Excl "neg_neg"]
7880QED
7881
7882Theorem leeq_trans:
7883    !x:extreal y z. x <= y /\ y = z ==> x <= z
7884Proof
7885    simp[]
7886QED
7887
7888Theorem eqle_trans:
7889    !x:extreal y z. x = y /\ y <= z ==> x <= z
7890Proof
7891    simp[]
7892QED
7893
7894Theorem seq_le_imp_lim_le :
7895    !x y (f :num->real). (!n. f n <= x) /\ (f --> y) sequentially ==> y <= x
7896Proof
7897    RW_TAC bool_ss [LIM_SEQUENTIALLY]
7898 >> MATCH_MP_TAC REAL_LE_EPSILON
7899 >> RW_TAC bool_ss []
7900 >> Q.PAT_X_ASSUM `!e. P e` (MP_TAC o Q.SPEC `e`)
7901 >> RW_TAC bool_ss []
7902 >> POP_ASSUM (MP_TAC o Q.SPEC `N`)
7903 >> Q.PAT_X_ASSUM `!n. P n` (MP_TAC o Q.SPEC `N`)
7904 >> REWRITE_TAC [dist]
7905 >> (RW_TAC bool_ss [GREATER_EQ, LESS_EQ_REFL, abs, REAL_LE_SUB_LADD, REAL_ADD_LID] \\
7906     FULL_SIMP_TAC bool_ss [REAL_NOT_LE, REAL_NEG_SUB, REAL_LT_SUB_RADD])
7907 >| [ (* goal 1 (of 2) *)
7908      MATCH_MP_TAC REAL_LE_TRANS \\
7909      Q.EXISTS_TAC `x` \\
7910      CONJ_TAC >- PROVE_TAC [REAL_LE_TRANS] \\
7911      PROVE_TAC [REAL_LE_ADDR, REAL_LT_LE],
7912      (* goal 2 (of 2) *)
7913      MATCH_MP_TAC REAL_LE_TRANS \\
7914      Q.EXISTS_TAC `f N + e` \\
7915      CONJ_TAC >- PROVE_TAC [REAL_LT_LE, REAL_ADD_SYM] \\
7916      PROVE_TAC [REAL_LE_ADD2, REAL_LE_REFL] ]
7917QED
7918
7919(* cf. seqTheory.SEQ_MONO_LE *)
7920Theorem seq_mono_le :
7921    !(f :num->real) x n. (!n. f n <= f (n + 1)) /\ (f --> x) sequentially ==> f n <= x
7922Proof
7923   RW_TAC bool_ss [LIM_SEQUENTIALLY] THEN MATCH_MP_TAC REAL_LE_EPSILON THEN
7924   RW_TAC bool_ss [] THEN Q.PAT_X_ASSUM `!e. P e` (MP_TAC o Q.SPEC `e`) THEN
7925   RW_TAC bool_ss [GREATER_EQ] THEN MP_TAC (Q.SPECL [`N`, `n`] LESS_EQ_CASES) THEN
7926   STRIP_TAC THENL
7927   [Q.PAT_X_ASSUM `!n. P n` (MP_TAC o Q.SPEC `n`) THEN ASM_REWRITE_TAC [dist] THEN
7928    REAL_ARITH_TAC, ALL_TAC] THEN FULL_SIMP_TAC std_ss [dist] THEN
7929   (SUFF_TAC ``!i : num. f (N - i) <= x + (e : real)`` THEN1
7930    PROVE_TAC [LESS_EQUAL_DIFF]) THEN
7931   INDUCT_TAC
7932   THENL [Q.PAT_X_ASSUM `!n. P n` (MP_TAC o Q.SPEC `N`)
7933          THEN RW_TAC bool_ss [abs, LESS_EQ_REFL, SUB_0]
7934          THEN simpLib.FULL_SIMP_TAC bool_ss
7935               [REAL_LT_SUB_RADD, REAL_NEG_SUB, REAL_NOT_LE, REAL_ADD_LID,
7936                REAL_LE_SUB_LADD]
7937          THEN PROVE_TAC
7938               [REAL_LT_LE, REAL_ADD_SYM, REAL_LE_TRANS, REAL_LE_ADDR],
7939          MP_TAC (ARITH_PROVE
7940                  ``(N - i = N - SUC i) \/ (N - i = (N - SUC i) + 1)``)
7941          THEN PROVE_TAC [REAL_LE_REFL, REAL_LE_TRANS]]
7942QED
7943
7944Theorem sup_seq' : (* was: sup_sequence *)
7945    !f l. mono_increasing f ==>
7946         ((f --> l) sequentially <=>
7947          (sup (IMAGE (\n. Normal (f n)) UNIV) = Normal l))
7948Proof
7949    rpt STRIP_TAC
7950 >> Suff ‘(f --> l) sequentially <=> (f --> l)’
7951 >- (Rewr' \\
7952     MATCH_MP_TAC sup_seq >> art [])
7953 >> REWRITE_TAC [LIM_SEQUENTIALLY_SEQ]
7954QED
7955
7956Theorem inf_seq' :
7957    !f l. mono_decreasing f ==>
7958         ((f --> l) sequentially <=>
7959          (inf (IMAGE (\n. Normal (f n)) UNIV) = Normal l))
7960Proof
7961    rpt STRIP_TAC
7962 >> Suff ‘(f --> l) sequentially <=> (f --> l)’
7963 >- (Rewr' \\
7964     MATCH_MP_TAC inf_seq >> art [])
7965 >> REWRITE_TAC [LIM_SEQUENTIALLY_SEQ]
7966QED
7967
7968Theorem bounded_imp_not_infty :
7969    !x k. abs x <= Normal k ==> x <> NegInf /\ x <> PosInf
7970Proof
7971    rw [abs_bounds, lt_infty] (* 2 subgoals *)
7972 >| [ (* goal 1 (of 2) *)
7973      Q_TAC (TRANS_TAC lte_trans) ‘-Normal k’ >> art [] \\
7974      rw [extreal_ainv_def, lt_infty],
7975      (* goal 2 (of 2) *)
7976      Q_TAC (TRANS_TAC let_trans) ‘Normal k’ >> art [] \\
7977      rw [lt_infty] ]
7978QED
7979
7980Theorem mono_increasing_ext :
7981    !f f'. ext_mono_increasing f /\ (!n. f n = Normal (f' n)) ==>
7982           mono_increasing f'
7983Proof
7984    rpt STRIP_TAC
7985 >> rw [mono_increasing_def]
7986 >> REWRITE_TAC [GSYM extreal_le_eq]
7987 >> Q.PAT_X_ASSUM ‘!n. f n = Normal (f' n)’ (REWRITE_TAC o wrap o GSYM)
7988 >> fs [ext_mono_increasing_def]
7989QED
7990
7991Theorem mono_decreasing_ext :
7992    !f f'. ext_mono_decreasing f /\ (!n. f n = Normal (f' n)) ==>
7993           mono_decreasing f'
7994Proof
7995    rpt STRIP_TAC
7996 >> rw [mono_decreasing_def]
7997 >> REWRITE_TAC [GSYM extreal_le_eq]
7998 >> Q.PAT_X_ASSUM ‘!n. f n = Normal (f' n)’ (REWRITE_TAC o wrap o GSYM)
7999 >> fs [ext_mono_decreasing_def]
8000QED
8001
8002Theorem sup_add_mono_bounded :
8003    !f g. ext_bounded (IMAGE f UNIV) /\ ext_mono_increasing f /\
8004          ext_bounded (IMAGE g UNIV) /\ ext_mono_increasing g ==>
8005          sup (IMAGE (\n. f n + g n) UNIV) =
8006          sup (IMAGE f UNIV) + sup (IMAGE g UNIV)
8007Proof
8008    rw [ext_bounded_alt]
8009 >> ‘!n. abs (f n) <= Normal k /\ abs (g n) <= Normal k'’ by METIS_TAC []
8010 >> Q.PAT_X_ASSUM ‘!x. _ ==> abs x <= Normal k’  K_TAC
8011 >> Q.PAT_X_ASSUM ‘!x. _ ==> abs x <= Normal k'’ K_TAC
8012 >> ‘!n. f n <> NegInf /\ f n <> PosInf /\ g n <> NegInf /\ g n <> PosInf’
8013       by METIS_TAC [bounded_imp_not_infty]
8014 >> qabbrev_tac ‘h = \n. f n + g n’
8015 >> Know ‘!n. abs (h n) <= Normal (k + k')’
8016 >- (rw [Abbr ‘h’] \\
8017     Q_TAC (TRANS_TAC le_trans) ‘abs (f n) + abs (g n)’ \\
8018     simp [abs_triangle, GSYM extreal_add_eq] \\
8019     MATCH_MP_TAC le_add2 >> rw [])
8020 >> DISCH_TAC
8021 >> ‘!n. h n <> NegInf /\ h n <> PosInf’ by METIS_TAC [bounded_imp_not_infty]
8022 >> Know ‘mono_increasing h’
8023 >- (rw [ext_mono_increasing_def, Abbr ‘h’] \\
8024     MATCH_MP_TAC le_add2 >> fs [ext_mono_increasing_def])
8025 >> DISCH_TAC
8026 >> qmatch_abbrev_tac ‘l3 = l1 + l2’
8027 >> ‘abs l1 <= Normal k /\
8028     abs l2 <= Normal k' /\
8029     abs l3 <= Normal (k + k')’ by METIS_TAC [sup_bounded']
8030 >> ‘l1 <> NegInf /\ l1 <> PosInf /\
8031     l2 <> NegInf /\ l2 <> PosInf /\
8032     l3 <> NegInf /\ l3 <> PosInf’ by PROVE_TAC [bounded_imp_not_infty]
8033 >> ‘?r1. l1 = Normal r1’ by METIS_TAC [extreal_cases]
8034 >> ‘?r2. l2 = Normal r2’ by METIS_TAC [extreal_cases]
8035 >> ‘?r3. l3 = Normal r3’ by METIS_TAC [extreal_cases]
8036 >> NTAC 3 (POP_ASSUM MP_TAC)
8037 >> Know ‘!n. ?r. f n = Normal r’
8038 >- (Q.X_GEN_TAC ‘n’ \\
8039     METIS_TAC [extreal_cases])
8040 >> simp [SKOLEM_THM]
8041 >> DISCH_THEN (Q.X_CHOOSE_THEN ‘f'’ STRIP_ASSUME_TAC)
8042 >> Know ‘!n. ?r. g n = Normal r’
8043 >- (Q.X_GEN_TAC ‘n’ \\
8044     METIS_TAC [extreal_cases])
8045 >> simp [SKOLEM_THM]
8046 >> DISCH_THEN (Q.X_CHOOSE_THEN ‘g'’ STRIP_ASSUME_TAC)
8047 >> Know ‘!n. ?r. h n = Normal r’
8048 >- (Q.X_GEN_TAC ‘n’ \\
8049     METIS_TAC [extreal_cases])
8050 >> simp [SKOLEM_THM]
8051 >> DISCH_THEN (Q.X_CHOOSE_THEN ‘h'’ STRIP_ASSUME_TAC)
8052 >> ‘mono_increasing f' /\
8053     mono_increasing g' /\
8054     mono_increasing h'’ by PROVE_TAC [mono_increasing_ext]
8055 >> simp [Abbr ‘l1’, Abbr ‘l2’, Abbr ‘l3’]
8056 >> ‘f = \n. Normal (f' n)’ by rw [FUN_EQ_THM] >> POP_ORW
8057 >> ‘g = \n. Normal (g' n)’ by rw [FUN_EQ_THM] >> POP_ORW
8058 >> ‘h = \n. Normal (h' n)’ by rw [FUN_EQ_THM] >> POP_ORW
8059 >> simp [GSYM sup_seq']
8060 >> Know ‘h' = \n. f' n + g' n’
8061 >- (rw [FUN_EQ_THM] \\
8062     REWRITE_TAC [GSYM extreal_11, GSYM extreal_add_eq] \\
8063     Q.PAT_X_ASSUM ‘!n. f n = Normal (f' n)’ (REWRITE_TAC o wrap o GSYM) \\
8064     Q.PAT_X_ASSUM ‘!n. g n = Normal (g' n)’ (REWRITE_TAC o wrap o GSYM) \\
8065     Q.PAT_X_ASSUM ‘!n. h n = Normal (h' n)’ (REWRITE_TAC o wrap o GSYM) \\
8066     simp [Abbr ‘h’])
8067 >> Rewr'
8068 >> rw [extreal_add_eq, extreal_11]
8069 >> ‘((\n. f' n + g' n) --> (r1 + r2)) sequentially’
8070      by METIS_TAC [real_topologyTheory.LIM_ADD]
8071 >> METIS_TAC [TRIVIAL_LIMIT_SEQUENTIALLY, LIM_UNIQUE]
8072QED
8073
8074Theorem inf_add_mono_bounded :
8075    !f g. ext_bounded (IMAGE f UNIV) /\ ext_mono_decreasing f /\
8076          ext_bounded (IMAGE g UNIV) /\ ext_mono_decreasing g ==>
8077          inf (IMAGE (\n. f n + g n) UNIV) =
8078          inf (IMAGE f UNIV) + inf (IMAGE g UNIV)
8079Proof
8080    rw [ext_bounded_alt]
8081 >> ‘!n. abs (f n) <= Normal k /\ abs (g n) <= Normal k'’ by METIS_TAC []
8082 >> Q.PAT_X_ASSUM ‘!x. _ ==> abs x <= Normal k’  K_TAC
8083 >> Q.PAT_X_ASSUM ‘!x. _ ==> abs x <= Normal k'’ K_TAC
8084 >> ‘!n. f n <> NegInf /\ f n <> PosInf /\ g n <> NegInf /\ g n <> PosInf’
8085       by METIS_TAC [bounded_imp_not_infty]
8086 >> qabbrev_tac ‘h = \n. f n + g n’
8087 >> Know ‘!n. abs (h n) <= Normal (k + k')’
8088 >- (rw [Abbr ‘h’] \\
8089     Q_TAC (TRANS_TAC le_trans) ‘abs (f n) + abs (g n)’ \\
8090     simp [abs_triangle, GSYM extreal_add_eq] \\
8091     MATCH_MP_TAC le_add2 >> rw [])
8092 >> DISCH_TAC
8093 >> ‘!n. h n <> NegInf /\ h n <> PosInf’ by METIS_TAC [bounded_imp_not_infty]
8094 >> Know ‘mono_decreasing h’
8095 >- (rw [ext_mono_decreasing_def, Abbr ‘h’] \\
8096     MATCH_MP_TAC le_add2 >> fs [ext_mono_decreasing_def])
8097 >> DISCH_TAC
8098 >> qmatch_abbrev_tac ‘l3 = l1 + l2’
8099 >> ‘abs l1 <= Normal k /\
8100     abs l2 <= Normal k' /\
8101     abs l3 <= Normal (k + k')’ by METIS_TAC [inf_bounded']
8102 >> ‘l1 <> NegInf /\ l1 <> PosInf /\
8103     l2 <> NegInf /\ l2 <> PosInf /\
8104     l3 <> NegInf /\ l3 <> PosInf’ by PROVE_TAC [bounded_imp_not_infty]
8105 >> ‘?r1. l1 = Normal r1’ by METIS_TAC [extreal_cases]
8106 >> ‘?r2. l2 = Normal r2’ by METIS_TAC [extreal_cases]
8107 >> ‘?r3. l3 = Normal r3’ by METIS_TAC [extreal_cases]
8108 >> NTAC 3 (POP_ASSUM MP_TAC)
8109 >> Know ‘!n. ?r. f n = Normal r’
8110 >- (Q.X_GEN_TAC ‘n’ \\
8111     METIS_TAC [extreal_cases])
8112 >> simp [SKOLEM_THM]
8113 >> DISCH_THEN (Q.X_CHOOSE_THEN ‘f'’ STRIP_ASSUME_TAC)
8114 >> Know ‘!n. ?r. g n = Normal r’
8115 >- (Q.X_GEN_TAC ‘n’ \\
8116     METIS_TAC [extreal_cases])
8117 >> simp [SKOLEM_THM]
8118 >> DISCH_THEN (Q.X_CHOOSE_THEN ‘g'’ STRIP_ASSUME_TAC)
8119 >> Know ‘!n. ?r. h n = Normal r’
8120 >- (Q.X_GEN_TAC ‘n’ \\
8121     METIS_TAC [extreal_cases])
8122 >> simp [SKOLEM_THM]
8123 >> DISCH_THEN (Q.X_CHOOSE_THEN ‘h'’ STRIP_ASSUME_TAC)
8124 >> ‘mono_decreasing f' /\
8125     mono_decreasing g' /\
8126     mono_decreasing h'’ by PROVE_TAC [mono_decreasing_ext]
8127 >> simp [Abbr ‘l1’, Abbr ‘l2’, Abbr ‘l3’]
8128 >> ‘f = \n. Normal (f' n)’ by rw [FUN_EQ_THM] >> POP_ORW
8129 >> ‘g = \n. Normal (g' n)’ by rw [FUN_EQ_THM] >> POP_ORW
8130 >> ‘h = \n. Normal (h' n)’ by rw [FUN_EQ_THM] >> POP_ORW
8131 >> simp [GSYM inf_seq']
8132 >> Know ‘h' = \n. f' n + g' n’
8133 >- (rw [FUN_EQ_THM] \\
8134     REWRITE_TAC [GSYM extreal_11, GSYM extreal_add_eq] \\
8135     Q.PAT_X_ASSUM ‘!n. f n = Normal (f' n)’ (REWRITE_TAC o wrap o GSYM) \\
8136     Q.PAT_X_ASSUM ‘!n. g n = Normal (g' n)’ (REWRITE_TAC o wrap o GSYM) \\
8137     Q.PAT_X_ASSUM ‘!n. h n = Normal (h' n)’ (REWRITE_TAC o wrap o GSYM) \\
8138     simp [Abbr ‘h’])
8139 >> Rewr'
8140 >> rw [extreal_add_eq, extreal_11]
8141 >> ‘((\n. f' n + g' n) --> (r1 + r2)) sequentially’
8142      by METIS_TAC [real_topologyTheory.LIM_ADD]
8143 >> METIS_TAC [TRIVIAL_LIMIT_SEQUENTIALLY, LIM_UNIQUE]
8144QED
8145
8146Theorem ext_liminf_add :
8147    !a b. ext_bounded (IMAGE a UNIV) /\
8148          ext_bounded (IMAGE b UNIV) ==>
8149          liminf a + liminf b <= liminf (\n. a n + b n)
8150Proof
8151    rw [ext_liminf_def]
8152 >> qmatch_abbrev_tac ‘sup (IMAGE f UNIV) + sup (IMAGE g UNIV) <= _’
8153 >> Know ‘sup (IMAGE f UNIV) + sup (IMAGE g UNIV) = sup (IMAGE (\n. f n + g n) UNIV)’
8154 >- (SYM_TAC >> MATCH_MP_TAC sup_add_mono_bounded \\
8155     rpt STRIP_TAC >| (* 4 subgoals *)
8156     [ (* goal 1 (of 4) *)
8157       NTAC 2 (Q.PAT_X_ASSUM ‘ext_bounded _’ MP_TAC) \\
8158       rw [ext_bounded_alt] \\
8159       Q.EXISTS_TAC ‘k + k'’ >> rw [REAL_LE_ADD] \\
8160       rename1 ‘abs (f n) <= Normal (k + k')’ \\
8161       Q_TAC (TRANS_TAC le_trans) ‘Normal k’ \\
8162       reverse CONJ_TAC >- rw [extreal_le_eq] \\
8163       METIS_TAC [inf_bounded],
8164       (* goal 2 (of 4) *)
8165       rw [ext_mono_increasing_def, Abbr ‘f’] \\
8166       MATCH_MP_TAC inf_mono_subset >> rw [SUBSET_DEF] \\
8167       Q.EXISTS_TAC ‘n’ >> rw [],
8168       (* goal 3 (of 4) *)
8169       NTAC 2 (Q.PAT_X_ASSUM ‘ext_bounded _’ MP_TAC) \\
8170       rw [ext_bounded_alt] \\
8171       Q.EXISTS_TAC ‘k + k'’ >> rw [REAL_LE_ADD] \\
8172       rename1 ‘abs (g n) <= Normal (k + k')’ \\
8173       Q_TAC (TRANS_TAC le_trans) ‘Normal k'’ \\
8174       reverse CONJ_TAC >- rw [extreal_le_eq] \\
8175       METIS_TAC [inf_bounded],
8176       (* goal 4 (of 4) *)
8177       rw [ext_mono_increasing_def, Abbr ‘g’] \\
8178       MATCH_MP_TAC inf_mono_subset >> rw [SUBSET_DEF] \\
8179       Q.EXISTS_TAC ‘n’ >> rw [] ])
8180 >> Rewr'
8181 >> MATCH_MP_TAC sup_mono
8182 >> rw [le_inf']
8183 >> rename1 ‘n <= m’
8184 >> MATCH_MP_TAC le_add2
8185 >> rw [Abbr ‘f’, Abbr ‘g’, inf_le'] (* 2 subgoals, same tactics *)
8186 >> POP_ASSUM MATCH_MP_TAC
8187 >> Q.EXISTS_TAC ‘m’ >> art []
8188QED
8189
8190Theorem ext_limsup_add :
8191    !a b. ext_bounded (IMAGE a UNIV) /\
8192          ext_bounded (IMAGE b UNIV) ==>
8193          limsup (\n. a n + b n) <= limsup a + limsup b
8194Proof
8195    rw [ext_limsup_def]
8196 >> qmatch_abbrev_tac ‘_ <= inf (IMAGE f UNIV) + inf (IMAGE g UNIV)’
8197 >> Know ‘inf (IMAGE f UNIV) + inf (IMAGE g UNIV) = inf (IMAGE (\n. f n + g n) UNIV)’
8198 >- (SYM_TAC >> MATCH_MP_TAC inf_add_mono_bounded \\
8199     rpt STRIP_TAC >| (* 4 subgoals *)
8200     [ (* goal 1 (of 4) *)
8201       NTAC 2 (Q.PAT_X_ASSUM ‘ext_bounded _’ MP_TAC) \\
8202       rw [ext_bounded_alt] \\
8203       Q.EXISTS_TAC ‘k + k'’ >> rw [REAL_LE_ADD] \\
8204       rename1 ‘abs (f n) <= Normal (k + k')’ \\
8205       Q_TAC (TRANS_TAC le_trans) ‘Normal k’ \\
8206       reverse CONJ_TAC >- rw [extreal_le_eq] \\
8207       METIS_TAC [sup_bounded],
8208       (* goal 2 (of 4) *)
8209       rw [ext_mono_decreasing_def, Abbr ‘f’] \\
8210       MATCH_MP_TAC sup_mono_subset >> rw [SUBSET_DEF] \\
8211       Q.EXISTS_TAC ‘n’ >> rw [],
8212       (* goal 3 (of 4) *)
8213       NTAC 2 (Q.PAT_X_ASSUM ‘ext_bounded _’ MP_TAC) \\
8214       rw [ext_bounded_alt] \\
8215       Q.EXISTS_TAC ‘k + k'’ >> rw [REAL_LE_ADD] \\
8216       rename1 ‘abs (g n) <= Normal (k + k')’ \\
8217       Q_TAC (TRANS_TAC le_trans) ‘Normal k'’ \\
8218       reverse CONJ_TAC >- rw [extreal_le_eq] \\
8219       METIS_TAC [sup_bounded],
8220       (* goal 4 (of 4) *)
8221       rw [ext_mono_decreasing_def, Abbr ‘g’] \\
8222       MATCH_MP_TAC sup_mono_subset >> rw [SUBSET_DEF] \\
8223       Q.EXISTS_TAC ‘n’ >> rw [] ])
8224 >> Rewr'
8225 >> MATCH_MP_TAC inf_mono
8226 >> rw [sup_le'] >> rename1 ‘n <= m’
8227 >> MATCH_MP_TAC le_add2
8228 >> rw [Abbr ‘f’, Abbr ‘g’, le_sup'] (* 2 subgoals, same tactics *)
8229 >> POP_ASSUM MATCH_MP_TAC
8230 >> Q.EXISTS_TAC ‘m’ >> art []
8231QED
8232
8233Theorem ext_limsup_mono :
8234    !p q. (!n. p n <= q n) ==> limsup p <= limsup q
8235Proof
8236    rw [ext_limsup_def]
8237 >> MATCH_MP_TAC inf_mono >> rw []
8238 >> qabbrev_tac ‘A = {i | n <= i}’
8239 >> ‘{p i | n <= i} = {p i | i IN A}’ by rw [Once EXTENSION, Abbr ‘A’] >> POP_ORW
8240 >> ‘{q i | n <= i} = {q i | i IN A}’ by rw [Once EXTENSION, Abbr ‘A’] >> POP_ORW
8241 >> MATCH_MP_TAC sup_mono_ext
8242 >> rw [Abbr ‘A’]
8243 >> rename1 ‘n <= k’
8244 >> Q.EXISTS_TAC ‘k’ >> rw []
8245QED
8246
8247Theorem ext_liminf_mono :
8248    !p q. (!n. p n <= q n) ==> liminf p <= liminf q
8249Proof
8250    rw [ext_liminf_def]
8251 >> MATCH_MP_TAC sup_mono >> rw []
8252 >> rw [le_inf']
8253 >> rename1 ‘n <= m’
8254 >> Q_TAC (TRANS_TAC le_trans) ‘p m’ >> rw []
8255 >> rw [inf_le']
8256 >> POP_ASSUM MATCH_MP_TAC
8257 >> Q.EXISTS_TAC ‘m’ >> rw []
8258QED
8259
8260(* NOTE: The equation doesn't hold (even “!n. mono_increasing (f n)” is assumed) *)
8261Theorem ext_limsup_sup_lemma :
8262    !f. sup (IMAGE (\m. limsup (\n. f n m)) univ(:num)) <=
8263        limsup (\n. sup (IMAGE (f n) univ(:num)))
8264Proof
8265    rw [sup_le']
8266 >> MATCH_MP_TAC ext_limsup_mono
8267 >> rw [le_sup']
8268 >> POP_ASSUM MATCH_MP_TAC
8269 >> Q.EXISTS_TAC ‘m’ >> rw []
8270QED
8271
8272Theorem ext_limsup_const :
8273    !(c :extreal). limsup (\n. c) = c
8274Proof
8275    rw [ext_limsup_def]
8276 >> Know ‘!(m :num). sup {c | n | m <= n} = c’
8277 >- (Q.X_GEN_TAC ‘m’ \\
8278     MATCH_MP_TAC sup_const_alt' >> simp [GSPECIFICATION] \\
8279     rw [] >> Q.EXISTS_TAC ‘m’ >> simp [])
8280 >> rw []
8281 >> MATCH_MP_TAC inf_const_alt' >> simp []
8282QED
8283
8284Theorem ext_liminf_const :
8285    !(c :extreal). liminf (\n. c) = c
8286Proof
8287    rw [ext_liminf_alt_limsup, o_DEF, ext_limsup_const]
8288QED
8289
8290Theorem ext_limsup_triangle :
8291    !f (J :'index set).
8292       FINITE J /\ (!i. ext_bounded (IMAGE (\n. f n i) UNIV)) ==>
8293       limsup (\n. SIGMA (f n) J) <= SIGMA (\i. limsup (\n. f n i)) J
8294Proof
8295    rpt STRIP_TAC
8296 >> Q.PAT_X_ASSUM ‘FINITE J’ MP_TAC
8297 >> Induct_on ‘J’ >> rw [ext_limsup_const]
8298 >> Know ‘!n. SIGMA (f n) (e INSERT J) = f n e + SIGMA (f n) (J DELETE e)’
8299 >- (Q.X_GEN_TAC ‘n’ \\
8300     irule EXTREAL_SUM_IMAGE_PROPERTY >> art [] \\
8301     DISJ2_TAC (* or DISJ1_TAC *) \\
8302     Q.X_GEN_TAC ‘i’ >> DISCH_TAC \\
8303     Q.PAT_X_ASSUM ‘!i. ext_bounded _’ (MP_TAC o Q.SPEC ‘i’) \\
8304     rw [lt_infty, ext_bounded_def, abs_bounds] \\
8305     Q_TAC (TRANS_TAC let_trans) ‘a’ >> art [] \\
8306     POP_ASSUM (MATCH_MP_TAC o cj 2) \\
8307     Q.EXISTS_TAC ‘n’ >> art [])
8308 >> Rewr'
8309 >> qmatch_abbrev_tac ‘_ <= SIGMA g _’
8310 >> Know ‘SIGMA g (e INSERT J) = g e + SIGMA g (J DELETE e)’
8311 >- (irule EXTREAL_SUM_IMAGE_PROPERTY >> art [] \\
8312     DISJ2_TAC \\
8313     Q.X_GEN_TAC ‘i’ >> DISCH_TAC \\
8314     Q.PAT_X_ASSUM ‘!i. ext_bounded _’ (MP_TAC o Q.SPEC ‘i’) \\
8315     rw [lt_infty, ext_bounded_def, Abbr ‘g’] \\
8316     Q_TAC (TRANS_TAC let_trans) ‘a’ >> art [] \\
8317     Suff ‘abs (limsup (\n. f n i)) <= a’ >- simp [abs_bounds] \\
8318     MATCH_MP_TAC ext_limsup_bounded >> rw [] \\
8319     POP_ASSUM MATCH_MP_TAC \\
8320     Q.EXISTS_TAC ‘n’ >> art [])
8321 >> Rewr'
8322 >> ‘J DELETE e = J’ by PROVE_TAC [DELETE_NON_ELEMENT] >> POP_ORW
8323 >> Cases_on ‘J = {}’ >- simp []
8324 (* applying ext_limsup_add *)
8325 >> Q_TAC (TRANS_TAC le_trans) ‘limsup (\n. f n e) + limsup (\n. SIGMA (f n) J)’
8326 >> CONJ_TAC
8327 >- (HO_MATCH_MP_TAC ext_limsup_add >> art [] \\
8328     fs [ext_bounded_def, SKOLEM_THM] \\
8329     Q.EXISTS_TAC ‘SIGMA f' J’ \\
8330     CONJ_TAC
8331     >- (MATCH_MP_TAC EXTREAL_SUM_IMAGE_NOT_POSINF >> simp []) \\
8332     reverse (rw [abs_bounds])
8333     >- (irule EXTREAL_SUM_IMAGE_MONO >> fs [abs_bounds] \\
8334         CONJ_ASM1_TAC >- METIS_TAC [] \\
8335         DISJ2_TAC >> rpt STRIP_TAC \\
8336         Q.PAT_X_ASSUM ‘!x. x IN J ==> f n x <= f' x’ (MP_TAC o Q.SPEC ‘x’) \\
8337         simp [GSYM extreal_lt_def, GSYM lt_infty]) \\
8338     Know ‘-SIGMA f' J =  SIGMA (\x. -f' x) J’
8339     >- (SYM_TAC >> MATCH_MP_TAC EXTREAL_SUM_IMAGE_MINUS >> art []) >> Rewr' \\
8340     irule EXTREAL_SUM_IMAGE_MONO >> fs [abs_bounds] \\
8341     CONJ_TAC >- METIS_TAC [] \\
8342     DISJ1_TAC >> RW_TAC std_ss []
8343     >- (‘NegInf = -PosInf’ by rw [extreal_ainv_def] >> POP_ORW \\
8344         simp [eq_neg]) \\
8345     CCONTR_TAC >> fs [] \\
8346     Q.PAT_X_ASSUM ‘!i. _’ (MP_TAC o Q.SPEC ‘x’) >> STRIP_TAC \\
8347     POP_ASSUM (MP_TAC o Q.SPEC ‘(f :num -> 'index -> extreal) n x’) \\
8348     impl_tac >- (Q.EXISTS_TAC ‘n’ >> REWRITE_TAC []) \\
8349     simp [le_infty] \\
8350    ‘NegInf = -PosInf’ by rw [extreal_ainv_def] >> POP_ORW \\
8351     simp [eq_neg])
8352 (* stage work *)
8353 >> simp []
8354 >> MATCH_MP_TAC le_ladd_imp >> art []
8355QED
8356
8357Theorem ext_limsup_cmul :
8358    !f c. 0 <= c ==> limsup (\n. Normal c * f n) = Normal c * limsup f
8359Proof
8360    rw [ext_limsup_def]
8361 >> Know ‘!m. {Normal c * f n | m <= n} = IMAGE (\n. Normal c * f n) {i | m <= i}’
8362 >- rw [Once EXTENSION]
8363 >> Rewr'
8364 >> Know ‘!m. {f n | m <= n} = IMAGE f {i | m <= i}’
8365 >- rw [Once EXTENSION]
8366 >> Rewr'
8367 >> Know ‘!m. sup (IMAGE (\n. Normal c * f n) {i | m <= i}) =
8368              Normal c * sup (IMAGE f {i | m <= i})’
8369 >- (Q.X_GEN_TAC ‘m’ \\
8370     MATCH_MP_TAC sup_cmul_general >> rw [Once EXTENSION] \\
8371     Q.EXISTS_TAC ‘m’ >> simp [])
8372 >> Rewr'
8373 >> qabbrev_tac ‘g = \m. sup (IMAGE f {i | m <= i})’
8374 >> simp []
8375 >> MATCH_MP_TAC inf_cmul' >> art []
8376QED
8377
8378Theorem ext_liminf_cmul :
8379    !f c. 0 <= c ==> liminf (\n. Normal c * f n) = Normal c * liminf f
8380Proof
8381    rw [ext_liminf_def]
8382 >> Know ‘!m. {Normal c * f n | m <= n} = IMAGE (\n. Normal c * f n) {i | m <= i}’
8383 >- rw [Once EXTENSION]
8384 >> Rewr'
8385 >> Know ‘!m. {f n | m <= n} = IMAGE f {i | m <= i}’
8386 >- rw [Once EXTENSION]
8387 >> Rewr'
8388 >> Know ‘!m. inf (IMAGE (\n. Normal c * f n) {i | m <= i}) =
8389              Normal c * inf (IMAGE f {i | m <= i})’
8390 >- (Q.X_GEN_TAC ‘m’ \\
8391     MATCH_MP_TAC inf_cmul_general >> rw [Once EXTENSION] \\
8392     Q.EXISTS_TAC ‘m’ >> simp [])
8393 >> Rewr'
8394 >> qabbrev_tac ‘g = \m. inf (IMAGE f {i | m <= i})’
8395 >> simp []
8396 >> MATCH_MP_TAC sup_cmul >> art []
8397QED
8398
8399(* ------------------------------------------------------------------------- *)
8400(*   Advanced results of ext_limsup/liminf (moved from martingaleTheory)     *)
8401(* ------------------------------------------------------------------------- *)
8402
8403Theorem LIM_SEQUENTIALLY_real_normal :
8404    !a l. (!n. a n <> PosInf /\ a n <> NegInf) ==>
8405          ((real o a --> l) sequentially <=>
8406           !e. 0 < e ==> ?N. !n. N <= n ==> abs (a n - Normal l) < Normal e)
8407Proof
8408    rw [LIM_SEQUENTIALLY, dist, o_DEF]
8409 >> EQ_TAC
8410 >- (rpt STRIP_TAC \\
8411     Q.PAT_X_ASSUM ‘!e. 0 < e ==> ?N. P’ (MP_TAC o (Q.SPEC ‘e’)) \\
8412     RW_TAC std_ss [] \\
8413     Know ‘!n. real (a n) - l = real (a n - Normal l)’
8414     >- (Q.X_GEN_TAC ‘n’ \\
8415        ‘?A. a n = Normal A’ by METIS_TAC [extreal_cases] >> POP_ORW \\
8416         rw [real_normal, extreal_sub_eq]) \\
8417     DISCH_THEN (FULL_SIMP_TAC std_ss o wrap) \\
8418     Know ‘!n. abs (real (a n - Normal l)) = real (abs (a n - Normal l))’
8419     >- (Q.X_GEN_TAC ‘n’ \\
8420         MATCH_MP_TAC abs_real \\
8421        ‘?A. a n = Normal A’ by METIS_TAC [extreal_cases] >> POP_ORW \\
8422         rw [extreal_sub_def]) \\
8423     DISCH_THEN (FULL_SIMP_TAC std_ss o wrap) \\
8424     POP_ASSUM MP_TAC \\
8425     ONCE_REWRITE_TAC [GSYM extreal_lt_eq] \\
8426     Know ‘!n. Normal (real (abs (a n - Normal l))) = abs (a n - Normal l)’
8427     >- (Q.X_GEN_TAC ‘n’ \\
8428         MATCH_MP_TAC normal_real \\
8429        ‘?A. a n = Normal A’ by METIS_TAC [extreal_cases] >> POP_ORW \\
8430         rw [extreal_sub_def, extreal_abs_def]) >> Rewr' \\
8431     DISCH_TAC \\
8432     Q.EXISTS_TAC ‘N’ >> rw [])
8433 >> rpt STRIP_TAC
8434 >> Q.PAT_X_ASSUM ‘!e. 0 < e ==> ?N. P’ (MP_TAC o (Q.SPEC ‘e’))
8435 >> RW_TAC std_ss []
8436 >> Q.EXISTS_TAC ‘N’
8437 >> rpt STRIP_TAC
8438 >> Know ‘real (a n) - l = real (a n - Normal l)’
8439 >- (‘?A. a n = Normal A’ by METIS_TAC [extreal_cases] >> POP_ORW \\
8440     rw [real_normal, extreal_sub_eq]) >> Rewr'
8441 >> Know ‘abs (real (a n - Normal l)) = real (abs (a n - Normal l))’
8442 >- (MATCH_MP_TAC abs_real \\
8443    ‘?A. a n = Normal A’ by METIS_TAC [extreal_cases] >> POP_ORW \\
8444     rw [extreal_sub_def]) >> Rewr'
8445 >> ONCE_REWRITE_TAC [GSYM extreal_lt_eq]
8446 >> Know ‘Normal (real (abs (a n - Normal l))) = abs (a n - Normal l)’
8447 >- (MATCH_MP_TAC normal_real \\
8448    ‘?A. a n = Normal A’ by METIS_TAC [extreal_cases] >> POP_ORW \\
8449     rw [extreal_sub_def, extreal_abs_def]) >> Rewr'
8450 >> FIRST_X_ASSUM MATCH_MP_TAC >> art []
8451QED
8452
8453(* The limit of the arithmetic means of the first n partial sums is called
8454  "Cesaro summation". cf. https://en.wikipedia.org/wiki/Cesaro_summation
8455
8456   This proof uses iterateTheory (numseg), added for WLLN_IID and SLLN_IID.
8457 *)
8458Theorem LIM_SEQUENTIALLY_CESARO :
8459    !(f :num->real) l. ((\n. f n) --> l) sequentially ==>
8460          ((\n. SIGMA f (count (SUC n)) / &SUC n) --> l) sequentially
8461Proof
8462    RW_TAC std_ss [LIM_SEQUENTIALLY, dist]
8463 >> Q.ABBREV_TAC ‘g = \n. f n - l’
8464 >> Know ‘!n. SIGMA f (count (SUC n)) / &SUC n - l =
8465              SIGMA g (count (SUC n)) / &SUC n’
8466 >- (rw [Abbr ‘g’] \\
8467     Know ‘SIGMA (\n. f n - l) (count (SUC n)) =
8468           SIGMA f (count (SUC n)) - SIGMA (\x. l) (count (SUC n))’
8469     >- (HO_MATCH_MP_TAC REAL_SUM_IMAGE_SUB >> rw []) >> Rewr' \\
8470    ‘FINITE (count (SUC n))’ by rw [] \\
8471     rw [REAL_SUM_IMAGE_FINITE_CONST3, CARD_COUNT, real_div, REAL_SUB_LDISTRIB])
8472 >> Rewr'
8473 >> Q.PAT_X_ASSUM ‘!e. 0 < e ==> _’ MP_TAC
8474 >> ‘!n. f n - l = g n’ by METIS_TAC [] >> POP_ORW
8475 >> DISCH_THEN (MP_TAC o (Q.SPEC ‘(1 / 2) * e’))
8476 >> ‘0 < 1 / 2 * e’ by rw []
8477 >> RW_TAC std_ss []
8478 >> Q.PAT_X_ASSUM ‘Abbrev (g = (\n. f n - l))’ K_TAC
8479 (* special case: N = 0 *)
8480 >> Cases_on ‘N = 0’
8481 >- (fs [] >> Q.EXISTS_TAC ‘0’ >> rw [real_div] \\
8482    ‘abs (inv (&SUC n) * SIGMA g (count (SUC n))) =
8483     abs (inv (&SUC n)) * abs (SIGMA g (count (SUC n)))’
8484       by rw [REAL_ABS_MUL] >> POP_ORW \\
8485    ‘abs (inv (&SUC n)) = inv (&SUC n) :real’ by rw [] >> POP_ORW \\
8486     MATCH_MP_TAC REAL_LET_TRANS \\
8487     Q.EXISTS_TAC ‘inv (&SUC n) * SIGMA (abs o g) (count (SUC n))’ \\
8488     CONJ_TAC >- (MATCH_MP_TAC REAL_LE_LMUL_IMP >> rw [] \\
8489                  MATCH_MP_TAC REAL_SUM_IMAGE_ABS_TRIANGLE >> rw []) \\
8490     MATCH_MP_TAC REAL_LET_TRANS \\
8491     Q.EXISTS_TAC ‘inv (&SUC n) * SIGMA (\i. 1 / 2 * e) (count (SUC n))’ \\
8492     CONJ_TAC >- (MATCH_MP_TAC REAL_LE_LMUL_IMP >> rw [] \\
8493                  irule REAL_SUM_IMAGE_MONO >> rw [o_DEF] \\
8494                  MATCH_MP_TAC REAL_LT_IMP_LE >> rw []) \\
8495     rw [REAL_SUM_IMAGE_FINITE_CONST3])
8496 (* stage work, now ‘0 < N’ *)
8497 >> ‘0 < N’ by RW_TAC arith_ss []
8498 >> Q.ABBREV_TAC ‘M = abs (SIGMA g (count N))’
8499 >> Q.EXISTS_TAC ‘MAX N (2 * clg (M * inv e))’
8500 >> RW_TAC std_ss [MAX_LE]
8501 (* applying LE_NUM_CEILING *)
8502 >> ‘M * realinv e <= &clg (M * realinv e)’ by PROVE_TAC [LE_NUM_CEILING]
8503 >> Know ‘2 * &clg (M * realinv e) <= (&n :real)’
8504 >- (REWRITE_TAC [GSYM REAL_DOUBLE] \\
8505    ‘!n. &n + (&n :real) = &(n + n)’ by rw [] >> POP_ORW \\
8506     REWRITE_TAC [GSYM TIMES2] >> rw [])
8507 >> DISCH_TAC
8508 >> Q.PAT_X_ASSUM ‘2 * clg (M * realinv e) <= n’ K_TAC
8509 >> Know ‘2 * (M * realinv e) <= &n’
8510 >- (MATCH_MP_TAC REAL_LE_TRANS \\
8511     Q.EXISTS_TAC ‘2 * &clg (M * realinv e)’ >> art [] \\
8512     MATCH_MP_TAC REAL_LE_LMUL_IMP >> rw [])
8513 >> NTAC 2 (POP_ASSUM K_TAC) (* clg is gone *)
8514 >> DISCH_TAC
8515 >> ‘count (SUC n) = (count N) UNION {N .. n}’
8516      by (rw [Once EXTENSION, numseg, IN_COUNT]) >> POP_ORW
8517 >> ‘DISJOINT (count N) {N .. n}’
8518      by (rw [DISJOINT_ALT, IN_COUNT, IN_NUMSEG])
8519 >> Know ‘SIGMA g ((count N) UNION {N .. n}) = SIGMA g (count N) + SIGMA g {N .. n}’
8520 >- (MATCH_MP_TAC REAL_SUM_IMAGE_DISJOINT_UNION \\
8521     rw [FINITE_COUNT, FINITE_NUMSEG]) >> Rewr'
8522 >> REWRITE_TAC [real_div, REAL_ADD_RDISTRIB]
8523 (* applying ABS_TRIANGLE *)
8524 >> MATCH_MP_TAC REAL_LET_TRANS
8525 >> Q.EXISTS_TAC ‘abs (SIGMA g (count N) * inv (&SUC n)) +
8526                  abs (SIGMA g {N .. n}  * inv (&SUC n))’
8527 >> REWRITE_TAC [ABS_TRIANGLE]
8528 >> Suff ‘abs (SIGMA g (count N) * inv (&SUC n)) < 1 / 2 * e /\
8529          abs (SIGMA g {N .. n} * inv (&SUC n)) < 1 / 2 * e’
8530 >- (DISCH_TAC \\
8531     GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) empty_rewrites
8532                     [GSYM X_HALF_HALF] \\
8533     MATCH_MP_TAC REAL_LT_ADD2 >> art [])
8534 (* applying REAL_SUM_IMAGE_ABS_TRIANGLE *)
8535 >> reverse CONJ_TAC
8536 >- (Know ‘abs (SIGMA g {N .. n} * inv (&SUC n)) =
8537           abs (SIGMA g {N .. n}) * abs (inv (&SUC n))’
8538     >- (rw [REAL_ABS_MUL]) >> Rewr' \\
8539    ‘abs (inv (&SUC n)) = inv (&SUC n) :real’ by rw [] >> POP_ORW \\
8540     MATCH_MP_TAC REAL_LET_TRANS \\
8541     Q.EXISTS_TAC ‘SIGMA (abs o g) {N .. n} * inv (&SUC n)’ \\
8542     CONJ_TAC >- (MATCH_MP_TAC REAL_LE_RMUL_IMP >> rw [] \\
8543                  MATCH_MP_TAC REAL_SUM_IMAGE_ABS_TRIANGLE \\
8544                  REWRITE_TAC [FINITE_NUMSEG]) \\
8545     MATCH_MP_TAC REAL_LET_TRANS \\
8546     Q.EXISTS_TAC ‘SIGMA (\i. 1 / 2 * e) {N .. n} * inv (&SUC n)’ \\
8547     CONJ_TAC >- (MATCH_MP_TAC REAL_LE_RMUL_IMP >> rw [] \\
8548                  irule REAL_SUM_IMAGE_MONO >> rw [FINITE_NUMSEG, IN_NUMSEG, o_DEF] \\
8549                  MATCH_MP_TAC REAL_LT_IMP_LE >> fs []) \\
8550    ‘FINITE {N .. n}’ by PROVE_TAC [FINITE_NUMSEG] \\
8551     rw [REAL_SUM_IMAGE_FINITE_CONST3, CARD_NUMSEG, GSYM ADD1])
8552 (* final part *)
8553 >> Know ‘abs (SIGMA g (count N) * inv (&SUC n)) = M * abs (inv (&SUC n))’
8554 >- (rw [Abbr ‘M’, REAL_ABS_MUL]) >> Rewr'
8555 >> ‘abs (inv (&SUC n)) = inv (&SUC n) :real’ by rw [] >> POP_ORW
8556 >> Q.PAT_X_ASSUM ‘2 * (M * realinv e) <= &n’
8557      (MP_TAC o (ONCE_REWRITE_RULE [REAL_MUL_ASSOC]))
8558 >> ‘e <> (0 :real)’ by PROVE_TAC [REAL_LT_IMP_NE] >> rw []
8559 >> MATCH_MP_TAC REAL_LET_TRANS
8560 >> Q.EXISTS_TAC ‘e * &n’ >> rw []
8561QED
8562
8563(* Properties A.1 (iv) [1, p.409] *)
8564Theorem ext_liminf_le_subseq :
8565    !a f l. (!n. a n <> PosInf /\ a n <> NegInf) /\
8566            (!m n. m < n ==> f m < f n) /\
8567            ((real o a o f) --> l) sequentially ==> liminf a <= Normal l
8568Proof
8569    rpt STRIP_TAC
8570 >> POP_ASSUM MP_TAC
8571 >> Know ‘((real o a o f) --> l) sequentially <=>
8572          !e. 0 < e ==> ?N. !n. N <= n ==> abs ((a o f) n - Normal l) < Normal e’
8573 >- (HO_MATCH_MP_TAC LIM_SEQUENTIALLY_real_normal >> rw [])
8574 >> Rewr'
8575 >> rw [o_DEF, abs_bounds_lt, ext_liminf_def, sup_le']
8576 >> MATCH_MP_TAC le_trans
8577 >> Q.EXISTS_TAC ‘inf {a (f n) | m <= n}’
8578 >> CONJ_TAC
8579 >- (MATCH_MP_TAC inf_mono_subset \\
8580     rw [SUBSET_DEF] \\
8581     Q.EXISTS_TAC ‘f n’ >> rw [] \\
8582     MATCH_MP_TAC LESS_EQ_TRANS \\
8583     Q.EXISTS_TAC ‘n’ >> rw [] \\
8584     MATCH_MP_TAC MONOTONE_BIGGER >> rw [])
8585 >> rw [inf_le']
8586 >> MATCH_MP_TAC le_epsilon
8587 >> rpt STRIP_TAC
8588 >> ‘e <> NegInf’ by METIS_TAC [lt_imp_le, pos_not_neginf]
8589 >> ‘?E. 0 < E /\ e = Normal E’
8590       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
8591 >> POP_ORW
8592 >> Q.PAT_X_ASSUM ‘e <> PosInf’ K_TAC
8593 >> Q.PAT_X_ASSUM ‘e <> NegInf’ K_TAC
8594 >> Q.PAT_X_ASSUM ‘0 < e’       K_TAC
8595 >> Q.PAT_X_ASSUM ‘!e. 0 < e ==> P’ (MP_TAC o (Q.SPEC ‘E’))
8596 >> RW_TAC std_ss []
8597 >> POP_ASSUM (MP_TAC o (Q.SPEC ‘N + m’))
8598 >> RW_TAC arith_ss []
8599 >> MATCH_MP_TAC le_trans
8600 >> Q.EXISTS_TAC ‘a (f (N + m))’
8601 >> CONJ_TAC
8602 >- (FIRST_X_ASSUM MATCH_MP_TAC \\
8603     Q.EXISTS_TAC ‘N + m’ >> rw [])
8604 >> MATCH_MP_TAC lt_imp_le
8605 >> ONCE_REWRITE_TAC [add_comm_normal]
8606 >> Suff ‘a (f (N + m)) < Normal E + Normal l <=>
8607          a (f (N + m)) - Normal l < Normal E’ >- rw []
8608 >> ONCE_REWRITE_TAC [EQ_SYM_EQ]
8609 >> MATCH_MP_TAC sub_lt_eq >> rw []
8610QED
8611
8612(* Properties A.1 (iv) [1, p.409] (dual of previous lemma) *)
8613Theorem ext_limsup_le_subseq :
8614    !a f l. (!n. a n <> PosInf /\ a n <> NegInf) /\
8615            (!m n. m < n ==> f m < f n) /\
8616            ((real o a o f) --> l) sequentially ==> Normal l <= limsup a
8617Proof
8618    rw [ext_limsup_alt_liminf]
8619 >> ‘Normal l = -Normal (-l)’ by rw [extreal_ainv_def] >> POP_ORW
8620 >> rw [le_neg]
8621 >> MATCH_MP_TAC ext_liminf_le_subseq
8622 >> Q.EXISTS_TAC ‘f’ >> rw []
8623 >| [ (* goal 1 (of 3) *)
8624     ‘?r. a n = Normal r’ by METIS_TAC [extreal_cases] >> rw [extreal_ainv_def],
8625      (* goal 2 (of 3) *)
8626     ‘?r. a n = Normal r’ by METIS_TAC [extreal_cases] >> rw [extreal_ainv_def],
8627      (* goal 3 (of 3) *)
8628      Suff ‘real o numeric_negate o a o f = (\n. -(real o a o f) n)’
8629      >- (Rewr' >> MATCH_MP_TAC real_topologyTheory.LIM_NEG >> art []) \\
8630      rw [o_DEF, FUN_EQ_THM] \\
8631      ‘?r. a (f n) = Normal r’ by METIS_TAC [extreal_cases] >> POP_ORW \\
8632      ASM_SIMP_TAC std_ss [GSYM extreal_11, GSYM extreal_ainv_def] \\
8633      Know ‘Normal (real (-Normal r)) = -Normal r’
8634      >- (MATCH_MP_TAC normal_real \\
8635          SIMP_TAC std_ss [extreal_ainv_def, extreal_not_infty]) >> Rewr' \\
8636      Know ‘Normal (real (Normal r)) = Normal r’
8637      >- (MATCH_MP_TAC normal_real >> rw []) >> Rewr' \\
8638      rw [extreal_ainv_def] ]
8639QED
8640
8641(* Properties A.1 (iv) [1, p.409] (construction of subsequence with liminf as
8642   the limit)
8643 *)
8644Theorem ext_liminf_imp_subseq :
8645    !a. (!n. a n <> PosInf /\ a n <> NegInf) /\
8646        liminf a <> PosInf /\ liminf a <> NegInf ==>
8647        ?f. (!m n. m < n ==> f m < f n) /\
8648            ((real o a o f) --> real (liminf a)) sequentially
8649Proof
8650    rpt STRIP_TAC
8651 >> Q.ABBREV_TAC ‘L = liminf a’
8652 >> Know ‘!k. inf {a n | k <= n} <= L’
8653 >- (rw [Abbr ‘L’, ext_liminf_def] \\
8654     MATCH_MP_TAC le_sup_imp' >> rw [] \\
8655     Q.EXISTS_TAC ‘k’ >> rw [])
8656 >> DISCH_TAC
8657 >> Know ‘!k. inf {a n | k <= n} <> PosInf’
8658 >- (rw [lt_infty] \\
8659     MATCH_MP_TAC let_trans \\
8660     Q.EXISTS_TAC ‘L’ >> art [] \\
8661    ‘?r. L = Normal r’ by METIS_TAC [extreal_cases] >> POP_ORW \\
8662     rw [lt_infty])
8663 >> DISCH_TAC
8664 (* it's impossible that ‘inf {a n | k <= n}’ (increasing) is always NegInf *)
8665 >> Cases_on ‘!Z. inf {a n | Z <= n} = NegInf’
8666 >- (Suff ‘L = NegInf’ >- PROVE_TAC [] \\
8667     SIMP_TAC std_ss [Abbr ‘L’, ext_liminf_def] >> POP_ORW \\
8668     Know ‘IMAGE (\m. NegInf) univ(:num) = (\y. y = NegInf)’
8669     >- (rw [Once EXTENSION]) >> Rewr' \\
8670     rw [sup_const])
8671 >> FULL_SIMP_TAC bool_ss [] (* this asserts ‘Z’ *)
8672 >> Know ‘!k. Z <= k ==> inf {a n | k <= n} <> NegInf’
8673 >- (rw [lt_infty] \\
8674     MATCH_MP_TAC lte_trans \\
8675     Q.EXISTS_TAC ‘inf {a n | Z <= n}’ \\
8676     reverse CONJ_TAC >- (MATCH_MP_TAC inf_mono_subset >> rw [SUBSET_DEF] \\
8677                          Q.EXISTS_TAC ‘n’ >> rw []) \\
8678     rw [GSYM lt_infty])
8679 >> DISCH_TAC
8680 (* applying sup_lt_epsilon' *)
8681 >> Know ‘!e. 0 < e ==>
8682              ?N. Z <= N /\ !k. N <= k ==> abs (L - inf {a n | k <= n}) < Normal e’
8683 >- (rpt STRIP_TAC \\
8684     Q.ABBREV_TAC ‘P = IMAGE (\m. inf {a n | m <= n}) UNIV’ \\
8685     Know ‘?x. x IN P /\ sup P < x + Normal e’
8686     >- (MATCH_MP_TAC sup_lt_epsilon' \\
8687        ‘sup P = L’ by METIS_TAC [ext_liminf_def] >> POP_ORW \\
8688         rw [extreal_of_num_def, extreal_lt_eq, Abbr ‘P’] \\
8689         Q.EXISTS_TAC ‘inf {a n | Z <= n}’ >> rw [] \\
8690         Q.EXISTS_TAC ‘Z’ >> rw []) \\
8691     rw [Abbr ‘P’, GSYM ext_liminf_def] (* this asserts ‘m’ *) \\
8692     Q.EXISTS_TAC ‘MAX m Z’ >> rw [] \\
8693     Know ‘abs (L - inf {a n | k <= n}) = L - inf {a n | k <= n}’
8694     >- (rw [abs_refl] \\
8695         Suff ‘0 <= L - inf {a n | k <= n} <=> inf {a n | k <= n} <= L’ >- rw [] \\
8696         ONCE_REWRITE_TAC [EQ_SYM_EQ] \\
8697         MATCH_MP_TAC sub_zero_le >> rw []) >> Rewr' \\
8698     MATCH_MP_TAC let_trans \\
8699     Q.EXISTS_TAC ‘L - inf {a n | m <= n}’ \\
8700     CONJ_TAC >- (MATCH_MP_TAC le_lsub_imp \\
8701                  MATCH_MP_TAC inf_mono_subset >> rw [SUBSET_DEF] \\
8702                  Q.EXISTS_TAC ‘n’ >> rw []) \\
8703     MATCH_MP_TAC sub_lt_imp2 >> rw [add_comm_normal])
8704 >> DISCH_TAC
8705 (* applying lt_inf_epsilon' *)
8706 >> Know ‘!e. 0 < e ==>
8707              !k. Z <= k ==> ?l. k <= l /\ abs (a l - inf {a n | k <= n}) < Normal e’
8708 >- (rpt STRIP_TAC \\
8709     Q.ABBREV_TAC ‘P = {a n | k <= n}’ \\
8710     Know ‘?x. x IN P /\ x < inf P + Normal e’
8711     >- (MATCH_MP_TAC lt_inf_epsilon' \\
8712         rw [Abbr ‘P’, extreal_of_num_def, extreal_lt_eq] \\
8713         Q.EXISTS_TAC ‘a k’ >> rw [] \\
8714         Q.EXISTS_TAC ‘k’ >> rw []) >> rw [Abbr ‘P’] \\
8715     Q.EXISTS_TAC ‘n’ >> rw [] \\
8716     Know ‘abs (a n - inf {a n | k <= n}) = a n - inf {a n | k <= n}’
8717     >- (rw [abs_refl] \\
8718         Know ‘0 <= a n - inf {a n | k <= n} <=> inf {a n | k <= n} <= a n’
8719         >- (ONCE_REWRITE_TAC [EQ_SYM_EQ] \\
8720             MATCH_MP_TAC sub_zero_le >> rw []) >> Rewr' \\
8721         rw [inf_le'] >> FIRST_X_ASSUM MATCH_MP_TAC \\
8722         Q.EXISTS_TAC ‘n’ >> rw []) >> Rewr' \\
8723     MATCH_MP_TAC sub_lt_imp2 >> rw [add_comm_normal])
8724 >> DISCH_TAC
8725 (* combine the previous two results, applying abs_triangle_neg
8726
8727    NOTE: now we go beyond the textbook proofs, to assert a "successor" function f
8728    which turns a previous (a l) (l starts from 0) to the next (a l'), such that
8729   ‘abs (a l' - L) < Normal (inv &SUC l)’.
8730
8731    The resulting subsequence is ‘g = \n. FUNPOW f n 0’.
8732 *)
8733 >> Know ‘!l. ?l'. l < l' /\ abs (a l' - L) < Normal (inv (&SUC l))’
8734 >- (rpt STRIP_TAC \\
8735     Q.ABBREV_TAC ‘(e :real) = inv (&SUC l)’ \\
8736     Know ‘0 < e’
8737     >- (Q.UNABBREV_TAC ‘e’ \\
8738         MATCH_MP_TAC REAL_INV_POS >> rw []) >> DISCH_TAC \\
8739    ‘0 < e / 2’ by rw [REAL_LT_DIV] \\
8740     Q.PAT_X_ASSUM ‘!e. 0 < e ==> ?N. P’ (MP_TAC o (Q.SPEC ‘e / 2’)) \\
8741     RW_TAC std_ss [] (* this asserts ‘N’ *) \\
8742     Q.PAT_X_ASSUM ‘!e. 0 < e ==> !k. P’ (MP_TAC o (Q.SPEC ‘e / 2’)) \\
8743     RW_TAC std_ss [] \\
8744     Q.PAT_X_ASSUM ‘!k. Z <= k ==> ?l. P’ (MP_TAC o (Q.SPEC ‘MAX N (SUC l)’)) \\
8745     RW_TAC std_ss [MAX_LE] (* this asserts ‘l'’ *) \\
8746     Q.EXISTS_TAC ‘l'’ >> rw [] (* l < l' *) \\
8747
8748     MATCH_MP_TAC let_trans \\
8749     Q.EXISTS_TAC ‘abs (a l' - inf {a n | MAX N (SUC l) <= n}) +
8750                   abs (L    - inf {a n | MAX N (SUC l) <= n})’ \\
8751     reverse CONJ_TAC
8752     >- (‘e = e / 2 + e / 2’ by PROVE_TAC [REAL_HALF_DOUBLE] >> POP_ORW \\
8753         REWRITE_TAC [GSYM extreal_add_def] \\
8754         MATCH_MP_TAC lt_add2 >> rw []) \\
8755    ‘?r1. a l' = Normal r1’ by METIS_TAC [extreal_cases] >> POP_ORW \\
8756    ‘?r2. L = Normal r2’ by METIS_TAC [extreal_cases] >> POP_ORW \\
8757     Know ‘inf {a n | MAX N (SUC l) <= n} <> NegInf’
8758     >- (FIRST_X_ASSUM MATCH_MP_TAC >> rw []) >> DISCH_TAC \\
8759    ‘?r3. inf {a n | MAX N (SUC l) <= n} = Normal r3’
8760       by METIS_TAC [extreal_cases] >> POP_ORW \\
8761     rw [extreal_sub_def, extreal_abs_def, extreal_add_def, extreal_le_eq] \\
8762     Suff ‘r1 - r2 = (r1 - r3) - (r2 - r3)’ >- rw [ABS_TRIANGLE_NEG] \\
8763     REAL_ARITH_TAC)
8764 >> DISCH_THEN (STRIP_ASSUME_TAC o
8765                (SIMP_RULE std_ss [SKOLEM_THM])) (* this asserts ‘f’ *)
8766 >> Q.ABBREV_TAC ‘g = \n. FUNPOW f n 0’
8767 >> Q.EXISTS_TAC ‘g’
8768 (* applying STRICTLY_INCREASING_TC (arithmeticTheory) *)
8769 >> STRONG_CONJ_TAC (* !m n. m < n ==> g m < g n *)
8770 >- (MATCH_MP_TAC STRICTLY_INCREASING_TC \\
8771     rw [Abbr ‘g’, FUNPOW_SUC])
8772 >> DISCH_TAC
8773 (* applying MONOTONE_BIGGER (real_topologyTheory) *)
8774 >> Know ‘!n. n <= g n’
8775 >- (MATCH_MP_TAC MONOTONE_BIGGER >> art [])
8776 >> DISCH_TAC
8777 (* stage work, now touching the goal *)
8778 >> Know ‘(real o a o g --> real L) sequentially <=>
8779          !e. 0 < e ==>
8780              ?N. !n. N <= n ==> abs ((a o g) n - Normal (real L)) < Normal e’
8781 >- (MATCH_MP_TAC LIM_SEQUENTIALLY_real_normal >> rw []) >> Rewr'
8782 >> rw [normal_real, o_DEF] (* this asserts ‘e’ *)
8783 (* find ‘N’ such that ‘&SUC N < 1 / e’ *)
8784 >> ‘?n. n <> 0 /\ (0 :real) < inv (&n) /\ inv (&n) < (e :real)’
8785       by METIS_TAC [REAL_ARCH_INV]
8786 (* stage work, the purpose of ‘N’ is to eliminate ‘Normal e’ *)
8787 >> Q.EXISTS_TAC ‘n’
8788 >> Q.X_GEN_TAC ‘m’ >> DISCH_TAC (* this asserts ‘m’ (‘n <= m’) *)
8789 >> ‘m <> 0’ by rw [] >> Cases_on ‘m’ >- fs []
8790 >> rename1 ‘SUC N <> 0’
8791 >> FULL_SIMP_TAC std_ss [Abbr ‘g’, FUNPOW_SUC]
8792 >> MATCH_MP_TAC lt_trans
8793 >> Q.ABBREV_TAC ‘l = FUNPOW f N 0’
8794 >> Q.EXISTS_TAC ‘Normal (inv (&SUC l))’
8795 >> Q.PAT_X_ASSUM ‘!l. l < f l /\ P’ (MP_TAC o (Q.SPEC ‘l’))
8796 >> RW_TAC std_ss [Abbr ‘l’, extreal_lt_eq]
8797 >> MATCH_MP_TAC REAL_LET_TRANS
8798 >> Q.EXISTS_TAC ‘inv (&SUC N)’
8799 >> CONJ_TAC
8800 >- (Know ‘inv (&SUC (FUNPOW f N 0)) <= (inv (&SUC N) :real) <=>
8801           &SUC N <= (&SUC (FUNPOW f N 0)) :real’
8802     >- (MATCH_MP_TAC REAL_INV_LE_ANTIMONO >> rw []) >> Rewr' \\
8803     rw [])
8804 >> MATCH_MP_TAC REAL_LET_TRANS
8805 >> Q.EXISTS_TAC ‘inv (&n)’ >> art []
8806 >> Know ‘inv (&SUC N) <= (inv (&n) :real) <=> &n <= (&SUC N :real)’
8807 >- (MATCH_MP_TAC REAL_INV_LE_ANTIMONO >> rw [])
8808 >> Rewr'
8809 >> RW_TAC real_ss []
8810QED
8811
8812(* Properties A.1 (iv) [1, p.409] *)
8813Theorem ext_limsup_imp_subseq :
8814    !a. (!n. a n <> PosInf /\ a n <> NegInf) /\
8815        limsup a <> PosInf /\ limsup a <> NegInf ==>
8816        ?f. (!m n. m < n ==> f m < f n) /\
8817            ((real o a o f) --> real (limsup a)) sequentially
8818Proof
8819    rw [ext_limsup_alt_liminf]
8820 >> Know ‘liminf (numeric_negate o a) <> PosInf’
8821 >- (CCONTR_TAC >> fs [extreal_ainv_def])
8822 >> DISCH_TAC
8823 >> Know ‘liminf (numeric_negate o a) <> NegInf’
8824 >- (CCONTR_TAC >> fs [extreal_ainv_def])
8825 >> DISCH_TAC
8826 >> Know ‘real (-liminf (numeric_negate o a)) = -real (liminf (numeric_negate o a))’
8827 >- (REWRITE_TAC [GSYM extreal_11, GSYM extreal_ainv_def] \\
8828     rw [normal_real])
8829 >> Rewr'
8830 >> Know ‘?f. (!m n. m < n ==> f m < f n) /\
8831              (real o (numeric_negate o a) o f -->
8832               real (liminf (numeric_negate o a))) sequentially’
8833 >- (MATCH_MP_TAC ext_liminf_imp_subseq >> rw [o_DEF] \\
8834    ‘?r. a n = Normal r’ by METIS_TAC [extreal_cases] >> rw [extreal_ainv_def])
8835 >> STRIP_TAC
8836 >> Q.EXISTS_TAC ‘f’ >> art []
8837 >> Q.ABBREV_TAC ‘l = real (liminf (numeric_negate o a))’
8838 >> Q.ABBREV_TAC ‘g = real o (numeric_negate o a) o f’
8839 >> Suff ‘real o a o f = \n. -g n’
8840 >- (Rewr' >> MATCH_MP_TAC real_topologyTheory.LIM_NEG >> art [])
8841 >> rw [o_DEF, Abbr ‘g’, FUN_EQ_THM]
8842 >> REWRITE_TAC [GSYM extreal_11, GSYM extreal_ainv_def]
8843 >> Know ‘-a (f n) <> PosInf /\ -a (f n) <> NegInf’
8844 >- (‘?r. a (f n) = Normal r’ by METIS_TAC [extreal_cases] \\
8845     rw [extreal_ainv_def])
8846 >> STRIP_TAC
8847 >> rw [normal_real]
8848QED
8849
8850(* Properties A.1 (v) [1, p.409] (full version) *)
8851Theorem ext_limsup_thm :
8852    !a l. (!n. a n <> PosInf /\ a n <> NegInf) ==>
8853          ((real o a --> l) sequentially <=>
8854           limsup a = Normal l /\ liminf a = Normal l)
8855Proof
8856    rpt STRIP_TAC
8857 >> EQ_TAC (* easy part first *)
8858 >- (DISCH_TAC \\
8859     MP_TAC (Q.SPECL [‘a’, ‘I’, ‘l’] ext_limsup_le_subseq) \\
8860     MP_TAC (Q.SPECL [‘a’, ‘I’, ‘l’] ext_liminf_le_subseq) \\
8861     RW_TAC arith_ss [] >| (* 2 subgoals *)
8862     [ (* goal 1 (of 2) *)
8863       Know ‘limsup a <> NegInf’
8864       >- (fs [lt_infty] >> MATCH_MP_TAC lte_trans \\
8865           Q.EXISTS_TAC ‘Normal l’ >> rw [lt_infty]) >> DISCH_TAC \\
8866       (* ‘(real o a --> l) sequentially’ cannot hold if limsup a = PosInf *)
8867       Know ‘limsup a <> PosInf’
8868       >- (rw [ext_limsup_def] \\
8869           CCONTR_TAC >> fs [] \\
8870          ‘!e. 0 < e ==> ?N. !n. N <= n ==> abs (a n - Normal l) < Normal e’
8871             by METIS_TAC [LIM_SEQUENTIALLY_real_normal] \\
8872           Q.ABBREV_TAC ‘P = IMAGE (\m. sup {a n | m <= n}) UNIV’ \\
8873           Suff ‘?x. x IN P /\ x < PosInf’
8874           >- (DISCH_TAC >> fs [Abbr ‘P’] \\
8875               Know ‘inf (IMAGE (\m. sup {a n | m <= n}) UNIV) < PosInf’
8876               >- (rw [GSYM inf_lt'] \\
8877                   Q.EXISTS_TAC ‘sup {a n | m <= n}’ >> rw [] \\
8878                   Q.EXISTS_TAC ‘m’ >> rw []) \\
8879               rw [lt_infty]) \\
8880           rw [Abbr ‘P’] \\
8881           POP_ASSUM (MP_TAC o (Q.SPEC ‘1’)) >> rw [abs_bounds_lt] \\
8882           Q.EXISTS_TAC ‘sup {a n | N <= n}’ \\
8883           CONJ_TAC >- (Q.EXISTS_TAC ‘N’ >> rw []) \\
8884           MATCH_MP_TAC let_trans \\
8885           Q.EXISTS_TAC ‘Normal (1 + l)’ >> rw [lt_infty, sup_le'] \\
8886           rw [GSYM extreal_add_def] \\
8887           MATCH_MP_TAC lt_imp_le \\
8888           Know ‘a n < Normal 1 + Normal l <=> a n - Normal l < Normal 1’
8889           >- (ONCE_REWRITE_TAC [EQ_SYM_EQ] \\
8890               MATCH_MP_TAC sub_lt_eq >> rw []) >> Rewr' \\
8891           METIS_TAC []) >> DISCH_TAC \\
8892       Know ‘?f. (!m n. m < n ==> f m < f n) /\
8893                 (real o a o f --> real (limsup a)) sequentially’
8894       >- (MATCH_MP_TAC ext_limsup_imp_subseq >> art []) >> STRIP_TAC \\
8895       Know ‘(real o a o f --> l) sequentially’
8896       >- (REWRITE_TAC [o_ASSOC] \\
8897           MATCH_MP_TAC LIM_SUBSEQUENCE >> art []) >> DISCH_TAC \\
8898       Know ‘real (limsup a) = l’
8899       >- (METIS_TAC [LIM_UNIQUE, TRIVIAL_LIMIT_SEQUENTIALLY]) \\
8900       REWRITE_TAC [GSYM extreal_11] \\
8901       ASM_SIMP_TAC std_ss [normal_real],
8902       (* goal 2 (of 2) *)
8903       Know ‘liminf a <> PosInf’
8904       >- (fs [lt_infty] >> MATCH_MP_TAC let_trans \\
8905           Q.EXISTS_TAC ‘Normal l’ >> rw [lt_infty]) >> DISCH_TAC \\
8906       (* if liminf a = NegInf, ‘(real o a --> l) sequentially’ cannot hold *)
8907       Know ‘liminf a <> NegInf’
8908       >- (rw [ext_liminf_def] \\
8909           CCONTR_TAC >> fs [] \\
8910          ‘!e. 0 < e ==> ?N. !n. N <= n ==> abs (a n - Normal l) < Normal e’
8911             by METIS_TAC [LIM_SEQUENTIALLY_real_normal] \\
8912           Q.ABBREV_TAC ‘P = IMAGE (\m. inf {a n | m <= n}) UNIV’ \\
8913           Suff ‘?x. x IN P /\ NegInf < x’
8914           >- (DISCH_TAC >> fs [Abbr ‘P’] \\
8915               Know ‘NegInf < sup (IMAGE (\m. inf {a n | m <= n}) UNIV)’
8916               >- (rw [lt_sup] \\
8917                   Q.EXISTS_TAC ‘inf {a n | m <= n}’ >> rw [] \\
8918                   Q.EXISTS_TAC ‘m’ >> rw []) \\
8919               rw [lt_infty]) \\
8920           rw [Abbr ‘P’] \\
8921           POP_ASSUM (MP_TAC o (Q.SPEC ‘1’)) >> rw [abs_bounds_lt] \\
8922           Q.EXISTS_TAC ‘inf {a n | N <= n}’ \\
8923           CONJ_TAC >- (Q.EXISTS_TAC ‘N’ >> rw []) \\
8924           MATCH_MP_TAC lte_trans \\
8925           Q.EXISTS_TAC ‘Normal (-1 + l)’ >> rw [lt_infty, le_inf'] \\
8926           rw [GSYM extreal_add_def, GSYM extreal_ainv_def] \\
8927           MATCH_MP_TAC lt_imp_le \\
8928           Know ‘-Normal 1 + Normal l < a n <=> -Normal 1 < a n - Normal l’
8929           >- (MATCH_MP_TAC lt_sub >> rw [extreal_ainv_def]) >> Rewr' \\
8930           METIS_TAC []) >> DISCH_TAC \\
8931       Know ‘?f. (!m n. m < n ==> f m < f n) /\
8932                 (real o a o f --> real (liminf a)) sequentially’
8933       >- (MATCH_MP_TAC ext_liminf_imp_subseq >> art []) >> STRIP_TAC \\
8934       Know ‘(real o a o f --> l) sequentially’
8935       >- (REWRITE_TAC [o_ASSOC] \\
8936           MATCH_MP_TAC LIM_SUBSEQUENCE >> art []) >> DISCH_TAC \\
8937    (* applying LIM_UNIQUE *)
8938       Know ‘real (liminf a) = l’
8939       >- (METIS_TAC [LIM_UNIQUE, TRIVIAL_LIMIT_SEQUENTIALLY]) \\
8940       REWRITE_TAC [GSYM extreal_11] \\
8941       ASM_SIMP_TAC std_ss [normal_real] ])
8942 (* stage work, now the hard part *)
8943 >> STRIP_TAC
8944 (* eventually ‘inf {a n | k <= n}’ (increasing) is normal *)
8945 >> Cases_on ‘!N1. inf {a n | N1 <= n} = NegInf’
8946 >- (Suff ‘liminf a = NegInf’ >- fs [] \\
8947     SIMP_TAC std_ss [ext_liminf_def] >> POP_ORW \\
8948     Know ‘IMAGE (\m. NegInf) univ(:num) = (\y. y = NegInf)’
8949     >- (rw [Once EXTENSION]) >> Rewr' \\
8950     rw [sup_const])
8951 (* eventually ‘sup {a n | k <= n}’ (decreasing) is normal *)
8952 >> Cases_on ‘!N2. sup {a n | N2 <= n} = PosInf’
8953 >- (Suff ‘limsup a = PosInf’ >- fs [] \\
8954     SIMP_TAC std_ss [ext_limsup_def] >> POP_ORW \\
8955     Know ‘IMAGE (\m. PosInf) univ(:num) = (\y. y = PosInf)’
8956     >- (rw [Once EXTENSION]) >> Rewr' \\
8957     rw [inf_const])
8958 >> FULL_SIMP_TAC bool_ss [] (* this asserts N1 and N2 *)
8959 >> Know ‘!k. N1 <= k ==> inf {a n | k <= n} <> NegInf’
8960 >- (rw [lt_infty] >> MATCH_MP_TAC lte_trans \\
8961     Q.EXISTS_TAC ‘inf {a n | N1 <= n}’ \\
8962     CONJ_TAC >- rw [GSYM lt_infty] \\
8963     MATCH_MP_TAC inf_mono_subset >> rw [SUBSET_DEF] \\
8964     Q.EXISTS_TAC ‘n’ >> rw [])
8965 >> DISCH_TAC
8966 >> Know ‘!k. N2 <= k ==> sup {a n | k <= n} <> PosInf’
8967 >- (rw [lt_infty] >> MATCH_MP_TAC let_trans \\
8968     Q.EXISTS_TAC ‘sup {a n | N2 <= n}’ \\
8969     reverse CONJ_TAC >- rw [GSYM lt_infty] \\
8970     MATCH_MP_TAC sup_mono_subset >> rw [SUBSET_DEF] \\
8971     Q.EXISTS_TAC ‘n’ >> rw [])
8972 >> DISCH_TAC
8973 >> Q.PAT_X_ASSUM ‘inf {a n | N1 <= n} <> NegInf’ K_TAC
8974 >> Q.PAT_X_ASSUM ‘sup {a n | N2 <= n} <> PosInf’ K_TAC
8975 (* stage work *)
8976 >> Know ‘!k. 0 <= a k - inf {a n | k <= n}’
8977 >- (Q.X_GEN_TAC ‘k’ \\
8978     MATCH_MP_TAC le_sub_imp2 >> rw [inf_le'] \\
8979     POP_ASSUM MATCH_MP_TAC \\
8980     Q.EXISTS_TAC ‘k’ >> rw [])
8981 >> DISCH_TAC
8982 >> Know ‘!k. inf {a n | k <= n} <> PosInf’
8983 >- (Q.X_GEN_TAC ‘k’ \\
8984     SPOSE_NOT_THEN (ASSUME_TAC o (SIMP_RULE std_ss [])) \\
8985     Q.PAT_X_ASSUM ‘!k. 0 <= a k - inf {a n | k <= n}’ (MP_TAC o (Q.SPEC ‘k’)) \\
8986    ‘?r. a k = Normal r’ by METIS_TAC [extreal_cases] >> art [] \\
8987     simp [extreal_sub_def, GSYM extreal_lt_def, lt_infty, extreal_of_num_def])
8988 >> DISCH_TAC
8989 >> Know ‘!k. sup {a n | k <= n} <> NegInf’
8990 >- (rw [lt_infty] \\
8991     MATCH_MP_TAC lte_trans >> Q.EXISTS_TAC ‘a k’ \\
8992     CONJ_TAC >- (‘?r. a k = Normal r’ by METIS_TAC [extreal_cases] \\
8993                  rw [GSYM lt_infty]) \\
8994     rw [le_sup'] \\
8995     FIRST_X_ASSUM MATCH_MP_TAC >> Q.EXISTS_TAC ‘k’ >> rw [])
8996 >> DISCH_TAC
8997 >> Know ‘!k. a k - inf {a n | k <= n} <= sup {a n | k <= n} - inf {a n | k <= n}’
8998 >- (Q.X_GEN_TAC ‘k’ \\
8999     MATCH_MP_TAC le_rsub_imp >> rw [le_sup'] \\
9000     POP_ASSUM MATCH_MP_TAC \\
9001     Q.EXISTS_TAC ‘k’ >> rw [])
9002 >> DISCH_TAC
9003 >> Q.ABBREV_TAC ‘P = \(k :num). sup {a n | k <= n} - inf {a n | k <= n}’
9004 >> Know ‘!k. 0 <= P k’
9005 >- (rw [Abbr ‘P’] \\
9006     MATCH_MP_TAC le_trans \\
9007     Q.EXISTS_TAC ‘a k - inf {a n | k <= n}’ >> rw [])
9008 >> DISCH_TAC
9009 (* applying lt_inf_epsilon' on liminf a *)
9010 >> Q.ABBREV_TAC ‘Q = IMAGE (\m. inf {a n | m <= n}) UNIV’
9011 >> ‘sup Q = liminf a’ by METIS_TAC [ext_liminf_def]
9012 >> Know ‘!z. 0 < z ==> ?x. x IN Q /\ sup Q < x + z’
9013 >- (rpt STRIP_TAC \\
9014     MATCH_MP_TAC sup_lt_epsilon' >> rw [Abbr ‘Q’] \\
9015     Q.EXISTS_TAC ‘inf {a n | N1 <= n}’ >> rw [] \\
9016     Q.EXISTS_TAC ‘N1’ >> rw [])
9017 >> POP_ORW >> rw [Abbr ‘Q’]
9018 (* applying sup_lt_epsilon' on limsup a *)
9019 >> Q.ABBREV_TAC ‘Q = IMAGE (\m. sup {a n | m <= n}) UNIV’
9020 >> ‘inf Q = limsup a’ by METIS_TAC [ext_limsup_def]
9021 >> Know ‘!z. 0 < z ==> ?x. x IN Q /\ x < inf Q + z’
9022 >- (rpt STRIP_TAC \\
9023     MATCH_MP_TAC lt_inf_epsilon' >> rw [Abbr ‘Q’] \\
9024     Q.EXISTS_TAC ‘sup {a n | N2 <= n}’ >> rw [] \\
9025     Q.EXISTS_TAC ‘N2’ >> rw [])
9026 >> POP_ORW >> rw [Abbr ‘Q’]
9027 (* This is stronger than ‘inf (IMAGE P UNIV) = 0’ *)
9028 >> Know ‘(real o P --> 0) sequentially’
9029 >- (rw [LIM_SEQUENTIALLY, o_DEF, dist] \\
9030    ‘0 < e / 2’ by rw [] \\
9031     NTAC 2 (Q.PAT_X_ASSUM ‘!z. 0 < z ==> ?x. R’
9032               (MP_TAC o (Q.SPEC ‘Normal (e / 2)’))) \\
9033     rw [extreal_of_num_def, extreal_lt_eq] (* this asserts ‘m’ and ‘m'’ *) \\
9034     fs [Abbr ‘P’] \\
9035     Q.EXISTS_TAC ‘MAX m m'’ \\
9036     Q.X_GEN_TAC ‘i’ >> rw [] \\
9037     Know ‘inf {a n | m <= n} <> NegInf’
9038     >- (SPOSE_NOT_THEN (ASSUME_TAC o (SIMP_RULE std_ss [])) \\
9039         Q.PAT_X_ASSUM ‘Normal l < inf {a n | m <= n} + Normal (e / 2)’ MP_TAC \\
9040         ASM_REWRITE_TAC [extreal_add_def, lt_infty]) >> DISCH_TAC \\
9041     Know ‘inf {a n | i <= n} <> NegInf’
9042     >- (REWRITE_TAC [lt_infty] >> MATCH_MP_TAC lte_trans \\
9043         Q.EXISTS_TAC ‘inf {a n | m <= n}’ >> rw [GSYM lt_infty] \\
9044         MATCH_MP_TAC inf_mono_subset >> rw [SUBSET_DEF] \\
9045         Q.EXISTS_TAC ‘n’ >> rw []) >> DISCH_TAC \\
9046     Know ‘sup {a n | m' <= n} <> PosInf’
9047     >- (SPOSE_NOT_THEN (ASSUME_TAC o (SIMP_RULE std_ss [])) \\
9048         Q.PAT_X_ASSUM ‘sup {a n | m' <= n} < Normal l + Normal (e / 2)’ MP_TAC \\
9049         ASM_REWRITE_TAC [extreal_add_def, lt_infty]) >> DISCH_TAC \\
9050     Know ‘sup {a n | i <= n} <> PosInf’
9051     >- (REWRITE_TAC [lt_infty] >> MATCH_MP_TAC let_trans \\
9052         Q.EXISTS_TAC ‘sup {a n | m' <= n}’ >> rw [GSYM lt_infty] \\
9053         MATCH_MP_TAC sup_mono_subset >> rw [SUBSET_DEF] \\
9054         Q.EXISTS_TAC ‘n’ >> rw []) >> DISCH_TAC \\
9055     Know ‘abs (real (sup {a n | i <= n} - inf {a n | i <= n})) =
9056                real (sup {a n | i <= n} - inf {a n | i <= n})’
9057     >- (rw [abs_refl] \\
9058         RW_TAC std_ss [GSYM extreal_le_eq, GSYM extreal_of_num_def] \\
9059         Suff ‘Normal (real (sup {a n | i <= n} - inf {a n | i <= n})) =
9060                             sup {a n | i <= n} - inf {a n | i <= n}’
9061         >- RW_TAC std_ss [] \\
9062         MATCH_MP_TAC normal_real \\
9063        ‘?r. sup {a n | i <= n} = Normal r’ by METIS_TAC [extreal_cases] >> POP_ORW \\
9064        ‘?z. inf {a n | i <= n} = Normal z’ by METIS_TAC [extreal_cases] >> POP_ORW \\
9065         rw [extreal_sub_def]) >> Rewr' \\
9066     REWRITE_TAC [GSYM extreal_lt_eq] \\
9067     Know ‘Normal (real (sup {a n | i <= n} - inf {a n | i <= n})) =
9068                         sup {a n | i <= n} - inf {a n | i <= n}’
9069     >- (MATCH_MP_TAC normal_real \\
9070        ‘?r. sup {a n | i <= n} = Normal r’ by METIS_TAC [extreal_cases] >> POP_ORW \\
9071        ‘?z. inf {a n | i <= n} = Normal z’ by METIS_TAC [extreal_cases] >> POP_ORW \\
9072         rw [extreal_sub_def]) >> Rewr' \\
9073    ‘Normal e = Normal (e / 2) + Normal (e / 2)’
9074       by METIS_TAC [REAL_HALF_DOUBLE, extreal_add_def, extreal_11] >> POP_ORW \\
9075     MATCH_MP_TAC let_trans \\
9076     Q.EXISTS_TAC ‘sup {a n | m' <= n} - inf {a n | i <= n}’ \\
9077     CONJ_TAC >- (MATCH_MP_TAC le_rsub_imp \\
9078                  MATCH_MP_TAC sup_mono_subset >> rw [SUBSET_DEF] \\
9079                  Q.EXISTS_TAC ‘n’ >> rw []) \\
9080     MATCH_MP_TAC let_trans \\
9081     Q.EXISTS_TAC ‘sup {a n | m' <= n} - inf {a n | m <= n}’ \\
9082     CONJ_TAC >- (MATCH_MP_TAC le_lsub_imp \\
9083                  MATCH_MP_TAC inf_mono_subset >> rw [SUBSET_DEF] \\
9084                  Q.EXISTS_TAC ‘n’ >> rw []) \\
9085     MATCH_MP_TAC lt_trans \\
9086     Q.EXISTS_TAC ‘Normal l + Normal (e / 2) - inf {a n | m <= n}’ \\
9087     CONJ_TAC >- (MATCH_MP_TAC lt_rsub_imp >> rw []) \\
9088     MATCH_MP_TAC sub_lt_imp2 \\
9089     NTAC 2 (CONJ_TAC >- rw [extreal_add_def]) \\
9090     Q.ABBREV_TAC ‘E = e / 2’ \\
9091     Q.PAT_X_ASSUM ‘Normal l < inf {a n | m <= n} + Normal E’ MP_TAC \\
9092    ‘?r. inf {a n | m <= n} = Normal r’ by METIS_TAC [extreal_cases] >> POP_ORW \\
9093     simp [extreal_add_def, extreal_lt_eq] \\
9094     REAL_ARITH_TAC)
9095 >> DISCH_TAC
9096 >> Q.ABBREV_TAC ‘Q = \(k :num). a k - inf {a n | k <= n}’
9097 >> ‘!k. 0 <= Q k /\ Q k <= P k’ by METIS_TAC []
9098 >> Know ‘(real o Q --> 0) sequentially’
9099 >- (Q.PAT_X_ASSUM ‘(real o P --> 0) sequentially’ MP_TAC \\
9100     rw [LIM_SEQUENTIALLY, o_DEF, dist] \\
9101     Q.PAT_X_ASSUM ‘!e. 0 < e ==> ?N. !n. N <= n ==> abs (real (P n)) < e’
9102       (MP_TAC o (Q.SPEC ‘e’)) \\
9103     RW_TAC std_ss [] (* this asserts ‘N’ *) \\
9104     Q.EXISTS_TAC ‘MAX N (MAX N1 N2)’ \\
9105     Q.X_GEN_TAC ‘i’ >> rw [] \\
9106     Know ‘P i <> PosInf /\ P i <> NegInf’
9107     >- (simp [Abbr ‘P’] \\
9108        ‘?r. sup {a n | i <= n} = Normal r’ by METIS_TAC [extreal_cases] >> POP_ORW \\
9109        ‘?z. inf {a n | i <= n} = Normal z’ by METIS_TAC [extreal_cases] >> POP_ORW \\
9110         rw [extreal_sub_def]) >> STRIP_TAC \\
9111     Know ‘Q i <> PosInf /\ Q i <> NegInf’
9112     >- (simp [Abbr ‘Q’] \\
9113        ‘?r. a i = Normal r’                by METIS_TAC [extreal_cases] >> POP_ORW \\
9114        ‘?z. inf {a n | i <= n} = Normal z’ by METIS_TAC [extreal_cases] >> POP_ORW \\
9115         rw [extreal_sub_def]) >> STRIP_TAC \\
9116     Know ‘abs (real (Q i)) = real (Q i)’
9117     >- (rw [abs_refl] \\
9118         RW_TAC std_ss [GSYM extreal_le_eq, GSYM extreal_of_num_def] \\
9119         Suff ‘Normal (real (Q i)) = Q i’ >- RW_TAC std_ss [] \\
9120         MATCH_MP_TAC normal_real >> rw []) >> Rewr' \\
9121     Q.PAT_X_ASSUM ‘!n. N <= n ==> abs (real (P n)) < e’
9122       (fn th => ASSUME_TAC (MATCH_MP th (ASSUME “N <= (i :num)”))) \\
9123     Know ‘abs (real (P i)) = real (P i)’
9124     >- (rw [abs_refl] \\
9125         RW_TAC std_ss [GSYM extreal_le_eq, GSYM extreal_of_num_def] \\
9126         Suff ‘Normal (real (P i)) = P i’ >- RW_TAC std_ss [] \\
9127         MATCH_MP_TAC normal_real >> rw []) >> DISCH_THEN (fs o wrap) \\
9128     MATCH_MP_TAC REAL_LET_TRANS \\
9129     Q.EXISTS_TAC ‘real (P i)’ >> art [] \\
9130     REWRITE_TAC [GSYM extreal_le_eq] \\
9131     RW_TAC std_ss [normal_real])
9132 >> DISCH_TAC
9133 (* final stage *)
9134 >> rw [LIM_SEQUENTIALLY_real_normal]
9135 >> ‘0 < e / 2’ by rw []
9136 >> Q.PAT_X_ASSUM ‘(real o Q --> 0) sequentially’ MP_TAC
9137 >> rw [LIM_SEQUENTIALLY, dist]
9138 >> POP_ASSUM (MP_TAC o (Q.SPEC ‘e / 2’))
9139 >> RW_TAC std_ss [] (* this asserts ‘N’ *)
9140 >> FULL_SIMP_TAC std_ss [Abbr ‘Q’]
9141 >> Q.PAT_X_ASSUM ‘!z. 0 < z ==> ?x. _ /\ Normal l < x + z’
9142      (MP_TAC o (Q.SPEC ‘Normal (e / 2)’))
9143 >> rw [extreal_of_num_def, extreal_lt_eq] (* this asserts ‘m’ *)
9144 >> Q.EXISTS_TAC ‘MAX (MAX N1 N) m’
9145 >> Q.X_GEN_TAC ‘i’ >> rw []
9146 >> Know ‘a i - Normal l =
9147         (a i - inf {a n | i <= n}) + (inf {a n | i <= n} - Normal l)’
9148 >- (‘?r. a i = Normal r’                by METIS_TAC [extreal_cases] >> POP_ORW \\
9149     ‘?z. inf {a n | i <= n} = Normal z’ by METIS_TAC [extreal_cases] >> POP_ORW \\
9150     rw [extreal_add_def, extreal_sub_def] >> REAL_ARITH_TAC)
9151 >> Rewr'
9152 (* applying abs_triangle *)
9153 >> Q_TAC (TRANS_TAC let_trans) ‘abs (a i - inf {a n | i <= n}) +
9154                                 abs (inf {a n | i <= n} - Normal l)’
9155 >> CONJ_TAC
9156 >- (MATCH_MP_TAC abs_triangle \\
9157    ‘?r. a i = Normal r’                by METIS_TAC [extreal_cases] >> POP_ORW \\
9158    ‘?z. inf {a n | i <= n} = Normal z’ by METIS_TAC [extreal_cases] >> POP_ORW \\
9159     rw [extreal_sub_def])
9160 >> ‘Normal e = Normal (e / 2) + Normal (e / 2)’
9161       by METIS_TAC [REAL_HALF_DOUBLE, extreal_add_def, extreal_11] >> POP_ORW
9162 >> MATCH_MP_TAC lt_add2
9163 >> CONJ_TAC
9164 >| [ (* goal 1 (of 2) *)
9165     ‘abs (a i - inf {a n | i <= n}) = a i - inf {a n | i <= n}’
9166        by (rw [abs_refl]) >> POP_ORW \\
9167      Q.PAT_X_ASSUM ‘!n. N <= n ==> _ < e / 2’ (MP_TAC o (Q.SPEC ‘i’)) \\
9168      RW_TAC std_ss [] \\
9169     ‘?r. a i = Normal r’                by METIS_TAC [extreal_cases] \\
9170      POP_ASSUM (FULL_SIMP_TAC std_ss o wrap) \\
9171     ‘?z. inf {a n | i <= n} = Normal z’ by METIS_TAC [extreal_cases] \\
9172      POP_ASSUM (FULL_SIMP_TAC std_ss o wrap) \\
9173      FULL_SIMP_TAC std_ss [extreal_sub_def, real_normal, extreal_lt_eq] \\
9174      FULL_SIMP_TAC std_ss [ABS_BOUNDS_LT],
9175      (* goal 2 (of 2) *)
9176      Know ‘abs (inf {a n | i <= n} - Normal l) = -(inf {a n | i <= n} - Normal l)’
9177      >- (MATCH_MP_TAC abs_neg' \\
9178          Know ‘inf {a n | i <= n} - Normal l <= 0 <=> inf {a n | i <= n} <= Normal l’
9179          >- (ONCE_REWRITE_TAC [EQ_SYM_EQ] \\
9180              MATCH_MP_TAC sub_le_zero >> rw []) >> Rewr' \\
9181          Q.PAT_X_ASSUM ‘liminf a = Normal l’ (ONCE_REWRITE_TAC o wrap o SYM) \\
9182          rw [ext_liminf_def, le_sup'] \\
9183          POP_ASSUM MATCH_MP_TAC \\
9184          Q.EXISTS_TAC ‘i’ >> rw []) >> Rewr' \\
9185      Know ‘-(inf {a n | i <= n} - Normal l) = Normal l - inf {a n | i <= n}’
9186      >- (MATCH_MP_TAC neg_sub \\
9187          DISJ2_TAC >> rw []) >> Rewr' \\
9188      MATCH_MP_TAC sub_lt_imp2 >> rw [] \\
9189      MATCH_MP_TAC lte_trans \\
9190      Q.EXISTS_TAC ‘inf {a n | m <= n} + Normal (e / 2)’ >> rw [add_comm_normal] \\
9191      MATCH_MP_TAC le_radd_imp \\
9192      MATCH_MP_TAC inf_mono_subset >> rw [SUBSET_DEF] \\
9193      Q.EXISTS_TAC ‘n’ >> rw [] ]
9194QED
9195
9196(* NOTE: This is a combination of ext_limsup_thm and extreal_lim_sequentially_eq *)
9197Theorem ext_limsup_thm' :
9198    !f l. (!n. f n <> PosInf /\ f n <> NegInf) /\ l <> PosInf /\ l <> NegInf ==>
9199          ((f --> l) sequentially <=> limsup f = l /\ liminf f = l)
9200Proof
9201    rpt STRIP_TAC
9202 >> Know ‘(f --> l) sequentially <=> (real o f --> real l) sequentially’
9203 >- (MATCH_MP_TAC extreal_lim_sequentially_eq >> art [])
9204 >> Rewr'
9205 >> ‘?r. l = Normal r’ by METIS_TAC [extreal_cases]
9206 >> simp [real_normal]
9207 >> MATCH_MP_TAC ext_limsup_thm >> art []
9208QED
9209
9210(* |- !f g l m.
9211        (f --> l) sequentially /\ (g --> m) sequentially ==>
9212        ((\x. f x + g x) --> (l + m)) sequentially
9213 *)
9214Theorem lim_sequentially_add = Q.ISPEC ‘sequentially’ EXTREAL_LIM_ADD
9215
9216Theorem lim_sequentially_sum :
9217    !f l s. FINITE s /\ (!i. i IN s ==> (f i --> l i) sequentially) /\
9218           (!i n. i IN s ==> f i n <> PosInf /\ f i n <> NegInf) /\
9219           (!i. l i <> PosInf /\ l i <> NegInf) ==>
9220           ((\n. SIGMA (\i. f i n) s) --> SIGMA l s) sequentially
9221Proof
9222    qx_genl_tac [‘f’, ‘l’]
9223 >> Suff ‘!s. FINITE s ==>
9224             (!i. i IN s ==> (f i --> l i) sequentially) /\
9225             (!i n. i IN s ==> f i n <> PosInf /\ f i n <> NegInf) /\
9226             (!i. l i <> PosInf /\ l i <> NegInf) ==>
9227             ((\n. SIGMA (\i. f i n) s) --> SIGMA l s) sequentially’
9228 >- METIS_TAC []
9229 >> HO_MATCH_MP_TAC FINITE_INDUCT
9230 >> simp [EXTREAL_LIM_CONST]
9231 >> rpt STRIP_TAC
9232 (* applying EXTREAL_SUM_IMAGE_PROPERTY *)
9233 >> Know ‘!n. SIGMA (\i. f i n) (e INSERT s) =
9234              (\i. f i n) e + SIGMA (\i. f i n) (s DELETE e)’
9235 >- (Q.X_GEN_TAC ‘n’ \\
9236     irule EXTREAL_SUM_IMAGE_PROPERTY >> simp [] \\
9237     METIS_TAC [])
9238 >> Rewr'
9239 >> Know ‘SIGMA l (e INSERT s) = l e + SIGMA l (s DELETE e)’
9240 >- (irule EXTREAL_SUM_IMAGE_PROPERTY >> simp [])
9241 >> Rewr'
9242 >> ‘s DELETE e = s’ by rw [GSYM DELETE_NON_ELEMENT]
9243 >> simp []
9244 >> HO_MATCH_MP_TAC lim_sequentially_add >> simp []
9245 >> ‘(\n. f e n) = f e’ by rw [FUN_EQ_THM] >> POP_ORW
9246 >> FIRST_X_ASSUM MATCH_MP_TAC >> simp []
9247QED
9248
9249Theorem lim_sequentially_cmul :
9250    !f l c. (!n. f n <> PosInf /\ f n <> NegInf) /\ l <> PosInf /\ l <> NegInf /\
9251            c <> PosInf /\ c <> NegInf /\
9252            (f --> l) sequentially ==> ((\n. c * f n) --> (c * l)) sequentially
9253Proof
9254    rpt STRIP_TAC
9255 >> qmatch_abbrev_tac ‘(g --> m) sequentially’
9256 >> Know ‘(g --> m) sequentially <=> (real o g --> real m) sequentially’
9257 >- (MATCH_MP_TAC extreal_lim_sequentially_eq \\
9258     simp [Abbr ‘g’, Abbr ‘m’] \\
9259    ‘?l'. l = Normal l'’ by METIS_TAC [extreal_cases] \\
9260    ‘?c'. c = Normal c'’ by METIS_TAC [extreal_cases] \\
9261     simp [extreal_mul_def] \\
9262     Q.EXISTS_TAC ‘0’ >> simp [] \\
9263     Q.X_GEN_TAC ‘n’ \\
9264    ‘?r. f n = Normal r’ by METIS_TAC [extreal_cases] \\
9265     simp [extreal_mul_def])
9266 >> Rewr'
9267 >> simp [Abbr ‘g’, Abbr ‘m’, mul_real, o_DEF]
9268 >> HO_MATCH_MP_TAC LIM_CMUL
9269 >> ‘(\n. real (f n)) = real o f’ by rw [FUN_EQ_THM, o_DEF] >> POP_ORW
9270 >> Suff ‘(real o f --> real l) sequentially <=> (f --> l) sequentially’
9271 >- rw []
9272 >> SYM_TAC
9273 >> MATCH_MP_TAC extreal_lim_sequentially_eq >> simp []
9274QED
9275
9276(* ------------------------------------------------------------------------- *)
9277(*   Analytic properties of mono-increasing functions (:extreal -> extreal)  *)
9278(* ------------------------------------------------------------------------- *)
9279
9280(* NOTE: “f right_continuous_at x0” (continuous from right) only holds for
9281   certain mono-increasing functions such as distribution functions.
9282
9283   It seems meaningless to talk about continuous at infinities, thus the type
9284   of x0 is :real instead of :extreal.
9285 *)
9286val _ = set_fixity "right_continuous_at" (Infix(NONASSOC, 450));
9287
9288Definition right_continuous_at :
9289    (f :extreal -> extreal) right_continuous_at x0 <=> inf {f x | x0 < x} = f x0
9290End
9291
9292(* cf. continuous_at for the rationale of the conclusion part. The present proof
9293   is based on inf_seq', which connects the sequential limit to inf IMAGE.
9294 *)
9295Theorem right_continuous_at_thm :
9296    !f x0. (!x y. x <= y ==> f x <= f y) /\ f right_continuous_at (Normal x0) /\
9297           (!x. f x <> PosInf /\ f x <> NegInf) ==>
9298            !e. 0 < e /\ e <> PosInf ==>
9299                ?d. 0 < d /\ !x. x - x0 < d ==> f (Normal x) - f (Normal x0) <= e
9300Proof
9301    rw [right_continuous_at]
9302 >> qabbrev_tac ‘y = f (Normal x0)’
9303 >> Q.PAT_X_ASSUM ‘inf _ = y’ MP_TAC
9304 (* preparing for inf_seq' *)
9305 >> qabbrev_tac ‘g = \n. real (f (Normal (x0 + inv &SUC n)))’
9306 >> Know ‘mono_decreasing g’
9307 >- (rw [mono_decreasing_def, Abbr ‘g’] \\
9308     REWRITE_TAC [GSYM extreal_le_eq] \\
9309     ASM_SIMP_TAC std_ss [normal_real] \\
9310     FIRST_X_ASSUM MATCH_MP_TAC >> rw [])
9311 >> DISCH_TAC
9312 >> Know ‘inf {f x | Normal x0 < x} = inf (IMAGE (\n. Normal (g n)) UNIV)’
9313 >- (reverse (rw [inf_eq'])
9314     >- (rw [le_inf', Abbr ‘g’, normal_real] \\
9315         POP_ASSUM MATCH_MP_TAC \\
9316         Q.EXISTS_TAC ‘Normal (x0 + inv (&SUC n))’ >> rw []) \\
9317     rw [inf_le', Abbr ‘g’, normal_real] \\
9318     Cases_on ‘x = PosInf’
9319     >- (Q_TAC (TRANS_TAC le_trans) ‘f (Normal (x0 + inv (&SUC 0)))’ \\
9320         CONJ_TAC >- (FIRST_X_ASSUM MATCH_MP_TAC \\
9321                      Q.EXISTS_TAC ‘0’ >> rw []) \\
9322         FIRST_X_ASSUM MATCH_MP_TAC >> rw []) \\
9323     Cases_on ‘x = NegInf’ >> fs [] \\
9324    ‘?r. x = Normal r’ by METIS_TAC [extreal_cases] \\
9325     POP_ASSUM (fs o wrap) >> T_TAC \\
9326    ‘0 < r - x0’ by rw [REAL_SUB_LT] \\
9327     drule REAL_ARCH_INV_SUC >> STRIP_TAC \\
9328     POP_ASSUM (ASSUME_TAC o
9329                REWRITE_RULE [REAL_LT_SUB_LADD, Once REAL_ADD_COMM]) \\
9330     Q_TAC (TRANS_TAC le_trans) ‘f (Normal (x0 + inv (&SUC n)))’ \\
9331     reverse CONJ_TAC
9332     >- (FIRST_X_ASSUM MATCH_MP_TAC >> simp [] \\
9333         MATCH_MP_TAC REAL_LT_IMP_LE >> art []) \\
9334     FIRST_X_ASSUM MATCH_MP_TAC \\
9335     Q.EXISTS_TAC ‘n’ >> rw [])
9336 >> Rewr'
9337 >> ‘?l. y = Normal l’ by METIS_TAC [extreal_cases]
9338 >> fs [Abbr ‘y’]
9339 (* applying inf_seq' *)
9340 >> Know ‘inf (IMAGE (\n. Normal (g n)) univ(:num)) = Normal l <=>
9341          (g --> l) sequentially’
9342 >- (ONCE_REWRITE_TAC [EQ_SYM_EQ] \\
9343     MATCH_MP_TAC inf_seq' >> art [])
9344 >> Rewr'
9345 >> rw [LIM_SEQUENTIALLY, metricTheory.dist, Abbr ‘g’]
9346 >> ‘e <> NegInf’ by rw [pos_not_neginf, lt_imp_le]
9347 >> ‘?r. 0 < r /\ e = Normal r’
9348      by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq]
9349 >> POP_ORW
9350 >> Q.PAT_X_ASSUM ‘!e. 0 < e ==> _’ (MP_TAC o Q.SPEC ‘r’) >> rw []
9351 >> Q.EXISTS_TAC ‘inv &SUC N’
9352 >> CONJ_TAC >- (MATCH_MP_TAC REAL_INV_POS >> rw [])
9353 >> rpt STRIP_TAC
9354 (* redefine g as the real version of f *)
9355 >> qabbrev_tac ‘g = real o f’
9356 >> Know ‘!x. f x = Normal (g x)’
9357 >- (rw [Abbr ‘g’] \\
9358     rw [normal_real])
9359 >> DISCH_THEN (FULL_SIMP_TAC std_ss o wrap)
9360 >> FULL_SIMP_TAC std_ss [real_normal, extreal_le_eq, extreal_sub_def, extreal_11]
9361 >> Q.PAT_X_ASSUM ‘!n. N <= n ==> _’ (MP_TAC o Q.SPEC ‘N’)
9362 >> simp []
9363 >> Know ‘abs (g (Normal (x0 + inv (&SUC N))) - l) =
9364               g (Normal (x0 + inv (&SUC N))) - l’
9365 >- (simp [ABS_REFL, REAL_SUB_LE] \\
9366     Q.PAT_X_ASSUM ‘_ = l’ (REWRITE_TAC o wrap o SYM) \\
9367     FIRST_X_ASSUM MATCH_MP_TAC >> simp [])
9368 >> Rewr'
9369 >> DISCH_TAC
9370 >> Q_TAC (TRANS_TAC REAL_LE_TRANS) ‘g (Normal (x0 + inv (&SUC N))) - l’
9371 >> reverse CONJ_TAC
9372 >- (MATCH_MP_TAC REAL_LT_IMP_LE >> art [])
9373 >> REWRITE_TAC [REAL_LE_SUB_CANCEL2]
9374 >> FIRST_X_ASSUM MATCH_MP_TAC
9375 >> simp []
9376 >> REWRITE_TAC [Once REAL_ADD_COMM]
9377 >> REWRITE_TAC [GSYM REAL_LE_SUB_RADD]
9378 >> MATCH_MP_TAC REAL_LT_IMP_LE >> art []
9379QED
9380
9381(* A function is "right-continuous" if it's right-continuous at every point.
9382
9383   NOTE: the requirement of mono-increasing is included since this version of
9384  "right-continuous" definition only works on mono-increasing functions.
9385
9386   NOTE: The concept of "right-continuous" at points PosInf/NegInf is tricky,
9387   and (may) not be true for all distribution functions, thus is excluded.
9388 *)
9389Definition right_continuous :
9390    right_continuous (f :extreal -> extreal) <=>
9391      (!x y. x <= y ==> f x <= f y) /\ !x. f right_continuous_at (Normal x)
9392End
9393
9394(* |- !f. right_continuous f <=>
9395         (!x y. x <= y ==> f x <= f y) /\ !x. inf {f x' | x < x'} = f (Normal x)
9396 *)
9397Theorem right_continuous_def =
9398        right_continuous |> REWRITE_RULE [right_continuous_at]
9399
9400(* NOTE: This core lemma holds also for other shapes of intervals (not used) *)
9401Theorem countable_disjoint_interval_lemma :
9402    !s. s = {interval (c,d) | c < d} /\ disjoint s ==> countable s
9403Proof
9404    simp [disjoint_def, IN_INTERVAL] >> DISCH_TAC
9405 >> qmatch_abbrev_tac ‘countable s’
9406 >> MP_TAC Q_DENSE_IN_REAL
9407 >> simp [GSYM RIGHT_EXISTS_IMP_THM, SKOLEM_THM]
9408 >> STRIP_TAC
9409 (* t is the set of rationals one-one mapping to each open intervals *)
9410 >> qabbrev_tac ‘g = \e. f (interval_lowerbound e) (interval_upperbound e)’
9411 >> qabbrev_tac ‘t = IMAGE g s’
9412 >> Suff ‘cardeq s t’
9413 >- (DISCH_TAC \\
9414     Know ‘countable s <=> countable t’
9415     >- (MATCH_MP_TAC CARD_COUNTABLE_CONG >> art []) >> Rewr' \\
9416     Q.PAT_X_ASSUM ‘cardeq s t’ K_TAC \\
9417     MATCH_MP_TAC COUNTABLE_SUBSET \\
9418     Q.EXISTS_TAC ‘q_set’ \\
9419     rw [QSET_COUNTABLE, SUBSET_DEF, Abbr ‘t’, Abbr ‘g’, Abbr ‘s’] \\
9420     simp [OPEN_INTERVAL_LOWERBOUND, OPEN_INTERVAL_UPPERBOUND])
9421 (* stage work *)
9422 >> simp [GSYM CARD_LE_ANTISYM]
9423 >> reverse CONJ_TAC >- rw [IMAGE_cardleq, Abbr ‘t’]
9424 >> rw [cardleq_def, INJ_DEF]
9425 >> Q.EXISTS_TAC ‘g’
9426 >> CONJ_TAC
9427 >- (rw [Abbr ‘g’, Abbr ‘t’] \\
9428     Q.EXISTS_TAC ‘x’ >> art [])
9429 (* NOTE: from now on the set ‘t’ is no more used *)
9430 >> rw [Abbr ‘s’, Abbr ‘g’, Abbr ‘t’]
9431 >> gs [OPEN_INTERVAL_LOWERBOUND, OPEN_INTERVAL_UPPERBOUND]
9432 >> rename1 ‘f c d = f a b’
9433 >> CCONTR_TAC
9434 >> qabbrev_tac ‘y = f a b’
9435 >> ‘c < y /\ y < d /\ a < y /\ y < b’ by METIS_TAC []
9436 >> Know ‘DISJOINT (interval (c,d)) (interval (a,b))’ >- METIS_TAC []
9437 >> NTAC 2 (Q.PAT_X_ASSUM ‘!a b. _’ K_TAC)
9438 >> simp [DISJOINT_ALT, OPEN_interval]
9439 >> Q.EXISTS_TAC ‘y’ >> art []
9440QED
9441
9442(* NOTE: It's surprising hard to prove such a simple and obvious statement *)
9443Theorem sup_open_interval :
9444    !a b. a < b ==> sup (open_interval a b) = b
9445Proof
9446    rw [open_interval_def]
9447 >> simp [GSYM le_antisym]
9448 >> CONJ_TAC
9449 >- (rw [sup_le'] \\
9450     MATCH_MP_TAC lt_imp_le >> art [])
9451 >> MATCH_MP_TAC le_epsilon
9452 >> rpt STRIP_TAC
9453 >> qmatch_abbrev_tac ‘b <= c + e’
9454 >> Know ‘e <> NegInf’
9455 >- (MATCH_MP_TAC pos_not_neginf \\
9456     MATCH_MP_TAC lt_imp_le >> art [])
9457 >> DISCH_TAC
9458 >> Know ‘b <= c + e <=> b - e <= c’
9459 >- (ONCE_REWRITE_TAC [EQ_SYM_EQ] \\
9460     MATCH_MP_TAC sub_le_eq >> art [])
9461 >> Rewr'
9462 >> rw [Abbr ‘c’, le_sup']
9463 >> Cases_on ‘b = PosInf’
9464 >- (‘?r. 0 < r /\ e = Normal r’
9465       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq] \\
9466     POP_ORW \\
9467     rw [extreal_sub_def] \\
9468     CCONTR_TAC >> fs [GSYM extreal_lt_def] \\
9469     MP_TAC (Q.SPECL [‘max a y’, ‘PosInf’] extreal_mean) \\
9470     ASM_REWRITE_TAC [max_lt] \\
9471     CCONTR_TAC >> fs [] \\
9472     METIS_TAC [let_antisym])
9473 (* b cannot be NegInf because a < b *)
9474 >> Cases_on ‘b = NegInf’ >- fs [lt_infty]
9475 >> MP_TAC (Q.SPECL [‘max a (b - e)’, ‘b’] extreal_mean) >> simp [max_lt]
9476 >> impl_tac >- rw [sub_lt_eq, lt_addr]
9477 >> STRIP_TAC
9478 >> ‘z <= y’ by rw []
9479 >> Q_TAC (TRANS_TAC le_trans) ‘z’ >> art []
9480 >> MATCH_MP_TAC lt_imp_le >> art []
9481QED
9482
9483Theorem inf_open_interval :
9484    !a b. a < b ==> inf (open_interval a b) = a
9485Proof
9486    rw [open_interval_def]
9487 >> simp [GSYM le_antisym]
9488 >> reverse CONJ_TAC
9489 >- (rw [le_inf'] \\
9490     MATCH_MP_TAC lt_imp_le >> art [])
9491 >> MATCH_MP_TAC le_epsilon
9492 >> rpt STRIP_TAC
9493 >> qmatch_abbrev_tac ‘c <= a + e’
9494 >> Know ‘e <> NegInf’
9495 >- (MATCH_MP_TAC pos_not_neginf \\
9496     MATCH_MP_TAC lt_imp_le >> art [])
9497 >> DISCH_TAC
9498 >> rw [Abbr ‘c’, inf_le']
9499 >> Cases_on ‘a = NegInf’
9500 >- (‘?r. 0 < r /\ e = Normal r’
9501       by METIS_TAC [extreal_cases, extreal_of_num_def, extreal_lt_eq] \\
9502     POP_ORW \\
9503     rw [extreal_add_def] \\
9504     CCONTR_TAC >> fs [GSYM extreal_lt_def] \\
9505     MP_TAC (Q.SPECL [‘NegInf’, ‘min b y’] extreal_mean) \\
9506     ASM_REWRITE_TAC [lt_min] \\
9507     CCONTR_TAC >> fs [] \\
9508     METIS_TAC [let_antisym])
9509 >> Cases_on ‘a = PosInf’ >- fs [lt_infty]
9510 >> MP_TAC (Q.SPECL [‘a’, ‘min (a + e) b’] extreal_mean) >> simp [lt_min]
9511 >> impl_tac >- rw [sub_lt_eq, lt_addr]
9512 >> STRIP_TAC
9513 >> ‘y <= z’ by rw []
9514 >> Q_TAC (TRANS_TAC le_trans) ‘z’ >> art []
9515 >> MATCH_MP_TAC lt_imp_le >> art []
9516QED
9517
9518(* NOTE: This is the extreal version of the core lemma we actually used. *)
9519Theorem countable_disjoint_open_interval_lemma :
9520    !s. s SUBSET {open_interval c d | c < d} /\ disjoint s ==> countable s
9521Proof
9522    rw [SUBSET_DEF, disjoint_def, IN_open_interval]
9523 >> MP_TAC Q_DENSE_IN_R' (* instead of Q_DENSE_IN_REAL *)
9524 >> simp [GSYM RIGHT_EXISTS_IMP_THM, SKOLEM_THM]
9525 >> STRIP_TAC
9526 (* t is the set of rationals one-one mapping to each open intervals *)
9527 >> qabbrev_tac ‘g = \e. f (inf e) (sup e)’
9528 >> qabbrev_tac ‘t = IMAGE g s’
9529 >> Suff ‘cardeq s t’
9530 >- (DISCH_TAC \\
9531     Know ‘countable s <=> countable t’
9532     >- (MATCH_MP_TAC CARD_COUNTABLE_CONG >> art []) >> Rewr' \\
9533     Q.PAT_X_ASSUM ‘cardeq s t’ K_TAC \\
9534     MATCH_MP_TAC COUNTABLE_SUBSET \\
9535     Q.EXISTS_TAC ‘q_set’ \\
9536     rw [QSET_COUNTABLE, SUBSET_DEF, Abbr ‘t’, Abbr ‘g’] \\
9537     Q.PAT_X_ASSUM ‘!x. x IN s ==> ?c d. _’ drule >> rw [] \\
9538     simp [inf_open_interval, sup_open_interval])
9539 (* stage work *)
9540 >> simp [GSYM CARD_LE_ANTISYM]
9541 >> reverse CONJ_TAC >- rw [IMAGE_cardleq, Abbr ‘t’]
9542 >> rw [cardleq_def, INJ_DEF]
9543 >> Q.EXISTS_TAC ‘g’
9544 >> CONJ_TAC
9545 >- (rw [Abbr ‘g’, Abbr ‘t’] \\
9546     Q.EXISTS_TAC ‘x’ >> art [])
9547 (* NOTE: from now on the set ‘t’ is no more used *)
9548 >> rw [Abbr ‘g’, Abbr ‘t’]
9549 >> ‘?a b. x = open_interval a b /\ a < b’ by METIS_TAC []
9550 >> ‘?c d. y = open_interval c d /\ c < d’ by METIS_TAC []
9551 >> gs [inf_open_interval, sup_open_interval]
9552 >> CCONTR_TAC
9553 >> qabbrev_tac ‘z = f c d’
9554 >> ‘a < Normal z /\ Normal z < b /\ c < Normal z /\ Normal z < d’ by METIS_TAC []
9555 >> Know ‘DISJOINT (open_interval a b) (open_interval c d)’ >- METIS_TAC []
9556 >> Q.PAT_X_ASSUM ‘!a b. _ ==> DISJOINT a b’ K_TAC
9557 >> simp [DISJOINT_ALT, IN_open_interval]
9558 >> Q.EXISTS_TAC ‘Normal z’ >> art []
9559QED
9560
9561(* NOTE: This definition does not assume f is left or right-continuous. *)
9562val _ = set_fixity "jumping_point_of" (Infix(NONASSOC, 450));
9563
9564Definition jumping_point_of :
9565    x0 jumping_point_of (f :extreal -> extreal) <=>
9566    sup {f x | x < Normal x0} <> inf {f x | Normal x0 < x}
9567End
9568
9569(* A jumping point is indeed "jumping".
9570
9571   NOTE: Although the jumping point is :real (i.e. meaningless at PosInf/NegInf),
9572   the function values, however, may jump from NegInf to PosInf (of course, such
9573   a big jumping can only happen once if exists.) For distribution functions
9574   ranged from 0 to 1 this is impossible, but the present definition is general.
9575 *)
9576Theorem jumping_point_of_jumping :
9577    !f x0. (!x y. x <= y ==> f x <= f y) /\ x0 jumping_point_of f ==>
9578           sup {f x | x < Normal x0} < inf {f x | Normal x0 < x}
9579Proof
9580    rw [jumping_point_of, lt_le]
9581 >> rw [sup_le']
9582 >> rw [le_inf']
9583 >> Q_TAC (TRANS_TAC le_trans) ‘f (Normal x0)’ >> rw []
9584QED
9585
9586(* NOTE: The set of "jumping points" is simply {x | x jumping_point_of f}.
9587   The next “jumping_area” is a set of all ranges of f where f is jumping, and
9588   therefore “BIGUNION (jumping_area f)” is the actual range (as set of reals)
9589   where f is jumping. f is continuous outside of this range.
9590 *)
9591val _ = set_fixity "flat_area_of" (Infix(NONASSOC, 450));
9592
9593Definition jumping_area_def :
9594    jumping_area f = {open_interval a b | ?x0. x0 jumping_point_of f /\
9595                                               a = sup {f x | x < Normal x0} /\
9596                                               b = inf {f x | Normal x0 < x}}
9597End
9598
9599(* NOTE: There may be jumping points between x0 and y0, but at this moment we
9600   don't know if these jumping points are countable or not.
9601 *)
9602Theorem mono_increasing_lemma :
9603    !f x0 y0. (!x y. x <= y ==> f x <= f y) /\ x0 < y0 ==>
9604              inf {f x | Normal x0 < x} <= sup {f x | x < Normal y0}
9605Proof
9606    rpt STRIP_TAC
9607 >> MP_TAC (Q.SPECL [‘x0’, ‘y0’] REAL_MEAN) >> rw []
9608 >> Q_TAC (TRANS_TAC le_trans) ‘f (Normal z)’
9609 >> CONJ_TAC
9610 >| [ (* goal 1 (of 2) *)
9611      MATCH_MP_TAC inf_le_imp' >> rw [] \\
9612      Q.EXISTS_TAC ‘Normal z’ >> rw [extreal_lt_eq],
9613      (* goal 2 (of 2) *)
9614      MATCH_MP_TAC le_sup_imp' >> rw [] \\
9615      Q.EXISTS_TAC ‘Normal z’ >> rw [extreal_lt_eq] ]
9616QED
9617
9618(* NOTE: This is saying the number of (disjoint) jumping areas is countable.
9619   The entire big union of all jumping areas is still uncountable (if exists).
9620 *)
9621Theorem jumping_area_countable :
9622    !f. (!x y. x <= y ==> f x <= f y) ==> countable (jumping_area f)
9623Proof
9624    rw [jumping_area_def]
9625 >> MATCH_MP_TAC countable_disjoint_open_interval_lemma
9626 >> CONJ_TAC
9627 >- (rw [SUBSET_DEF] \\
9628     qexistsl_tac [‘sup {f x | x < Normal x0}’,
9629                   ‘inf {f x | Normal x0 < x}’] >> art [] \\
9630     MATCH_MP_TAC jumping_point_of_jumping >> art [])
9631 >> rw [disjoint_def]
9632 >> rename1 ‘y0 jumping_point_of f’
9633 >> rw [DISJOINT_ALT, IN_open_interval]
9634 >> CCONTR_TAC
9635 >> Q.PAT_X_ASSUM ‘open_interval _ _ <> open_interval _ _’ MP_TAC >> fs []
9636 >> qmatch_abbrev_tac ‘open_interval a b = open_interval c d’
9637 >> fs [jumping_point_of]
9638 >> ‘a < b /\ c < d’ by METIS_TAC [lt_trans]
9639 >> Cases_on ‘x0 = y0’ >> fs []
9640 >> ‘x0 < y0 \/ y0 < x0’ by METIS_TAC [REAL_LT_TOTAL]
9641 >| [ (* goal 1 (of 2) *)
9642     ‘b <= c’ by METIS_TAC [mono_increasing_lemma] \\
9643     ‘x < c’ by METIS_TAC [lte_trans] \\
9644      METIS_TAC [lt_antisym],
9645      (* goal 2 (of 2) *)
9646     ‘d <= a’ by METIS_TAC [mono_increasing_lemma] \\
9647     ‘x < a’ by METIS_TAC [lte_trans] \\
9648      METIS_TAC [lt_antisym] ]
9649QED
9650
9651Theorem open_interval_11 :
9652    !a b c d. a < b /\ c < d ==>
9653             (open_interval a b = open_interval c d <=> a = c /\ b = d)
9654Proof
9655    rpt STRIP_TAC
9656 >> reverse EQ_TAC >- rw []
9657 >> rw [Once EXTENSION, IN_open_interval]
9658 >| [ (* goal 1 (of 2) *)
9659      CCONTR_TAC \\
9660     ‘a < c \/ c < a’ by METIS_TAC [lt_total] >| (* 2 subgoals *)
9661      [ (* goal 1.1 (of 2): c--------d
9662                        a-z------b *)
9663        MP_TAC (Q.SPECL [‘a’, ‘min b c’] extreal_mean) >> rw [lt_min] \\
9664        CCONTR_TAC >> fs [] \\
9665        METIS_TAC [lt_antisym],
9666        (* goal 1.2 (of 2): a--------b
9667                        c-z------d *)
9668        MP_TAC (Q.SPECL [‘c’, ‘min a d’] extreal_mean) >> rw [lt_min] \\
9669        CCONTR_TAC >> fs [] \\
9670        METIS_TAC [lt_antisym] ],
9671      (* goal 2 (of 2) *)
9672      CCONTR_TAC \\
9673     ‘b < d \/ d < b’ by METIS_TAC [lt_total] >| (* 2 subgoals *)
9674      [ (* goal 1.1 (of 2): c------z-d
9675                        a--------b *)
9676        MP_TAC (Q.SPECL [‘max b c’, ‘d’] extreal_mean) >> rw [max_lt] \\
9677        CCONTR_TAC >> fs [] \\
9678        METIS_TAC [lt_antisym],
9679        (* goal 1.2 (of 2): a------z-b
9680                        c--------d *)
9681        MP_TAC (Q.SPECL [‘max a d’, ‘b’] extreal_mean) >> rw [max_lt] \\
9682        CCONTR_TAC >> fs [] \\
9683        METIS_TAC [lt_antisym] ] ]
9684QED
9685
9686(* NOTE: This is also Lemma 14.14 of [1. p.147] *)
9687Theorem countable_jumping_point_of :
9688    !f. (!x y. x <= y ==> f x <= f y) ==> countable {x | x jumping_point_of f}
9689Proof
9690    rpt STRIP_TAC
9691 >> qmatch_abbrev_tac ‘countable s’
9692 >> Suff ‘countable s <=> countable (jumping_area f)’
9693 >- (Rewr' \\
9694     MATCH_MP_TAC jumping_area_countable >> art [])
9695 >> MATCH_MP_TAC CARD_COUNTABLE_CONG
9696 >> rw [cardeq_def, Abbr ‘s’]
9697 >> qabbrev_tac ‘g = \x0. let a = sup {f x | x < Normal x0};
9698                              b = inf {f x | Normal x0 < x} in
9699                            open_interval a b’
9700 >> Q.EXISTS_TAC ‘g’
9701 >> rw [BIJ_THM, Abbr ‘g’, jumping_area_def]
9702 >- (qexistsl_tac [‘sup {f x | x < Normal x0}’,
9703                   ‘inf {f x | Normal x0 < x}’] >> art [] \\
9704     Q.EXISTS_TAC ‘x0’ >> art [])
9705 >> rw [EXISTS_UNIQUE_ALT]
9706 >> Q.EXISTS_TAC ‘x0’
9707 >> Q.X_GEN_TAC ‘y0’
9708 >> reverse EQ_TAC >- (rw [] >> rw [])
9709 >> STRIP_TAC
9710 >> POP_ASSUM MP_TAC
9711 >> qmatch_abbrev_tac ‘open_interval c d = open_interval a b ==> _’
9712 >> ‘a < b /\ c < d’ by METIS_TAC [jumping_point_of_jumping]
9713 >> simp [open_interval_11]
9714 >> STRIP_TAC
9715 >> CCONTR_TAC
9716 >> ‘x0 < y0 \/ y0 < x0’ by METIS_TAC [REAL_LT_TOTAL]
9717 >| [ (* goal 1 (of 2) *)
9718     ‘b <= c’ by METIS_TAC [mono_increasing_lemma] \\
9719     ‘a < c’ by METIS_TAC [lte_trans] \\
9720      METIS_TAC [lt_le],
9721      (* goal 2 (of 2) *)
9722     ‘d <= a’ by METIS_TAC [mono_increasing_lemma] \\
9723     ‘d < b’ by METIS_TAC [let_trans] \\
9724      METIS_TAC [lt_le] ]
9725QED
9726
9727(* NOTE: This definition does not assume f is left or right-continuous.
9728   For constant function (\x. c), “(NegInf,PosInf) flat_area_of f” should hold.
9729 *)
9730Definition flat_area_of :
9731   (a,b) flat_area_of (f :extreal -> extreal) <=> a < b /\
9732        ?c. (!x. a < x /\ x < b ==> f x = c) /\
9733            (!x. x < a ==> f x < c) /\ (!x. b < x ==> c < f x)
9734End
9735
9736Definition flat_areas_def :
9737    flat_areas f = {open_interval a b | (a,b) flat_area_of f}
9738End
9739
9740Theorem flat_areas_countable :
9741    !f. (!x y. x <= y ==> f x <= f y) ==> countable (flat_areas f)
9742Proof
9743    rw [flat_areas_def]
9744 >> MATCH_MP_TAC countable_disjoint_open_interval_lemma
9745 >> CONJ_TAC
9746 >- (rw [SUBSET_DEF, flat_area_of] \\
9747     qexistsl_tac [‘a’, ‘b’] >> art [])
9748 >> rw [disjoint_def]
9749 >> rw [DISJOINT_ALT, IN_open_interval]
9750 >> CCONTR_TAC >> fs []
9751 >> Q.PAT_X_ASSUM ‘open_interval _ _ <> open_interval _ _’ MP_TAC >> fs []
9752 >> qmatch_abbrev_tac ‘open_interval a b = open_interval c d’
9753 >> fs [flat_area_of]
9754 >> NTAC 4 (POP_ASSUM K_TAC)
9755 >> simp [open_interval_11]
9756 >> ‘c' = c''’ by METIS_TAC []
9757 >> POP_ASSUM (fs o wrap o SYM)
9758 >> CONJ_TAC (* 2 subgoals *)
9759 >| [ (* goal 1 (of 2) *)
9760      CCONTR_TAC \\
9761     ‘a < c \/ c < a’ by METIS_TAC [lt_total] >| (* 2 subgoals *)
9762      [ (* goal 1.1 (of 2): a_z_c___________/__/
9763                           /   /           b  d *)
9764        MP_TAC (Q.SPECL [‘a’, ‘min b c’] extreal_mean) >> rw [lt_min] \\
9765        CCONTR_TAC >> fs [] \\
9766       ‘f z = c' /\ f z < c'’ by METIS_TAC [] \\
9767        METIS_TAC [lt_le],
9768        (* goal 1.2 (of 2): c_z_a___________/__/
9769                           /   /           d  b *)
9770        MP_TAC (Q.SPECL [‘c’, ‘min a d’] extreal_mean) >> rw [lt_min] \\
9771        CCONTR_TAC >> fs [] \\
9772       ‘f z = c' /\ f z < c'’ by METIS_TAC [] \\
9773        METIS_TAC [lt_le] ],
9774      (* goal 2 (of 2) *)
9775      CCONTR_TAC \\
9776     ‘b < d \/ d < b’ by METIS_TAC [lt_total] >| (* 2 subgoals *)
9777      [ (* goal 2.1 (of 2): a__c___________/___/
9778                           /  /           b z d *)
9779        MP_TAC (Q.SPECL [‘max b c’, ‘d’] extreal_mean) >> rw [max_lt] \\
9780        CCONTR_TAC >> fs [] \\
9781       ‘f z = c' /\ c' < f z’ by METIS_TAC [] \\
9782        METIS_TAC [lt_le],
9783        (* goal 2.2 (of 2): c__a___________/___/
9784                           /  /           d z b *)
9785        MP_TAC (Q.SPECL [‘max a d’, ‘b’] extreal_mean) >> rw [max_lt] \\
9786        CCONTR_TAC >> fs [] \\
9787       ‘f z = c' /\ c' < f z’ by METIS_TAC [] \\
9788        METIS_TAC [lt_le] ] ]
9789QED
9790
9791Theorem countable_flat_area_of :
9792    !f. (!x y. x <= y ==> f x <= f y) ==> countable {(a,b) | (a,b) flat_area_of f}
9793Proof
9794    rpt STRIP_TAC
9795 >> qmatch_abbrev_tac ‘countable s’
9796 >> Suff ‘countable s <=> countable (flat_areas f)’
9797 >- (Rewr' \\
9798     MATCH_MP_TAC flat_areas_countable >> art [])
9799 >> MATCH_MP_TAC CARD_COUNTABLE_CONG
9800 >> rw [cardeq_def, Abbr ‘s’]
9801 >> qabbrev_tac ‘g = \e. open_interval (FST e) (SND e)’
9802 >> Q.EXISTS_TAC ‘g’
9803 >> rw [BIJ_THM, Abbr ‘g’, flat_areas_def]
9804 >- (qexistsl_tac [‘a’, ‘b’] >> simp [])
9805 >> rw [EXISTS_UNIQUE_ALT]
9806 >> Q.EXISTS_TAC ‘(a,b)’
9807 >> simp [FORALL_PROD]
9808 >> qx_genl_tac [‘c’, ‘d’]
9809 >> reverse EQ_TAC >- NTAC 2 (rw [])
9810 >> STRIP_TAC
9811 >> fs [flat_area_of]
9812 >> gs [open_interval_11]
9813QED
9814
9815(* NOTE: Both ‘sup o IMAGE f’ and ‘inf o IMAGE f’ are equivalent here. See
9816  [flat_values_alt] below. The present definition is easier for proving its
9817   countable.
9818 *)
9819Definition flat_values_def :
9820    flat_values f = IMAGE (sup o IMAGE f) (flat_areas f)
9821End
9822
9823Theorem IN_flat_values_lemma[local] :
9824    !a b. a < b /\ (!x. a < x /\ x < b ==> f x = c) ==>
9825          IMAGE f (open_interval a b) = (\y. y = c)
9826Proof
9827    rpt STRIP_TAC
9828 >> rw [Once EXTENSION, IN_open_interval]
9829 >> EQ_TAC >> rw []
9830 >- (FIRST_X_ASSUM MATCH_MP_TAC >> art [])
9831 >> MP_TAC (Q.SPECL [‘a’, ‘b’] extreal_mean) >> rw []
9832 >> Q.EXISTS_TAC ‘z’ >> art []
9833 >> ONCE_REWRITE_TAC [EQ_SYM_EQ]
9834 >> FIRST_X_ASSUM MATCH_MP_TAC >> art []
9835QED
9836
9837Theorem IN_flat_values :
9838    !f z. z IN flat_values f <=>
9839          ?a b. a < b /\ (!x. a < x /\ x < b ==> f x = z) /\
9840               (!x. x < a ==> f x < z) /\ (!x. b < x ==> z < f x)
9841Proof
9842    rw [flat_values_def, flat_areas_def, flat_area_of]
9843 >> EQ_TAC >> rw []
9844 >- (qexistsl_tac [‘a’, ‘b’] \\
9845     Suff ‘IMAGE f (open_interval a b) = (\y. y = c)’
9846     >- (Rewr' >> simp [sup_const]) \\
9847     MATCH_MP_TAC IN_flat_values_lemma >> art [])
9848 >> Q.EXISTS_TAC ‘open_interval a b’
9849 >> Suff ‘IMAGE f (open_interval a b) = (\y. y = z)’
9850 >- (Rewr' >> simp [sup_const] \\
9851     qexistsl_tac [‘a’, ‘b’] >> art [] \\
9852     Q.EXISTS_TAC ‘z’ >> art [])
9853 >> MATCH_MP_TAC IN_flat_values_lemma >> art []
9854QED
9855
9856Theorem flat_values_alt :
9857    !f. flat_values f = IMAGE (inf o IMAGE f) (flat_areas f)
9858Proof
9859    rw [Once EXTENSION, IN_flat_values]
9860 >> EQ_TAC >> rw []
9861 >- (Q.EXISTS_TAC ‘open_interval a b’ \\
9862     Know ‘IMAGE f (open_interval a b) = (\y. y = x)’
9863     >- (MATCH_MP_TAC IN_flat_values_lemma >> art []) >> Rewr' \\
9864     simp [inf_const] \\
9865     rw [flat_areas_def, flat_area_of] \\
9866     qexistsl_tac [‘a’, ‘b’] >> art [] \\
9867     Q.EXISTS_TAC ‘x’ >> art [])
9868 >> fs [flat_areas_def, flat_area_of]
9869 >> qexistsl_tac [‘a’, ‘b’] >> art []
9870 >> Know ‘IMAGE f (open_interval a b) = (\y. y = c)’
9871 >- (MATCH_MP_TAC IN_flat_values_lemma >> art [])
9872 >> Rewr'
9873 >> simp [inf_const]
9874QED
9875
9876Theorem flat_values_countable :
9877    !f. (!x y. x <= y ==> f x <= f y) ==> countable (flat_values f)
9878Proof
9879    rw [flat_values_def]
9880 >> MATCH_MP_TAC COUNTABLE_IMAGE
9881 >> MATCH_MP_TAC flat_areas_countable >> art []
9882QED
9883
9884(* Helper lemmas for later results *)
9885
9886Theorem FN_PLUS_MUL:
9887    ∀f g. (λx. f x * g x)⁺ = (λx. f⁺ x * g⁺ x + f⁻ x * g⁻ x)
9888Proof
9889    rw[FUN_EQ_THM,FN_PLUS_ALT',extreal_max_def,fn_minus_def,extreal_lt_def] >>
9890    Cases_on `0 ≤ f x` >> Cases_on `0 ≤ g x` >> simp[]
9891    >- simp[le_mul] >> fs[GSYM extreal_lt_def]
9892    >- (Cases_on `f x = 0` >> simp[] >> `0 < f x` by simp[lt_le] >> simp[GSYM extreal_not_lt,mul_lt])
9893    >- (Cases_on `g x = 0` >> simp[] >> `0 < g x` by simp[lt_le] >> simp[GSYM extreal_not_lt,mul_lt2])
9894    >- simp[lt_mul_neg,le_lt,neg_mul2]
9895QED
9896
9897Theorem FN_MINUS_MUL:
9898    ∀f g. (λx. f x * g x)⁻ = (λx. f⁺ x * g⁻ x + f⁻ x * g⁺ x)
9899Proof
9900    rw[FUN_EQ_THM,FN_PLUS_ALT',extreal_max_def,fn_minus_def,extreal_lt_def] >>
9901    Cases_on `0 ≤ f x` >> Cases_on `0 ≤ g x` >> simp[]
9902    >- simp[le_mul] >> fs[GSYM extreal_lt_def]
9903    >- (Cases_on `f x = 0` >> simp[] >> `0 < f x` by simp[lt_le] >> simp[mul_lt,mul_rneg])
9904    >- (Cases_on `g x = 0` >> simp[] >> `0 < g x` by simp[lt_le] >> simp[mul_lt2,mul_lneg])
9905    >- (simp[lt_le] >> simp[GSYM extreal_not_lt,lt_mul_neg])
9906QED
9907
9908(* ------------------------------------------------------------------------- *)
9909(* Backwards compatibility: export all theorems moved to extreal_baseTheory  *)
9910(* ------------------------------------------------------------------------- *)
9911
9912val _ = map (fn name => save_thm (name, DB.fetch "extreal_base" name))
9913      ["EXTREAL_ARCH",
9914       "EXTREAL_EQ_LADD",
9915       "EXTREAL_EQ_RADD",
9916       "SIMP_EXTREAL_ARCH", "SIMP_EXTREAL_ARCH_NEG",
9917       "EXTREAL_ARCH_INV", "EXTREAL_ARCH_INV'",
9918       "Q_COUNTABLE", "Q_DENSE_IN_R", "Q_not_infty",
9919       "abs_0",
9920       "abs_abs",
9921       "abs_bounds", "abs_bounds_lt",
9922       "abs_div", "abs_div_normal",
9923       "abs_eq_0",
9924       "abs_gt_0",
9925       "abs_le_0",
9926       "abs_le_half_pow2",
9927       "abs_le_square_plus1",
9928       "abs_max",
9929       "abs_mul",
9930       "abs_neg", "abs_neg'", "abs_neg_eq",
9931       "abs_not_infty",
9932       "abs_not_zero",
9933       "abs_pos",
9934       "abs_pow2",
9935       "abs_pow_le_mono",
9936       "abs_real",
9937       "abs_refl",
9938       "abs_sub", "abs_sub'",
9939       "abs_triangle", "abs_triangle_full",
9940       "abs_triangle_neg", "abs_triangle_neg_full",
9941       "abs_triangle_sub", "abs_triangle_sub_full",
9942       "abs_triangle_sub'", "abs_triangle_sub_full'",
9943       "abs_unbounds",
9944       "add_assoc",
9945       "add_comm", "add_comm_normal",
9946       "add_infty",
9947       "add_ldistrib",
9948       "add_ldistrib_pos", "add_ldistrib_neg",
9949       "add_ldistrib_normal", "add_ldistrib_normal2",
9950       "add_lzero",
9951       "add_not_infty",
9952       "add_pow2", "add_pow2_pos",
9953       "add_rdistrib",
9954       "add_rdistrib_normal", "add_rdistrib_normal2",
9955       "add_rzero",
9956       "add_sub", "add_sub_normal", "add_sub2",
9957       "add2_sub2",
9958       "div_add", "div_add2",
9959       "div_eq_mul_linv",
9960       "div_eq_mul_rinv",
9961       "div_infty",
9962       "div_mul_refl",
9963       "div_not_infty",
9964       "div_one",
9965       "div_refl", "div_refl_pos",
9966       "div_sub",
9967       "entire",
9968       "eq_add_sub_switch",
9969       "eq_neg",
9970       "eq_sub_ladd", "eq_sub_ladd_normal",
9971       "eq_sub_radd",
9972       "eq_sub_switch",
9973       "extreal_11",
9974       "extreal_abs_def",
9975       "extreal_add_def", "extreal_add_eq",
9976       "extreal_ainv_def",
9977       "extreal_cases",
9978       "extreal_double",
9979       "extreal_distinct",
9980       "extreal_div_def", "extreal_div_eq",
9981       "extreal_eq_zero",
9982       "extreal_inv_def", "extreal_inv_eq",
9983       "extreal_le_def", "extreal_le_eq",
9984       "extreal_lt_def", "extreal_lt_eq",
9985       "extreal_mean",
9986       "extreal_max_def",
9987       "extreal_min_def",
9988       "extreal_mul_def",
9989       "extreal_mul_eq",
9990       "extreal_of_num_def",
9991       "extreal_pow_def", "extreal_pow",
9992       "extreal_sqrt_def",
9993       "extreal_sub",
9994       "extreal_sub_add",
9995       "extreal_sub_def", "extreal_sub_eq",
9996       "extreal_not_infty",
9997       "extreal_not_lt",
9998       "fourths_between",
9999       "fourth_cancel",
10000       "half_between",
10001       "half_cancel",
10002       "half_double",
10003       "half_not_infty",
10004       "infty_div",
10005       "infty_pow2",
10006       "inv_1over",
10007       "inv_infty",
10008       "inv_inj",
10009       "inv_inv",
10010       "inv_le_antimono", "inv_le_antimono_imp",
10011       "inv_lt_antimono",
10012       "inv_mul",
10013       "inv_not_infty",
10014       "inv_one",
10015       "inv_pos", "inv_pos'", "inv_pos_eq",
10016       "ldiv_eq",
10017       "ldiv_le_imp",
10018       "le_01", "le_02",
10019       "le_abs",
10020       "le_abs_bounds",
10021       "le_add", "le_add2",
10022       "le_add_neg",
10023       "le_addl", "le_addl_imp",
10024       "le_addr", "le_addr_imp",
10025       "le_antisym",
10026       "le_div",
10027       "le_infty",
10028       "le_inv",
10029       "le_ladd", "le_ladd_imp",
10030       "le_lsub_imp",
10031       "le_lt",
10032       "le_ldiv",
10033       "le_lmul", "le_lmul_imp",
10034       "le_lneg",
10035       "le_max", "le_max1", "le_max2",
10036       "le_min",
10037       "le_mul", "le_mul_neg",
10038       "le_mul2",
10039       "le_neg",
10040       "le_not_infty",
10041       "le_num",
10042       "le_pow2",
10043       "le_radd", "le_radd_imp",
10044       "le_refl",
10045       "le_rmul", "le_rmul_imp",
10046       "le_rdiv",
10047       "le_rsub_imp",
10048       "le_sub_eq", "le_sub_eq2",
10049       "le_sub_imp", "le_sub_imp2",
10050       "le_total",
10051       "le_trans",
10052       "let_add", "let_add2", "let_add2_alt",
10053       "let_antisym",
10054       "let_mul",
10055       "let_total",
10056       "let_trans",
10057       "linv_uniq",
10058       "lt_01", "lt_02", "lt_10",
10059       "lt_add", "lt_add2",
10060       "lt_add_neg",
10061       "lt_abs_bounds",
10062       "lt_addl",
10063       "lt_addr", "lt_addr_imp",
10064       "lt_antisym",
10065       "lt_div",
10066       "lt_imp_le",
10067       "lt_imp_ne",
10068       "lt_infty",
10069       "lt_ladd",
10070       "lt_ldiv",
10071       "lt_le",
10072       "lt_lmul", "lt_lmul_imp",
10073       "lt_lsub_imp",
10074       "lt_max",
10075       "lt_max_between",
10076       "lt_mul", "lt_mul_neg",
10077       "lt_mul2",
10078       "lt_neg",
10079       "lt_radd",
10080       "lt_rdiv", "lt_rdiv_neg",
10081       "lt_refl",
10082       "lt_rmul", "lt_rmul_imp",
10083       "lt_rsub_imp",
10084       "lt_sub", "lt_sub'",
10085       "lt_sub_imp", "lt_sub_imp'", "lt_sub_imp2",
10086       "lt_total",
10087       "lt_trans",
10088       "lte_add",
10089       "lte_mul",
10090       "lte_total",
10091       "lte_trans",
10092       "max_comm",
10093       "max_infty",
10094       "max_le", "max_le2_imp",
10095       "max_reduce",
10096       "max_refl",
10097       "min_comm",
10098       "min_infty",
10099       "min_le", "min_le1", "min_le2", "min_le2_imp",
10100       "min_le_between",
10101       "min_reduce",
10102       "min_refl",
10103       "mul_assoc",
10104       "mul_comm",
10105       "mul_div_refl",
10106       "mul_infty", "mul_infty'",
10107       "mul_lcancel",
10108       "mul_le", "mul_le2",
10109       "mul_let",
10110       "mul_linv", "mul_linv_pos",
10111       "mul_lneg",
10112       "mul_lt", "mul_lt2",
10113       "mul_lte",
10114       "mul_lone",
10115       "mul_lposinf",
10116       "mul_lzero",
10117       "mul_not_infty", "mul_not_infty2",
10118       "mul_rcancel",
10119       "mul_rneg",
10120       "mul_rone",
10121       "mul_rposinf",
10122       "mul_rzero",
10123       "ne_01", "ne_02",
10124       "neg_0",
10125       "neg_add",
10126       "neg_eq0",
10127       "neg_minus1",
10128       "neg_mul2",
10129       "neg_sub",
10130       "neg_neg",
10131       "neg_not_posinf",
10132       "normal_0", "normal_1",
10133       "normal_inv_eq",
10134       "normal_real_set",
10135       "num_lt_infty",
10136       "num_not_infty",
10137       "one_pow",
10138       "pos_not_neginf",
10139       "pow_0", "pow_1", "pow_2",
10140       "pow_2_abs",
10141       "pow_add",
10142       "pow_div",
10143       "pow_eq",
10144       "pow_inv",
10145       "pow_le", "pow_le_full",
10146       "pow_le_mono",
10147       "pow_lt", "pow_lt2",
10148       "pow_minus1",
10149       "pow_mul",
10150       "pow_neg_odd",
10151       "pow_not_infty",
10152       "pow_pos_even",
10153       "pow_pos_le",
10154       "pow_pos_lt",
10155       "pow_pow",
10156       "pow_zero", "pow_zero_imp",
10157       "pow2_le_eq",
10158       "pow2_sqrt",
10159       "quotient_normal",
10160       "real_0",
10161       "real_def",
10162       "real_normal",
10163       "rdiv_eq",
10164       "real_set_def", "real_set_empty",
10165       "rinv_uniq",
10166       "sqrt_0", "sqrt_1",
10167       "sqrt_le_n",
10168       "sqrt_le_x",
10169       "sqrt_mono_le",
10170       "sqrt_mul",
10171       "sqrt_pos_le",
10172       "sqrt_pos_lt",
10173       "sqrt_pos_ne",
10174       "sqrt_pow2",
10175       "sub_0",
10176       "sub_add", "sub_add_normal", "sub_add2",
10177       "sub_eq_0",
10178       "sub_infty",
10179       "sub_ldistrib",
10180       "sub_lzero",
10181       "sub_le_eq", "sub_le_eq2",
10182       "sub_le_imp", "sub_le_imp2",
10183       "sub_le_switch", "sub_le_switch2",
10184       "sub_le_zero",
10185       "sub_lneg",
10186       "sub_lt_eq",
10187       "sub_lt_imp", "sub_lt_imp2",
10188       "sub_lt_zero", "sub_lt_zero2",
10189       "sub_not_infty",
10190       "sub_pow2",
10191       "sub_rdistrib",
10192       "sub_refl",
10193       "sub_rneg",
10194       "sub_rzero",
10195       "sub_zero_le",
10196       "sub_zero_lt", "sub_zero_lt2",
10197       "thirds_between",
10198       "third_cancel",
10199       "normal_real",
10200       "x_half_half",
10201       "zero_div",
10202       "zero_pow"];
10203
10204(* References:
10205
10206  [1] Schilling, R.L.: Measures, Integrals and Martingales (2nd Edition).
10207      Cambridge University Press (2017).
10208  [2] Fichtenholz, G.M.: Differential- und Integralrechnung (Differential and
10209      Integral Calculus), Vol.2. (1967).
10210  [3] Harrison, J.: Constructing the real numbers in HOL. TPHOLs. (1992).
10211  [4] Wikipedia: https://en.wikipedia.org/wiki/Limit_superior_and_limit_inferior
10212 *)