1 (* ========================================================================= *)
2 (* More basic properties of the reals. *)
4 (* John Harrison, University of Cambridge Computer Laboratory *)
6 (* (c) Copyright, University of Cambridge 1998 *)
7 (* (c) Copyright, John Harrison 1998-2007 *)
8 (* (c) Copyright, Valentina Bruno 2010 *)
9 (* ========================================================================= *)
11 needs "realarith.ml";;
13 (* ------------------------------------------------------------------------- *)
14 (* Additional commutativity properties of the inclusion map. *)
15 (* ------------------------------------------------------------------------- *)
17 let REAL_OF_NUM_LT = prove
18 (`!m n. &m < &n <=> m < n`,
19 REWRITE_TAC[real_lt; GSYM NOT_LE; REAL_OF_NUM_LE]);;
21 let REAL_OF_NUM_GE = prove
22 (`!m n. &m >= &n <=> m >= n`,
23 REWRITE_TAC[GE; real_ge; REAL_OF_NUM_LE]);;
25 let REAL_OF_NUM_GT = prove
26 (`!m n. &m > &n <=> m > n`,
27 REWRITE_TAC[GT; real_gt; REAL_OF_NUM_LT]);;
29 let REAL_OF_NUM_MAX = prove
30 (`!m n. max (&m) (&n) = &(MAX m n)`,
31 REWRITE_TAC[REAL_OF_NUM_LE; MAX; real_max; GSYM COND_RAND]);;
33 let REAL_OF_NUM_MIN = prove
34 (`!m n. min (&m) (&n) = &(MIN m n)`,
35 REWRITE_TAC[REAL_OF_NUM_LE; MIN; real_min; GSYM COND_RAND]);;
37 let REAL_OF_NUM_SUC = prove
38 (`!n. &n + &1 = &(SUC n)`,
39 REWRITE_TAC[ADD1; REAL_OF_NUM_ADD]);;
41 let REAL_OF_NUM_SUB = prove
42 (`!m n. m <= n ==> (&n - &m = &(n - m))`,
43 REPEAT GEN_TAC THEN REWRITE_TAC[LE_EXISTS] THEN
44 STRIP_TAC THEN ASM_REWRITE_TAC[ADD_SUB2] THEN
45 REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN
46 ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN
47 REWRITE_TAC[real_sub; GSYM REAL_ADD_ASSOC] THEN
48 MESON_TAC[REAL_ADD_LINV; REAL_ADD_SYM; REAL_ADD_LID]);;
50 (* ------------------------------------------------------------------------- *)
51 (* A few theorems we need to prove explicitly for later. *)
52 (* ------------------------------------------------------------------------- *)
54 let REAL_MUL_AC = prove
56 ((m * n) * p = m * (n * p)) /\
57 (m * (n * p) = n * (m * p))`,
58 REWRITE_TAC[REAL_MUL_ASSOC; EQT_INTRO(SPEC_ALL REAL_MUL_SYM)] THEN
59 AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_ACCEPT_TAC REAL_MUL_SYM);;
61 let REAL_ADD_RDISTRIB = prove
62 (`!x y z. (x + y) * z = x * z + y * z`,
63 MESON_TAC[REAL_MUL_SYM; REAL_ADD_LDISTRIB]);;
65 let REAL_LT_LADD_IMP = prove
66 (`!x y z. y < z ==> x + y < x + z`,
67 REPEAT GEN_TAC THEN CONV_TAC CONTRAPOS_CONV THEN
68 REWRITE_TAC[real_lt] THEN
69 DISCH_THEN(MP_TAC o MATCH_MP REAL_LE_LADD_IMP) THEN
70 DISCH_THEN(MP_TAC o SPEC `--x`) THEN
71 REWRITE_TAC[REAL_ADD_ASSOC; REAL_ADD_LINV; REAL_ADD_LID]);;
73 let REAL_LT_MUL = prove
74 (`!x y. &0 < x /\ &0 < y ==> &0 < x * y`,
75 REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LT_LE] THEN
76 CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN
77 STRIP_TAC THEN ASM_REWRITE_TAC[REAL_ENTIRE] THEN
78 MATCH_MP_TAC REAL_LE_MUL THEN ASM_REWRITE_TAC[]);;
80 (* ------------------------------------------------------------------------- *)
81 (* Tactic version of REAL_ARITH. *)
82 (* ------------------------------------------------------------------------- *)
84 let REAL_ARITH_TAC = CONV_TAC REAL_ARITH;;
86 (* ------------------------------------------------------------------------- *)
87 (* Prove all the linear theorems we can blow away automatically. *)
88 (* ------------------------------------------------------------------------- *)
90 let REAL_EQ_ADD_LCANCEL_0 = prove
91 (`!x y. (x + y = x) <=> (y = &0)`,
94 let REAL_EQ_ADD_RCANCEL_0 = prove
95 (`!x y. (x + y = y) <=> (x = &0)`,
98 let REAL_LNEG_UNIQ = prove
99 (`!x y. (x + y = &0) <=> (x = --y)`,
102 let REAL_RNEG_UNIQ = prove
103 (`!x y. (x + y = &0) <=> (y = --x)`,
106 let REAL_NEG_LMUL = prove
107 (`!x y. --(x * y) = (--x) * y`,
110 let REAL_NEG_RMUL = prove
111 (`!x y. --(x * y) = x * (--y)`,
114 let REAL_NEGNEG = prove
118 let REAL_NEG_MUL2 = prove
119 (`!x y. (--x) * (--y) = x * y`,
122 let REAL_LT_LADD = prove
123 (`!x y z. (x + y) < (x + z) <=> y < z`,
126 let REAL_LT_RADD = prove
127 (`!x y z. (x + z) < (y + z) <=> x < y`,
130 let REAL_LT_ANTISYM = prove
131 (`!x y. ~(x < y /\ y < x)`,
134 let REAL_LT_GT = prove
135 (`!x y. x < y ==> ~(y < x)`,
138 let REAL_NOT_EQ = prove
139 (`!x y. ~(x = y) <=> x < y \/ y < x`,
142 let REAL_NOT_LE = prove
143 (`!x y. ~(x <= y) <=> y < x`,
146 let REAL_LET_ANTISYM = prove
147 (`!x y. ~(x <= y /\ y < x)`,
150 let REAL_NEG_LT0 = prove
151 (`!x. (--x) < &0 <=> &0 < x`,
154 let REAL_NEG_GT0 = prove
155 (`!x. &0 < (--x) <=> x < &0`,
158 let REAL_NEG_LE0 = prove
159 (`!x. (--x) <= &0 <=> &0 <= x`,
162 let REAL_NEG_GE0 = prove
163 (`!x. &0 <= (--x) <=> x <= &0`,
166 let REAL_LT_TOTAL = prove
167 (`!x y. (x = y) \/ x < y \/ y < x`,
170 let REAL_LT_NEGTOTAL = prove
171 (`!x. (x = &0) \/ (&0 < x) \/ (&0 < --x)`,
174 let REAL_LE_01 = prove
178 let REAL_LT_01 = prove
182 let REAL_LE_LADD = prove
183 (`!x y z. (x + y) <= (x + z) <=> y <= z`,
186 let REAL_LE_RADD = prove
187 (`!x y z. (x + z) <= (y + z) <=> x <= y`,
190 let REAL_LT_ADD2 = prove
191 (`!w x y z. w < x /\ y < z ==> (w + y) < (x + z)`,
194 let REAL_LE_ADD2 = prove
195 (`!w x y z. w <= x /\ y <= z ==> (w + y) <= (x + z)`,
198 let REAL_LT_LNEG = prove
199 (`!x y. --x < y <=> &0 < x + y`,
200 REWRITE_TAC[real_lt; REAL_LE_RNEG; REAL_ADD_AC]);;
202 let REAL_LT_RNEG = prove
203 (`!x y. x < --y <=> x + y < &0`,
204 REWRITE_TAC[real_lt; REAL_LE_LNEG; REAL_ADD_AC]);;
206 let REAL_LT_ADDNEG = prove
207 (`!x y z. y < (x + (--z)) <=> (y + z) < x`,
210 let REAL_LT_ADDNEG2 = prove
211 (`!x y z. (x + (--y)) < z <=> x < (z + y)`,
214 let REAL_LT_ADD1 = prove
215 (`!x y. x <= y ==> x < (y + &1)`,
218 let REAL_SUB_ADD = prove
219 (`!x y. (x - y) + y = x`,
222 let REAL_SUB_ADD2 = prove
223 (`!x y. y + (x - y) = x`,
226 let REAL_SUB_REFL = prove
230 let REAL_LE_DOUBLE = prove
231 (`!x. &0 <= x + x <=> &0 <= x`,
234 let REAL_LE_NEGL = prove
235 (`!x. (--x <= x) <=> (&0 <= x)`,
238 let REAL_LE_NEGR = prove
239 (`!x. (x <= --x) <=> (x <= &0)`,
242 let REAL_NEG_EQ_0 = prove
243 (`!x. (--x = &0) <=> (x = &0)`,
246 let REAL_ADD_SUB = prove
247 (`!x y. (x + y) - x = y`,
250 let REAL_NEG_EQ = prove
251 (`!x y. (--x = y) <=> (x = --y)`,
254 let REAL_NEG_MINUS1 = prove
255 (`!x. --x = (--(&1)) * x`,
258 let REAL_LT_IMP_NE = prove
259 (`!x y. x < y ==> ~(x = y)`,
262 let REAL_LE_ADDR = prove
263 (`!x y. x <= x + y <=> &0 <= y`,
266 let REAL_LE_ADDL = prove
267 (`!x y. y <= x + y <=> &0 <= x`,
270 let REAL_LT_ADDR = prove
271 (`!x y. x < x + y <=> &0 < y`,
274 let REAL_LT_ADDL = prove
275 (`!x y. y < x + y <=> &0 < x`,
278 let REAL_SUB_SUB = prove
279 (`!x y. (x - y) - x = --y`,
282 let REAL_LT_ADD_SUB = prove
283 (`!x y z. (x + y) < z <=> x < (z - y)`,
286 let REAL_LT_SUB_RADD = prove
287 (`!x y z. (x - y) < z <=> x < z + y`,
290 let REAL_LT_SUB_LADD = prove
291 (`!x y z. x < (y - z) <=> (x + z) < y`,
294 let REAL_LE_SUB_LADD = prove
295 (`!x y z. x <= (y - z) <=> (x + z) <= y`,
298 let REAL_LE_SUB_RADD = prove
299 (`!x y z. (x - y) <= z <=> x <= z + y`,
302 let REAL_LT_NEG = prove
303 (`!x y. --x < --y <=> y < x`,
306 let REAL_LE_NEG = prove
307 (`!x y. --x <= --y <=> y <= x`,
310 let REAL_ADD2_SUB2 = prove
311 (`!a b c d. (a + b) - (c + d) = (a - c) + (b - d)`,
314 let REAL_SUB_LZERO = prove
318 let REAL_SUB_RZERO = prove
322 let REAL_LET_ADD2 = prove
323 (`!w x y z. w <= x /\ y < z ==> (w + y) < (x + z)`,
326 let REAL_LTE_ADD2 = prove
327 (`!w x y z. w < x /\ y <= z ==> w + y < x + z`,
330 let REAL_SUB_LNEG = prove
331 (`!x y. (--x) - y = --(x + y)`,
334 let REAL_SUB_RNEG = prove
335 (`!x y. x - (--y) = x + y`,
338 let REAL_SUB_NEG2 = prove
339 (`!x y. (--x) - (--y) = y - x`,
342 let REAL_SUB_TRIANGLE = prove
343 (`!a b c. (a - b) + (b - c) = a - c`,
346 let REAL_EQ_SUB_LADD = prove
347 (`!x y z. (x = y - z) <=> (x + z = y)`,
350 let REAL_EQ_SUB_RADD = prove
351 (`!x y z. (x - y = z) <=> (x = z + y)`,
354 let REAL_SUB_SUB2 = prove
355 (`!x y. x - (x - y) = y`,
358 let REAL_ADD_SUB2 = prove
359 (`!x y. x - (x + y) = --y`,
362 let REAL_EQ_IMP_LE = prove
363 (`!x y. (x = y) ==> x <= y`,
366 let REAL_POS_NZ = prove
367 (`!x. &0 < x ==> ~(x = &0)`,
370 let REAL_DIFFSQ = prove
371 (`!x y. (x + y) * (x - y) = (x * x) - (y * y)`,
374 let REAL_EQ_NEG2 = prove
375 (`!x y. (--x = --y) <=> (x = y)`,
378 let REAL_LT_NEG2 = prove
379 (`!x y. --x < --y <=> y < x`,
382 let REAL_SUB_LDISTRIB = prove
383 (`!x y z. x * (y - z) = x * y - x * z`,
386 let REAL_SUB_RDISTRIB = prove
387 (`!x y z. (x - y) * z = x * z - y * z`,
390 (* ------------------------------------------------------------------------- *)
391 (* Theorems about "abs". *)
392 (* ------------------------------------------------------------------------- *)
394 let REAL_ABS_ZERO = prove
395 (`!x. (abs(x) = &0) <=> (x = &0)`,
398 let REAL_ABS_0 = prove
402 let REAL_ABS_1 = prove
406 let REAL_ABS_TRIANGLE = prove
407 (`!x y. abs(x + y) <= abs(x) + abs(y)`,
410 let REAL_ABS_TRIANGLE_LE = prove
411 (`!x y z.abs(x) + abs(y - x) <= z ==> abs(y) <= z`,
414 let REAL_ABS_TRIANGLE_LT = prove
415 (`!x y z.abs(x) + abs(y - x) < z ==> abs(y) < z`,
418 let REAL_ABS_POS = prove
422 let REAL_ABS_SUB = prove
423 (`!x y. abs(x - y) = abs(y - x)`,
426 let REAL_ABS_NZ = prove
427 (`!x. ~(x = &0) <=> &0 < abs(x)`,
430 let REAL_ABS_ABS = prove
431 (`!x. abs(abs(x)) = abs(x)`,
434 let REAL_ABS_LE = prove
438 let REAL_ABS_REFL = prove
439 (`!x. (abs(x) = x) <=> &0 <= x`,
442 let REAL_ABS_BETWEEN = prove
443 (`!x y d. &0 < d /\ ((x - d) < y) /\ (y < (x + d)) <=> abs(y - x) < d`,
446 let REAL_ABS_BOUND = prove
447 (`!x y d. abs(x - y) < d ==> y < (x + d)`,
450 let REAL_ABS_STILLNZ = prove
451 (`!x y. abs(x - y) < abs(y) ==> ~(x = &0)`,
454 let REAL_ABS_CASES = prove
455 (`!x. (x = &0) \/ &0 < abs(x)`,
458 let REAL_ABS_BETWEEN1 = prove
459 (`!x y z. x < z /\ (abs(y - x)) < (z - x) ==> y < z`,
462 let REAL_ABS_SIGN = prove
463 (`!x y. abs(x - y) < y ==> &0 < x`,
466 let REAL_ABS_SIGN2 = prove
467 (`!x y. abs(x - y) < --y ==> x < &0`,
470 let REAL_ABS_CIRCLE = prove
471 (`!x y h. abs(h) < (abs(y) - abs(x)) ==> abs(x + h) < abs(y)`,
474 let REAL_SUB_ABS = prove
475 (`!x y. (abs(x) - abs(y)) <= abs(x - y)`,
478 let REAL_ABS_SUB_ABS = prove
479 (`!x y. abs(abs(x) - abs(y)) <= abs(x - y)`,
482 let REAL_ABS_BETWEEN2 = prove
483 (`!x0 x y0 y. x0 < y0 /\ &2 * abs(x - x0) < (y0 - x0) /\
484 &2 * abs(y - y0) < (y0 - x0)
488 let REAL_ABS_BOUNDS = prove
489 (`!x k. abs(x) <= k <=> --k <= x /\ x <= k`,
492 let REAL_BOUNDS_LE = prove
493 (`!x k. --k <= x /\ x <= k <=> abs(x) <= k`,
496 let REAL_BOUNDS_LT = prove
497 (`!x k. --k < x /\ x < k <=> abs(x) < k`,
500 (* ------------------------------------------------------------------------- *)
501 (* Theorems about max and min. *)
502 (* ------------------------------------------------------------------------- *)
504 let REAL_MIN_MAX = prove
505 (`!x y. min x y = --(max (--x) (--y))`,
508 let REAL_MAX_MIN = prove
509 (`!x y. max x y = --(min (--x) (--y))`,
512 let REAL_MAX_MAX = prove
513 (`!x y. x <= max x y /\ y <= max x y`,
516 let REAL_MIN_MIN = prove
517 (`!x y. min x y <= x /\ min x y <= y`,
520 let REAL_MAX_SYM = prove
521 (`!x y. max x y = max y x`,
524 let REAL_MIN_SYM = prove
525 (`!x y. min x y = min y x`,
528 let REAL_LE_MAX = prove
529 (`!x y z. z <= max x y <=> z <= x \/ z <= y`,
532 let REAL_LE_MIN = prove
533 (`!x y z. z <= min x y <=> z <= x /\ z <= y`,
536 let REAL_LT_MAX = prove
537 (`!x y z. z < max x y <=> z < x \/ z < y`,
540 let REAL_LT_MIN = prove
541 (`!x y z. z < min x y <=> z < x /\ z < y`,
544 let REAL_MAX_LE = prove
545 (`!x y z. max x y <= z <=> x <= z /\ y <= z`,
548 let REAL_MIN_LE = prove
549 (`!x y z. min x y <= z <=> x <= z \/ y <= z`,
552 let REAL_MAX_LT = prove
553 (`!x y z. max x y < z <=> x < z /\ y < z`,
556 let REAL_MIN_LT = prove
557 (`!x y z. min x y < z <=> x < z \/ y < z`,
560 let REAL_MAX_ASSOC = prove
561 (`!x y z. max x (max y z) = max (max x y) z`,
564 let REAL_MIN_ASSOC = prove
565 (`!x y z. min x (min y z) = min (min x y) z`,
568 let REAL_MAX_ACI = prove
569 (`(max x y = max y x) /\
570 (max (max x y) z = max x (max y z)) /\
571 (max x (max y z) = max y (max x z)) /\
573 (max x (max x y) = max x y)`,
576 let REAL_MIN_ACI = prove
577 (`(min x y = min y x) /\
578 (min (min x y) z = min x (min y z)) /\
579 (min x (min y z) = min y (min x z)) /\
581 (min x (min x y) = min x y)`,
584 (* ------------------------------------------------------------------------- *)
585 (* To simplify backchaining, just as in the natural number case. *)
586 (* ------------------------------------------------------------------------- *)
589 let pth = PURE_ONCE_REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS in
590 fun th -> GEN_ALL(MATCH_MP pth (SPEC_ALL th));;
593 let pth = PURE_ONCE_REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS in
594 fun th -> GEN_ALL(MATCH_MP pth (SPEC_ALL th));;
596 (* ------------------------------------------------------------------------- *)
597 (* Now a bit of nonlinear stuff. *)
598 (* ------------------------------------------------------------------------- *)
600 let REAL_ABS_MUL = prove
601 (`!x y. abs(x * y) = abs(x) * abs(y)`,
603 DISJ_CASES_TAC (SPEC `x:real` REAL_LE_NEGTOTAL) THENL
605 GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [GSYM REAL_ABS_NEG]] THEN
606 (DISJ_CASES_TAC (SPEC `y:real` REAL_LE_NEGTOTAL) THENL
608 GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM REAL_ABS_NEG]]) THEN
609 ASSUM_LIST(MP_TAC o MATCH_MP REAL_LE_MUL o end_itlist CONJ o rev) THEN
610 REWRITE_TAC[REAL_MUL_LNEG; REAL_MUL_RNEG; REAL_NEG_NEG] THEN DISCH_TAC THENL
612 GEN_REWRITE_TAC LAND_CONV [GSYM REAL_ABS_NEG];
613 GEN_REWRITE_TAC LAND_CONV [GSYM REAL_ABS_NEG];
615 ASM_REWRITE_TAC[real_abs; REAL_MUL_LNEG; REAL_MUL_RNEG; REAL_NEG_NEG]);;
617 let REAL_POW_LE = prove
618 (`!x n. &0 <= x ==> &0 <= x pow n`,
619 REPEAT STRIP_TAC THEN SPEC_TAC(`n:num`,`n:num`) THEN
620 INDUCT_TAC THEN REWRITE_TAC[real_pow; REAL_POS] THEN
621 MATCH_MP_TAC REAL_LE_MUL THEN ASM_REWRITE_TAC[]);;
623 let REAL_POW_LT = prove
624 (`!x n. &0 < x ==> &0 < x pow n`,
625 REPEAT STRIP_TAC THEN SPEC_TAC(`n:num`,`n:num`) THEN
626 INDUCT_TAC THEN REWRITE_TAC[real_pow; REAL_LT_01] THEN
627 MATCH_MP_TAC REAL_LT_MUL THEN ASM_REWRITE_TAC[]);;
629 let REAL_ABS_POW = prove
630 (`!x n. abs(x pow n) = abs(x) pow n`,
631 GEN_TAC THEN INDUCT_TAC THEN
632 ASM_REWRITE_TAC[real_pow; REAL_ABS_NUM; REAL_ABS_MUL]);;
634 let REAL_LE_LMUL = prove
635 (`!x y z. &0 <= x /\ y <= z ==> x * y <= x * z`,
636 ONCE_REWRITE_TAC[REAL_ARITH `x <= y <=> &0 <= y - x`] THEN
637 REWRITE_TAC[GSYM REAL_SUB_LDISTRIB; REAL_SUB_RZERO; REAL_LE_MUL]);;
639 let REAL_LE_RMUL = prove
640 (`!x y z. x <= y /\ &0 <= z ==> x * z <= y * z`,
641 MESON_TAC[REAL_MUL_SYM; REAL_LE_LMUL]);;
643 let REAL_LT_LMUL = prove
644 (`!x y z. &0 < x /\ y < z ==> x * y < x * z`,
645 ONCE_REWRITE_TAC[REAL_ARITH `x < y <=> &0 < y - x`] THEN
646 REWRITE_TAC[GSYM REAL_SUB_LDISTRIB; REAL_SUB_RZERO; REAL_LT_MUL]);;
648 let REAL_LT_RMUL = prove
649 (`!x y z. x < y /\ &0 < z ==> x * z < y * z`,
650 MESON_TAC[REAL_MUL_SYM; REAL_LT_LMUL]);;
652 let REAL_EQ_MUL_LCANCEL = prove
653 (`!x y z. (x * y = x * z) <=> (x = &0) \/ (y = z)`,
655 ONCE_REWRITE_TAC[REAL_ARITH `(x = y) <=> (x - y = &0)`] THEN
656 REWRITE_TAC[GSYM REAL_SUB_LDISTRIB; REAL_ENTIRE; REAL_SUB_RZERO]);;
658 let REAL_EQ_MUL_RCANCEL = prove
659 (`!x y z. (x * z = y * z) <=> (x = y) \/ (z = &0)`,
660 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
661 REWRITE_TAC[REAL_EQ_MUL_LCANCEL] THEN
664 let REAL_MUL_LINV_UNIQ = prove
665 (`!x y. (x * y = &1) ==> (inv(y) = x)`,
667 ASM_CASES_TAC `y = &0` THEN
668 ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_OF_NUM_EQ; ARITH_EQ] THEN
669 FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP REAL_MUL_LINV) THEN
670 ASM_REWRITE_TAC[REAL_EQ_MUL_RCANCEL] THEN
671 DISCH_THEN(ACCEPT_TAC o SYM));;
673 let REAL_MUL_RINV_UNIQ = prove
674 (`!x y. (x * y = &1) ==> (inv(x) = y)`,
675 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
676 MATCH_ACCEPT_TAC REAL_MUL_LINV_UNIQ);;
678 let REAL_INV_INV = prove
679 (`!x. inv(inv x) = x`,
680 GEN_TAC THEN ASM_CASES_TAC `x = &0` THEN
681 ASM_REWRITE_TAC[REAL_INV_0] THEN
682 MATCH_MP_TAC REAL_MUL_RINV_UNIQ THEN
683 MATCH_MP_TAC REAL_MUL_LINV THEN
686 let REAL_EQ_INV2 = prove
687 (`!x y. inv(x) = inv(y) <=> x = y`,
688 MESON_TAC[REAL_INV_INV]);;
690 let REAL_INV_EQ_0 = prove
691 (`!x. inv(x) = &0 <=> x = &0`,
692 GEN_TAC THEN EQ_TAC THEN DISCH_TAC THEN ASM_REWRITE_TAC[REAL_INV_0] THEN
693 ONCE_REWRITE_TAC[GSYM REAL_INV_INV] THEN ASM_REWRITE_TAC[REAL_INV_0]);;
695 let REAL_LT_INV = prove
696 (`!x. &0 < x ==> &0 < inv(x)`,
698 REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC (SPEC `inv(x)` REAL_LT_NEGTOTAL) THEN
699 ASM_REWRITE_TAC[] THENL
700 [RULE_ASSUM_TAC(REWRITE_RULE[REAL_INV_EQ_0]) THEN ASM_REWRITE_TAC[];
701 DISCH_TAC THEN SUBGOAL_THEN `&0 < --(inv x) * x` MP_TAC THENL
702 [MATCH_MP_TAC REAL_LT_MUL THEN ASM_REWRITE_TAC[];
703 REWRITE_TAC[REAL_MUL_LNEG]]] THEN
704 SUBGOAL_THEN `inv(x) * x = &1` SUBST1_TAC THENL
705 [MATCH_MP_TAC REAL_MUL_LINV THEN
706 UNDISCH_TAC `&0 < x` THEN REAL_ARITH_TAC;
707 REWRITE_TAC[REAL_LT_RNEG; REAL_ADD_LID; REAL_OF_NUM_LT; ARITH]]);;
709 let REAL_LT_INV_EQ = prove
710 (`!x. &0 < inv x <=> &0 < x`,
711 GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[REAL_LT_INV] THEN
712 GEN_REWRITE_TAC (funpow 2 RAND_CONV) [GSYM REAL_INV_INV] THEN
713 REWRITE_TAC[REAL_LT_INV]);;
715 let REAL_INV_NEG = prove
716 (`!x. inv(--x) = --(inv x)`,
717 GEN_TAC THEN ASM_CASES_TAC `x = &0` THEN
718 ASM_REWRITE_TAC[REAL_NEG_0; REAL_INV_0] THEN
719 MATCH_MP_TAC REAL_MUL_LINV_UNIQ THEN
720 REWRITE_TAC[REAL_MUL_LNEG; REAL_MUL_RNEG; REAL_NEG_NEG] THEN
721 MATCH_MP_TAC REAL_MUL_LINV THEN ASM_REWRITE_TAC[]);;
723 let REAL_LE_INV_EQ = prove
724 (`!x. &0 <= inv x <=> &0 <= x`,
725 REWRITE_TAC[REAL_LE_LT; REAL_LT_INV_EQ; REAL_INV_EQ_0] THEN
726 MESON_TAC[REAL_INV_EQ_0]);;
728 let REAL_LE_INV = prove
729 (`!x. &0 <= x ==> &0 <= inv(x)`,
730 REWRITE_TAC[REAL_LE_INV_EQ]);;
732 let REAL_MUL_RINV = prove
733 (`!x. ~(x = &0) ==> (x * inv(x) = &1)`,
734 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
735 REWRITE_TAC[REAL_MUL_LINV]);;
737 let REAL_INV_1 = prove
739 MATCH_MP_TAC REAL_MUL_RINV_UNIQ THEN
740 REWRITE_TAC[REAL_MUL_LID]);;
742 let REAL_INV_EQ_1 = prove
743 (`!x. inv(x) = &1 <=> x = &1`,
744 MESON_TAC[REAL_INV_INV; REAL_INV_1]);;
746 let REAL_DIV_1 = prove
748 REWRITE_TAC[real_div; REAL_INV_1; REAL_MUL_RID]);;
750 let REAL_DIV_REFL = prove
751 (`!x. ~(x = &0) ==> (x / x = &1)`,
752 GEN_TAC THEN REWRITE_TAC[real_div; REAL_MUL_RINV]);;
754 let REAL_DIV_RMUL = prove
755 (`!x y. ~(y = &0) ==> ((x / y) * y = x)`,
756 SIMP_TAC[real_div; GSYM REAL_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_RID]);;
758 let REAL_DIV_LMUL = prove
759 (`!x y. ~(y = &0) ==> (y * (x / y) = x)`,
760 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[REAL_DIV_RMUL]);;
762 let REAL_ABS_INV = prove
763 (`!x. abs(inv x) = inv(abs x)`,
764 GEN_TAC THEN CONV_TAC SYM_CONV THEN
765 ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[REAL_INV_0; REAL_ABS_0] THEN
766 MATCH_MP_TAC REAL_MUL_RINV_UNIQ THEN
767 REWRITE_TAC[GSYM REAL_ABS_MUL] THEN
768 POP_ASSUM(SUBST1_TAC o MATCH_MP REAL_MUL_RINV) THEN
769 REWRITE_TAC[REAL_ABS_1]);;
771 let REAL_ABS_DIV = prove
772 (`!x y. abs(x / y) = abs(x) / abs(y)`,
773 REWRITE_TAC[real_div; REAL_ABS_INV; REAL_ABS_MUL]);;
775 let REAL_INV_MUL = prove
776 (`!x y. inv(x * y) = inv(x) * inv(y)`,
778 MAP_EVERY ASM_CASES_TAC [`x = &0`; `y = &0`] THEN
779 ASM_REWRITE_TAC[REAL_INV_0; REAL_MUL_LZERO; REAL_MUL_RZERO] THEN
780 MATCH_MP_TAC REAL_MUL_LINV_UNIQ THEN
781 ONCE_REWRITE_TAC[AC REAL_MUL_AC `(a * b) * (c * d) = (a * c) * (b * d)`] THEN
782 EVERY_ASSUM(SUBST1_TAC o MATCH_MP REAL_MUL_LINV) THEN
783 REWRITE_TAC[REAL_MUL_LID]);;
785 let REAL_INV_DIV = prove
786 (`!x y. inv(x / y) = y / x`,
787 REWRITE_TAC[real_div; REAL_INV_INV; REAL_INV_MUL] THEN
788 MATCH_ACCEPT_TAC REAL_MUL_SYM);;
790 let REAL_POW_MUL = prove
791 (`!x y n. (x * y) pow n = (x pow n) * (y pow n)`,
792 GEN_TAC THEN GEN_TAC THEN INDUCT_TAC THEN
793 ASM_REWRITE_TAC[real_pow; REAL_MUL_LID; REAL_MUL_AC]);;
795 let REAL_POW_INV = prove
796 (`!x n. (inv x) pow n = inv(x pow n)`,
797 GEN_TAC THEN INDUCT_TAC THEN
798 ASM_REWRITE_TAC[real_pow; REAL_INV_1; REAL_INV_MUL]);;
800 let REAL_INV_POW = prove
801 (`!x n. inv(x pow n) = (inv x) pow n`,
802 REWRITE_TAC[REAL_POW_INV]);;
804 let REAL_POW_DIV = prove
805 (`!x y n. (x / y) pow n = (x pow n) / (y pow n)`,
806 REWRITE_TAC[real_div; REAL_POW_MUL; REAL_POW_INV]);;
808 let REAL_DIV_EQ_0 = prove
809 (`!x y. x / y = &0 <=> x = &0 \/ y = &0`,
810 REWRITE_TAC[real_div; REAL_INV_EQ_0; REAL_ENTIRE]);;
812 let REAL_POW_ADD = prove
813 (`!x m n. x pow (m + n) = x pow m * x pow n`,
814 GEN_TAC THEN INDUCT_TAC THEN
815 ASM_REWRITE_TAC[ADD_CLAUSES; real_pow; REAL_MUL_LID; REAL_MUL_ASSOC]);;
817 let REAL_POW_NZ = prove
818 (`!x n. ~(x = &0) ==> ~(x pow n = &0)`,
819 GEN_TAC THEN INDUCT_TAC THEN
820 REWRITE_TAC[real_pow; REAL_OF_NUM_EQ; ARITH] THEN
821 ASM_MESON_TAC[REAL_ENTIRE]);;
823 let REAL_POW_SUB = prove
824 (`!x m n. ~(x = &0) /\ m <= n ==> (x pow (n - m) = x pow n / x pow m)`,
826 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
827 REWRITE_TAC[LE_EXISTS] THEN
828 DISCH_THEN(CHOOSE_THEN SUBST1_TAC) THEN
829 REWRITE_TAC[ADD_SUB2] THEN REWRITE_TAC[REAL_POW_ADD] THEN
830 REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
831 GEN_REWRITE_TAC LAND_CONV [GSYM REAL_MUL_LID] THEN
832 REWRITE_TAC[REAL_MUL_ASSOC] THEN AP_THM_TAC THEN AP_TERM_TAC THEN
833 CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_MUL_LINV THEN
834 MATCH_MP_TAC REAL_POW_NZ THEN ASM_REWRITE_TAC[]);;
836 let REAL_LT_IMP_NZ = prove
837 (`!x. &0 < x ==> ~(x = &0)`,
840 let REAL_LT_LCANCEL_IMP = prove
841 (`!x y z. &0 < x /\ x * y < x * z ==> y < z`,
843 DISCH_THEN(fun th -> ASSUME_TAC(CONJUNCT1 th) THEN MP_TAC th) THEN DISCH_THEN
844 (MP_TAC o uncurry CONJ o (MATCH_MP REAL_LT_INV F_F I) o CONJ_PAIR) THEN
845 DISCH_THEN(MP_TAC o MATCH_MP REAL_LT_LMUL) THEN
846 POP_ASSUM(ASSUME_TAC o MATCH_MP REAL_MUL_LINV o MATCH_MP REAL_LT_IMP_NZ) THEN
847 ASM_REWRITE_TAC[REAL_MUL_ASSOC; REAL_MUL_LID]);;
849 let REAL_LT_RCANCEL_IMP = prove
850 (`!x y z. &0 < z /\ x * z < y * z ==> x < y`,
851 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[REAL_LT_LCANCEL_IMP]);;
853 let REAL_LE_LCANCEL_IMP = prove
854 (`!x y z. &0 < x /\ x * y <= x * z ==> y <= z`,
855 REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_LT; REAL_EQ_MUL_LCANCEL] THEN
856 ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[REAL_LT_REFL] THEN
857 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN DISJ1_TAC THEN
858 MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN
859 EXISTS_TAC `x:real` THEN ASM_REWRITE_TAC[]);;
861 let REAL_LE_RCANCEL_IMP = prove
862 (`!x y z. &0 < z /\ x * z <= y * z ==> x <= y`,
863 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[REAL_LE_LCANCEL_IMP]);;
865 let REAL_LE_RMUL_EQ = prove
866 (`!x y z. &0 < z ==> (x * z <= y * z <=> x <= y)`,
867 MESON_TAC[REAL_LE_RMUL; REAL_LE_RCANCEL_IMP; REAL_LT_IMP_LE]);;
869 let REAL_LE_LMUL_EQ = prove
870 (`!x y z. &0 < z ==> (z * x <= z * y <=> x <= y)`,
871 MESON_TAC[REAL_LE_RMUL_EQ; REAL_MUL_SYM]);;
873 let REAL_LT_RMUL_EQ = prove
874 (`!x y z. &0 < z ==> (x * z < y * z <=> x < y)`,
875 SIMP_TAC[GSYM REAL_NOT_LE; REAL_LE_RMUL_EQ]);;
877 let REAL_LT_LMUL_EQ = prove
878 (`!x y z. &0 < z ==> (z * x < z * y <=> x < y)`,
879 SIMP_TAC[GSYM REAL_NOT_LE; REAL_LE_LMUL_EQ]);;
881 let REAL_LE_MUL_EQ = prove
882 (`(!x y. &0 < x ==> (&0 <= x * y <=> &0 <= y)) /\
883 (!x y. &0 < y ==> (&0 <= x * y <=> &0 <= x))`,
884 MESON_TAC[REAL_LE_LMUL_EQ; REAL_LE_RMUL_EQ; REAL_MUL_LZERO; REAL_MUL_RZERO]);;
886 let REAL_LT_MUL_EQ = prove
887 (`(!x y. &0 < x ==> (&0 < x * y <=> &0 < y)) /\
888 (!x y. &0 < y ==> (&0 < x * y <=> &0 < x))`,
889 MESON_TAC[REAL_LT_LMUL_EQ; REAL_LT_RMUL_EQ; REAL_MUL_LZERO; REAL_MUL_RZERO]);;
891 let REAL_MUL_POS_LT = prove
892 (`!x y. &0 < x * y <=> &0 < x /\ &0 < y \/ x < &0 /\ y < &0`,
893 REPEAT STRIP_TAC THEN
894 STRIP_ASSUME_TAC(SPEC `x:real` REAL_LT_NEGTOTAL) THEN
895 STRIP_ASSUME_TAC(SPEC `y:real` REAL_LT_NEGTOTAL) THEN
896 ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO; REAL_LT_REFL] THEN
897 ASSUM_LIST(MP_TAC o MATCH_MP REAL_LT_MUL o end_itlist CONJ) THEN
898 REPEAT(POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC);;
900 let REAL_MUL_POS_LE = prove
901 (`!x y. &0 <= x * y <=>
902 x = &0 \/ y = &0 \/ &0 < x /\ &0 < y \/ x < &0 /\ y < &0`,
903 REWRITE_TAC[REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN
904 REWRITE_TAC[REAL_MUL_POS_LT; REAL_ENTIRE] THEN REAL_ARITH_TAC);;
906 let REAL_LE_RDIV_EQ = prove
907 (`!x y z. &0 < z ==> (x <= y / z <=> x * z <= y)`,
908 REPEAT STRIP_TAC THEN
909 FIRST_ASSUM(fun th ->
910 GEN_REWRITE_TAC LAND_CONV [GSYM(MATCH_MP REAL_LE_RMUL_EQ th)]) THEN
911 ASM_SIMP_TAC[real_div; GSYM REAL_MUL_ASSOC; REAL_MUL_LINV;
912 REAL_MUL_RID; REAL_LT_IMP_NZ]);;
914 let REAL_LE_LDIV_EQ = prove
915 (`!x y z. &0 < z ==> (x / z <= y <=> x <= y * z)`,
916 REPEAT STRIP_TAC THEN
917 FIRST_ASSUM(fun th ->
918 GEN_REWRITE_TAC LAND_CONV [GSYM(MATCH_MP REAL_LE_RMUL_EQ th)]) THEN
919 ASM_SIMP_TAC[real_div; GSYM REAL_MUL_ASSOC; REAL_MUL_LINV;
920 REAL_MUL_RID; REAL_LT_IMP_NZ]);;
922 let REAL_LT_RDIV_EQ = prove
923 (`!x y z. &0 < z ==> (x < y / z <=> x * z < y)`,
924 SIMP_TAC[GSYM REAL_NOT_LE; REAL_LE_LDIV_EQ]);;
926 let REAL_LT_LDIV_EQ = prove
927 (`!x y z. &0 < z ==> (x / z < y <=> x < y * z)`,
928 SIMP_TAC[GSYM REAL_NOT_LE; REAL_LE_RDIV_EQ]);;
930 let REAL_EQ_RDIV_EQ = prove
931 (`!x y z. &0 < z ==> ((x = y / z) <=> (x * z = y))`,
932 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
933 SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ]);;
935 let REAL_EQ_LDIV_EQ = prove
936 (`!x y z. &0 < z ==> ((x / z = y) <=> (x = y * z))`,
937 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
938 SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ]);;
940 let REAL_LT_DIV2_EQ = prove
941 (`!x y z. &0 < z ==> (x / z < y / z <=> x < y)`,
942 SIMP_TAC[real_div; REAL_LT_RMUL_EQ; REAL_LT_INV_EQ]);;
944 let REAL_LE_DIV2_EQ = prove
945 (`!x y z. &0 < z ==> (x / z <= y / z <=> x <= y)`,
946 SIMP_TAC[real_div; REAL_LE_RMUL_EQ; REAL_LT_INV_EQ]);;
948 let REAL_MUL_2 = prove
949 (`!x. &2 * x = x + x`,
952 let REAL_POW_EQ_0 = prove
953 (`!x n. (x pow n = &0) <=> (x = &0) /\ ~(n = 0)`,
954 GEN_TAC THEN INDUCT_TAC THEN
955 ASM_REWRITE_TAC[NOT_SUC; real_pow; REAL_ENTIRE] THENL
959 let REAL_LE_MUL2 = prove
960 (`!w x y z. &0 <= w /\ w <= x /\ &0 <= y /\ y <= z
962 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
963 EXISTS_TAC `w * z` THEN CONJ_TAC THENL
964 [MATCH_MP_TAC REAL_LE_LMUL; MATCH_MP_TAC REAL_LE_RMUL] THEN
965 ASM_REWRITE_TAC[] THEN
966 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `y:real` THEN
969 let REAL_LT_MUL2 = prove
970 (`!w x y z. &0 <= w /\ w < x /\ &0 <= y /\ y < z
972 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
973 EXISTS_TAC `w * z` THEN CONJ_TAC THENL
974 [MATCH_MP_TAC REAL_LE_LMUL; MATCH_MP_TAC REAL_LT_RMUL] THEN
975 ASM_REWRITE_TAC[] THENL
976 [MATCH_MP_TAC REAL_LT_IMP_LE THEN ASM_REWRITE_TAC[];
977 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `y:real` THEN
978 ASM_REWRITE_TAC[]]);;
980 let REAL_LT_SQUARE = prove
981 (`!x. (&0 < x * x) <=> ~(x = &0)`,
982 GEN_TAC THEN REWRITE_TAC[REAL_LT_LE; REAL_LE_SQUARE] THEN
983 GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [EQ_SYM_EQ] THEN
984 REWRITE_TAC[REAL_ENTIRE]);;
986 let REAL_POW_1 = prove
988 REWRITE_TAC[num_CONV `1`] THEN
989 REWRITE_TAC[real_pow; REAL_MUL_RID]);;
991 let REAL_POW_ONE = prove
992 (`!n. &1 pow n = &1`,
993 INDUCT_TAC THEN ASM_REWRITE_TAC[real_pow; REAL_MUL_LID]);;
995 let REAL_LT_INV2 = prove
996 (`!x y. &0 < x /\ x < y ==> inv(y) < inv(x)`,
997 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LT_RCANCEL_IMP THEN
998 EXISTS_TAC `x * y` THEN CONJ_TAC THENL
999 [MATCH_MP_TAC REAL_LT_MUL THEN
1000 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN REAL_ARITH_TAC;
1001 SUBGOAL_THEN `(inv x * x = &1) /\ (inv y * y = &1)` ASSUME_TAC THENL
1002 [CONJ_TAC THEN MATCH_MP_TAC REAL_MUL_LINV THEN
1003 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN REAL_ARITH_TAC;
1004 ASM_REWRITE_TAC[REAL_MUL_ASSOC; REAL_MUL_LID] THEN
1005 GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [REAL_MUL_SYM] THEN
1006 ASM_REWRITE_TAC[GSYM REAL_MUL_ASSOC; REAL_MUL_RID]]]);;
1008 let REAL_LE_INV2 = prove
1009 (`!x y. &0 < x /\ x <= y ==> inv(y) <= inv(x)`,
1010 REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_LT] THEN
1011 ASM_CASES_TAC `x:real = y` THEN ASM_REWRITE_TAC[] THEN
1012 STRIP_TAC THEN DISJ1_TAC THEN MATCH_MP_TAC REAL_LT_INV2 THEN
1013 ASM_REWRITE_TAC[]);;
1015 let REAL_LT_LINV = prove
1016 (`!x y. &0 < y /\ inv y < x ==> inv x < y`,
1017 REPEAT STRIP_TAC THEN MP_TAC (SPEC `y:real` REAL_LT_INV) THEN
1018 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
1019 MP_TAC (SPECL [`(inv y:real)`; `x:real`] REAL_LT_INV2) THEN
1020 ASM_REWRITE_TAC[REAL_INV_INV]);;
1022 let REAL_LT_RINV = prove
1023 (`!x y. &0 < x /\ x < inv y ==> y < inv x`,
1024 REPEAT STRIP_TAC THEN MP_TAC (SPEC `x:real` REAL_LT_INV) THEN
1025 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
1026 MP_TAC (SPECL [`x:real`; `inv y:real`] REAL_LT_INV2) THEN
1027 ASM_REWRITE_TAC[REAL_INV_INV]);;
1029 let REAL_LE_LINV = prove
1030 (`!x y. &0 < y /\ inv y <= x ==> inv x <= y`,
1031 REPEAT STRIP_TAC THEN MP_TAC (SPEC `y:real` REAL_LT_INV) THEN
1032 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
1033 MP_TAC (SPECL [`(inv y:real)`; `x:real`] REAL_LE_INV2) THEN
1034 ASM_REWRITE_TAC[REAL_INV_INV]);;
1036 let REAL_LE_RINV = prove
1037 (`!x y. &0 < x /\ x <= inv y ==> y <= inv x`,
1038 REPEAT STRIP_TAC THEN MP_TAC (SPEC `x:real` REAL_LT_INV) THEN
1039 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
1040 MP_TAC (SPECL [`x:real`; `inv y:real`] REAL_LE_INV2) THEN
1041 ASM_REWRITE_TAC[REAL_INV_INV]);;
1043 let REAL_INV_LE_1 = prove
1044 (`!x. &1 <= x ==> inv(x) <= &1`,
1045 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_INV_1] THEN
1046 MATCH_MP_TAC REAL_LE_INV2 THEN ASM_REWRITE_TAC[REAL_LT_01]);;
1048 let REAL_INV_1_LE = prove
1049 (`!x. &0 < x /\ x <= &1 ==> &1 <= inv(x)`,
1050 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_INV_1] THEN
1051 MATCH_MP_TAC REAL_LE_INV2 THEN ASM_REWRITE_TAC[REAL_LT_01]);;
1053 let REAL_INV_LT_1 = prove
1054 (`!x. &1 < x ==> inv(x) < &1`,
1055 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_INV_1] THEN
1056 MATCH_MP_TAC REAL_LT_INV2 THEN ASM_REWRITE_TAC[REAL_LT_01]);;
1058 let REAL_INV_1_LT = prove
1059 (`!x. &0 < x /\ x < &1 ==> &1 < inv(x)`,
1060 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_INV_1] THEN
1061 MATCH_MP_TAC REAL_LT_INV2 THEN ASM_REWRITE_TAC[REAL_LT_01]);;
1063 let REAL_SUB_INV = prove
1064 (`!x y. ~(x = &0) /\ ~(y = &0) ==> (inv(x) - inv(y) = (y - x) / (x * y))`,
1065 REWRITE_TAC[real_div; REAL_SUB_RDISTRIB; REAL_INV_MUL] THEN
1066 SIMP_TAC[REAL_MUL_ASSOC; REAL_MUL_RINV; REAL_MUL_LID] THEN
1067 REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN REWRITE_TAC[GSYM real_div] THEN
1068 SIMP_TAC[REAL_DIV_LMUL]);;
1070 let REAL_DOWN = prove
1071 (`!d. &0 < d ==> ?e. &0 < e /\ e < d`,
1072 GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `d / &2` THEN
1073 ASSUME_TAC(REAL_ARITH `&0 < &2`) THEN
1074 ASSUME_TAC(MATCH_MP REAL_MUL_LINV (REAL_ARITH `~(&2 = &0)`)) THEN
1075 CONJ_TAC THEN MATCH_MP_TAC REAL_LT_RCANCEL_IMP THEN EXISTS_TAC `&2` THEN
1076 ASM_REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC; REAL_MUL_RID] THEN
1077 UNDISCH_TAC `&0 < d` THEN REAL_ARITH_TAC);;
1079 let REAL_DOWN2 = prove
1080 (`!d1 d2. &0 < d1 /\ &0 < d2 ==> ?e. &0 < e /\ e < d1 /\ e < d2`,
1081 REPEAT GEN_TAC THEN STRIP_TAC THEN
1082 DISJ_CASES_TAC(SPECL [`d1:real`; `d2:real`] REAL_LE_TOTAL) THENL
1083 [MP_TAC(SPEC `d1:real` REAL_DOWN);
1084 MP_TAC(SPEC `d2:real` REAL_DOWN)] THEN
1085 ASM_REWRITE_TAC[] THEN
1086 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
1087 EXISTS_TAC `e:real` THEN
1088 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
1091 let REAL_POW_LE2 = prove
1092 (`!n x y. &0 <= x /\ x <= y ==> x pow n <= y pow n`,
1093 INDUCT_TAC THEN REWRITE_TAC[real_pow; REAL_LE_REFL] THEN
1094 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
1095 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
1096 [MATCH_MP_TAC REAL_POW_LE THEN ASM_REWRITE_TAC[];
1097 FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]]);;
1099 let REAL_POW_LE_1 = prove
1100 (`!n x. &1 <= x ==> &1 <= x pow n`,
1101 REPEAT STRIP_TAC THEN
1102 MP_TAC(SPECL [`n:num`; `&1`; `x:real`] REAL_POW_LE2) THEN
1103 ASM_REWRITE_TAC[REAL_POW_ONE; REAL_POS]);;
1105 let REAL_POW_1_LE = prove
1106 (`!n x. &0 <= x /\ x <= &1 ==> x pow n <= &1`,
1107 REPEAT STRIP_TAC THEN
1108 MP_TAC(SPECL [`n:num`; `x:real`; `&1`] REAL_POW_LE2) THEN
1109 ASM_REWRITE_TAC[REAL_POW_ONE]);;
1111 let REAL_POW_MONO = prove
1112 (`!m n x. &1 <= x /\ m <= n ==> x pow m <= x pow n`,
1113 REPEAT GEN_TAC THEN REWRITE_TAC[LE_EXISTS] THEN
1114 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
1115 DISCH_THEN(X_CHOOSE_THEN `d:num` SUBST1_TAC) THEN
1116 REWRITE_TAC[REAL_POW_ADD] THEN
1117 GEN_REWRITE_TAC LAND_CONV [GSYM REAL_MUL_RID] THEN
1118 MATCH_MP_TAC REAL_LE_LMUL THEN CONJ_TAC THENL
1119 [MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `&1` THEN
1120 REWRITE_TAC[REAL_OF_NUM_LE; ARITH] THEN
1121 MATCH_MP_TAC REAL_POW_LE_1 THEN ASM_REWRITE_TAC[];
1122 MATCH_MP_TAC REAL_POW_LE_1 THEN ASM_REWRITE_TAC[]]);;
1124 let REAL_POW_LT2 = prove
1125 (`!n x y. ~(n = 0) /\ &0 <= x /\ x < y ==> x pow n < y pow n`,
1126 INDUCT_TAC THEN REWRITE_TAC[NOT_SUC; real_pow] THEN REPEAT STRIP_TAC THEN
1127 ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[real_pow; REAL_MUL_RID] THEN
1128 MATCH_MP_TAC REAL_LT_MUL2 THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
1129 [MATCH_MP_TAC REAL_POW_LE THEN ASM_REWRITE_TAC[];
1130 FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]]);;
1132 let REAL_POW_LT_1 = prove
1133 (`!n x. ~(n = 0) /\ &1 < x ==> &1 < x pow n`,
1134 REPEAT STRIP_TAC THEN
1135 MP_TAC(SPECL [`n:num`; `&1`; `x:real`] REAL_POW_LT2) THEN
1136 ASM_REWRITE_TAC[REAL_POW_ONE; REAL_POS]);;
1138 let REAL_POW_1_LT = prove
1139 (`!n x. ~(n = 0) /\ &0 <= x /\ x < &1 ==> x pow n < &1`,
1140 REPEAT STRIP_TAC THEN
1141 MP_TAC(SPECL [`n:num`; `x:real`; `&1`] REAL_POW_LT2) THEN
1142 ASM_REWRITE_TAC[REAL_POW_ONE]);;
1144 let REAL_POW_MONO_LT = prove
1145 (`!m n x. &1 < x /\ m < n ==> x pow m < x pow n`,
1146 REPEAT GEN_TAC THEN REWRITE_TAC[LT_EXISTS] THEN
1147 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
1148 DISCH_THEN(CHOOSE_THEN SUBST_ALL_TAC) THEN
1149 REWRITE_TAC[REAL_POW_ADD] THEN
1150 GEN_REWRITE_TAC LAND_CONV [GSYM REAL_MUL_RID] THEN
1151 MATCH_MP_TAC REAL_LT_LMUL THEN CONJ_TAC THENL
1152 [MATCH_MP_TAC REAL_POW_LT THEN
1153 MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `&1` THEN
1154 ASM_REWRITE_TAC[REAL_OF_NUM_LT; ARITH];
1155 SPEC_TAC(`d:num`,`d:num`) THEN
1156 INDUCT_TAC THEN ONCE_REWRITE_TAC[real_pow] THENL
1157 [ASM_REWRITE_TAC[real_pow; REAL_MUL_RID]; ALL_TAC] THEN
1158 GEN_REWRITE_TAC LAND_CONV [GSYM REAL_MUL_LID] THEN
1159 MATCH_MP_TAC REAL_LT_MUL2 THEN
1160 ASM_REWRITE_TAC[REAL_OF_NUM_LE; ARITH]]);;
1162 let REAL_POW_POW = prove
1163 (`!x m n. (x pow m) pow n = x pow (m * n)`,
1164 GEN_TAC THEN GEN_TAC THEN INDUCT_TAC THEN
1165 ASM_REWRITE_TAC[real_pow; MULT_CLAUSES; REAL_POW_ADD]);;
1167 let REAL_EQ_RCANCEL_IMP = prove
1168 (`!x y z. ~(z = &0) /\ (x * z = y * z) ==> (x = y)`,
1169 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
1170 REWRITE_TAC[REAL_SUB_RZERO; GSYM REAL_SUB_RDISTRIB; REAL_ENTIRE] THEN
1173 let REAL_EQ_LCANCEL_IMP = prove
1174 (`!x y z. ~(z = &0) /\ (z * x = z * y) ==> (x = y)`,
1175 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN MATCH_ACCEPT_TAC REAL_EQ_RCANCEL_IMP);;
1177 let REAL_LT_DIV = prove
1178 (`!x y. &0 < x /\ &0 < y ==> &0 < x / y`,
1179 SIMP_TAC[REAL_LT_MUL; REAL_LT_INV_EQ; real_div]);;
1181 let REAL_LE_DIV = prove
1182 (`!x y. &0 <= x /\ &0 <= y ==> &0 <= x / y`,
1183 SIMP_TAC[REAL_LE_MUL; REAL_LE_INV_EQ; real_div]);;
1185 let REAL_DIV_POW2 = prove
1187 ==> (x pow m / x pow n = if n <= m then x pow (m - n)
1188 else inv(x pow (n - m)))`,
1189 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
1190 ASM_SIMP_TAC[REAL_POW_SUB] THEN
1191 GEN_REWRITE_TAC LAND_CONV [GSYM REAL_INV_INV] THEN
1192 AP_TERM_TAC THEN REWRITE_TAC[REAL_INV_DIV] THEN
1193 UNDISCH_TAC `~(n:num <= m)` THEN REWRITE_TAC[NOT_LE] THEN
1194 DISCH_THEN(MP_TAC o MATCH_MP LT_IMP_LE) THEN
1195 ASM_SIMP_TAC[REAL_POW_SUB]);;
1197 let REAL_DIV_POW2_ALT = prove
1199 ==> (x pow m / x pow n = if n < m then x pow (m - n)
1200 else inv(x pow (n - m)))`,
1201 REPEAT STRIP_TAC THEN
1202 GEN_REWRITE_TAC LAND_CONV [GSYM REAL_INV_INV] THEN
1203 ONCE_REWRITE_TAC[REAL_INV_DIV] THEN
1204 ASM_SIMP_TAC[GSYM NOT_LE; REAL_DIV_POW2] THEN
1205 ASM_CASES_TAC `m <= n:num` THEN
1206 ASM_REWRITE_TAC[REAL_INV_INV]);;
1208 let REAL_LT_POW2 = prove
1209 (`!n. &0 < &2 pow n`,
1210 SIMP_TAC[REAL_POW_LT; REAL_OF_NUM_LT; ARITH]);;
1212 let REAL_LE_POW2 = prove
1213 (`!n. &1 <= &2 pow n`,
1214 GEN_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `&2 pow 0` THEN
1215 SIMP_TAC[REAL_POW_MONO; LE_0; REAL_OF_NUM_LE; ARITH] THEN
1216 REWRITE_TAC[real_pow; REAL_LE_REFL]);;
1218 let REAL_POW2_ABS = prove
1219 (`!x. abs(x) pow 2 = x pow 2`,
1220 GEN_TAC THEN REWRITE_TAC[real_abs] THEN
1221 COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_POW_NEG; ARITH_EVEN]);;
1223 let REAL_LE_SQUARE_ABS = prove
1224 (`!x y. abs(x) <= abs(y) <=> x pow 2 <= y pow 2`,
1225 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN
1226 MESON_TAC[REAL_POW_LE2; REAL_ABS_POS; NUM_EQ_CONV `2 = 0`;
1227 REAL_POW_LT2; REAL_NOT_LE]);;
1229 let REAL_LT_SQUARE_ABS = prove
1230 (`!x y. abs(x) < abs(y) <=> x pow 2 < y pow 2`,
1231 REWRITE_TAC[GSYM REAL_NOT_LE; REAL_LE_SQUARE_ABS]);;
1233 let REAL_EQ_SQUARE_ABS = prove
1234 (`!x y. abs x = abs y <=> x pow 2 = y pow 2`,
1235 REWRITE_TAC[GSYM REAL_LE_ANTISYM; REAL_LE_SQUARE_ABS]);;
1237 let REAL_LE_POW_2 = prove
1238 (`!x. &0 <= x pow 2`,
1239 REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE]);;
1241 let REAL_LT_POW_2 = prove
1242 (`!x. &0 < x pow 2 <=> ~(x = &0)`,
1243 REWRITE_TAC[REAL_LE_POW_2; REAL_ARITH `&0 < x <=> &0 <= x /\ ~(x = &0)`] THEN
1244 REWRITE_TAC[REAL_POW_EQ_0; ARITH]);;
1246 let REAL_SOS_EQ_0 = prove
1247 (`!x y. x pow 2 + y pow 2 = &0 <=> x = &0 /\ y = &0`,
1248 REPEAT GEN_TAC THEN EQ_TAC THEN
1249 SIMP_TAC[REAL_POW_2; REAL_MUL_LZERO; REAL_ADD_LID] THEN
1250 DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH
1251 `x + y = &0 ==> &0 <= x /\ &0 <= y ==> x = &0 /\ y = &0`)) THEN
1252 REWRITE_TAC[REAL_LE_SQUARE; REAL_ENTIRE]);;
1254 let REAL_POW_ZERO = prove
1255 (`!n. &0 pow n = if n = 0 then &1 else &0`,
1256 INDUCT_TAC THEN REWRITE_TAC[real_pow; NOT_SUC; REAL_MUL_LZERO]);;
1258 let REAL_POW_MONO_INV = prove
1259 (`!m n x. &0 <= x /\ x <= &1 /\ n <= m ==> x pow m <= x pow n`,
1260 REPEAT STRIP_TAC THEN ASM_CASES_TAC `x = &0` THENL
1261 [ASM_REWRITE_TAC[REAL_POW_ZERO] THEN
1262 REPEAT(COND_CASES_TAC THEN REWRITE_TAC[REAL_POS; REAL_LE_REFL]) THEN
1263 UNDISCH_TAC `n:num <= m` THEN ASM_REWRITE_TAC[LE];
1264 GEN_REWRITE_TAC BINOP_CONV [GSYM REAL_INV_INV] THEN
1265 MATCH_MP_TAC REAL_LE_INV2 THEN REWRITE_TAC[GSYM REAL_POW_INV] THEN
1267 [MATCH_MP_TAC REAL_POW_LT THEN REWRITE_TAC[REAL_LT_INV_EQ];
1268 MATCH_MP_TAC REAL_POW_MONO THEN ASM_REWRITE_TAC[] THEN
1269 MATCH_MP_TAC REAL_INV_1_LE] THEN
1270 ASM_REWRITE_TAC[REAL_LT_LE]]);;
1272 let REAL_POW_LE2_REV = prove
1273 (`!n x y. ~(n = 0) /\ &0 <= y /\ x pow n <= y pow n ==> x <= y`,
1274 MESON_TAC[REAL_POW_LT2; REAL_NOT_LE]);;
1276 let REAL_POW_LT2_REV = prove
1277 (`!n x y. &0 <= y /\ x pow n < y pow n ==> x < y`,
1278 MESON_TAC[REAL_POW_LE2; REAL_NOT_LE]);;
1280 let REAL_POW_EQ = prove
1281 (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y /\ x pow n = y pow n ==> x = y`,
1282 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN MESON_TAC[REAL_POW_LE2_REV]);;
1284 let REAL_POW_EQ_ABS = prove
1285 (`!n x y. ~(n = 0) /\ x pow n = y pow n ==> abs x = abs y`,
1286 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_POW_EQ THEN EXISTS_TAC `n:num` THEN
1287 ASM_REWRITE_TAC[REAL_ABS_POS; GSYM REAL_ABS_POW]);;
1289 let REAL_POW_EQ_1_IMP = prove
1290 (`!x n. ~(n = 0) /\ x pow n = &1 ==> abs(x) = &1`,
1291 REPEAT STRIP_TAC THEN GEN_REWRITE_TAC RAND_CONV [GSYM REAL_ABS_NUM] THEN
1292 MATCH_MP_TAC REAL_POW_EQ_ABS THEN EXISTS_TAC `n:num` THEN
1293 ASM_REWRITE_TAC[REAL_POW_ONE]);;
1295 let REAL_POW_EQ_1 = prove
1296 (`!x n. x pow n = &1 <=> abs(x) = &1 /\ (x < &0 ==> EVEN(n)) \/ n = 0`,
1298 ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[real_pow] THEN
1299 ASM_CASES_TAC `abs(x) = &1` THENL
1300 [ALL_TAC; ASM_MESON_TAC[REAL_POW_EQ_1_IMP]] THEN
1301 ASM_REWRITE_TAC[] THEN
1302 FIRST_X_ASSUM(DISJ_CASES_THEN SUBST1_TAC o MATCH_MP (REAL_ARITH
1303 `abs x = a ==> x = a \/ x = --a`)) THEN
1304 ASM_REWRITE_TAC[REAL_POW_NEG; REAL_POW_ONE] THEN
1305 REPEAT COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
1307 let REAL_POW_LT2_ODD = prove
1308 (`!n x y. x < y /\ ODD n ==> x pow n < y pow n`,
1309 REPEAT GEN_TAC THEN ASM_CASES_TAC `n = 0` THEN
1310 ASM_REWRITE_TAC[ARITH] THEN STRIP_TAC THEN
1311 DISJ_CASES_TAC(SPEC `y:real` REAL_LE_NEGTOTAL) THENL
1312 [DISJ_CASES_TAC(REAL_ARITH `&0 <= x \/ &0 < --x`) THEN
1313 ASM_SIMP_TAC[REAL_POW_LT2] THEN
1314 SUBGOAL_THEN `&0 < --x pow n /\ &0 <= y pow n` MP_TAC THENL
1315 [ASM_SIMP_TAC[REAL_POW_LE; REAL_POW_LT];
1316 ASM_REWRITE_TAC[REAL_POW_NEG; GSYM NOT_ODD] THEN REAL_ARITH_TAC];
1317 SUBGOAL_THEN `--y pow n < --x pow n` MP_TAC THENL
1318 [MATCH_MP_TAC REAL_POW_LT2 THEN ASM_REWRITE_TAC[];
1319 ASM_REWRITE_TAC[REAL_POW_NEG; GSYM NOT_ODD]] THEN
1320 REPEAT(POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC]);;
1322 let REAL_POW_LE2_ODD = prove
1323 (`!n x y. x <= y /\ ODD n ==> x pow n <= y pow n`,
1324 REWRITE_TAC[REAL_LE_LT] THEN REPEAT STRIP_TAC THEN
1325 ASM_SIMP_TAC[REAL_POW_LT2_ODD]);;
1327 let REAL_POW_LT2_ODD_EQ = prove
1328 (`!n x y. ODD n ==> (x pow n < y pow n <=> x < y)`,
1329 MESON_TAC[REAL_POW_LT2_ODD; REAL_POW_LE2_ODD; REAL_NOT_LE]);;
1331 let REAL_POW_LE2_ODD_EQ = prove
1332 (`!n x y. ODD n ==> (x pow n <= y pow n <=> x <= y)`,
1333 MESON_TAC[REAL_POW_LT2_ODD; REAL_POW_LE2_ODD; REAL_NOT_LE]);;
1335 let REAL_POW_EQ_ODD_EQ = prove
1336 (`!n x y. ODD n ==> (x pow n = y pow n <=> x = y)`,
1337 SIMP_TAC[GSYM REAL_LE_ANTISYM; REAL_POW_LE2_ODD_EQ]);;
1339 let REAL_POW_EQ_ODD = prove
1340 (`!n x y. ODD n /\ x pow n = y pow n ==> x = y`,
1341 MESON_TAC[REAL_POW_EQ_ODD_EQ]);;
1343 let REAL_POW_EQ_EQ = prove
1344 (`!n x y. x pow n = y pow n <=>
1345 if EVEN n then n = 0 \/ abs x = abs y else x = y`,
1346 REPEAT GEN_TAC THEN ASM_CASES_TAC `n = 0` THEN
1347 ASM_REWRITE_TAC[real_pow; ARITH] THEN COND_CASES_TAC THEN
1348 ASM_SIMP_TAC[REAL_POW_EQ_ODD_EQ; GSYM NOT_EVEN] THEN
1349 EQ_TAC THENL [ASM_MESON_TAC[REAL_POW_EQ_ABS]; ALL_TAC] THEN
1350 REWRITE_TAC[REAL_EQ_SQUARE_ABS] THEN DISCH_TAC THEN
1351 FIRST_X_ASSUM(X_CHOOSE_THEN `m:num` SUBST1_TAC o
1352 REWRITE_RULE[EVEN_EXISTS]) THEN ASM_REWRITE_TAC[GSYM REAL_POW_POW]);;
1354 (* ------------------------------------------------------------------------- *)
1355 (* Some basic forms of the Archimedian property. *)
1356 (* ------------------------------------------------------------------------- *)
1358 let REAL_ARCH_SIMPLE = prove
1360 let lemma = prove(`(!x. (?n. x = &n) ==> P x) <=> !n. P(&n)`,MESON_TAC[]) in
1361 MP_TAC(SPEC `\y. ?n. y = &n` REAL_COMPLETE) THEN REWRITE_TAC[lemma] THEN
1362 MESON_TAC[REAL_LE_SUB_LADD; REAL_OF_NUM_ADD; REAL_LE_TOTAL;
1363 REAL_ARITH `~(M <= M - &1)`]);;
1365 let REAL_ARCH_LT = prove
1367 MESON_TAC[REAL_ARCH_SIMPLE; REAL_OF_NUM_ADD;
1368 REAL_ARITH `x <= n ==> x < n + &1`]);;
1370 let REAL_ARCH = prove
1371 (`!x. &0 < x ==> !y. ?n. y < &n * x`,
1372 MESON_TAC[REAL_ARCH_LT; REAL_LT_LDIV_EQ]);;
1374 (* ------------------------------------------------------------------------- *)
1375 (* The sign of a real number, as a real number. *)
1376 (* ------------------------------------------------------------------------- *)
1378 let real_sgn = new_definition
1379 `(real_sgn:real->real) x =
1380 if &0 < x then &1 else if x < &0 then -- &1 else &0`;;
1382 let REAL_SGN_0 = prove
1383 (`real_sgn(&0) = &0`,
1384 REWRITE_TAC[real_sgn] THEN REAL_ARITH_TAC);;
1386 let REAL_SGN_NEG = prove
1387 (`!x. real_sgn(--x) = --(real_sgn x)`,
1388 REWRITE_TAC[real_sgn] THEN REAL_ARITH_TAC);;
1390 let REAL_SGN_ABS = prove
1391 (`!x. real_sgn(x) * abs(x) = x`,
1392 REWRITE_TAC[real_sgn] THEN REAL_ARITH_TAC);;
1394 let REAL_EQ_SGN_ABS = prove
1395 (`!x y:real. x = y <=> real_sgn x = real_sgn y /\ abs x = abs y`,
1396 MESON_TAC[REAL_SGN_ABS]);;
1398 let REAL_ABS_SGN = prove
1399 (`!x. abs(real_sgn x) = real_sgn(abs x)`,
1400 REWRITE_TAC[real_sgn] THEN REAL_ARITH_TAC);;
1402 let REAL_SGN = prove
1403 (`!x. real_sgn x = x / abs x`,
1404 GEN_TAC THEN ASM_CASES_TAC `x = &0` THENL
1405 [ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO; REAL_SGN_0];
1406 GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [GSYM REAL_SGN_ABS] THEN
1407 ASM_SIMP_TAC[real_div; GSYM REAL_MUL_ASSOC; REAL_ABS_ZERO;
1408 REAL_MUL_RINV; REAL_MUL_RID]]);;
1410 let REAL_SGN_MUL = prove
1411 (`!x y. real_sgn(x * y) = real_sgn(x) * real_sgn(y)`,
1412 REWRITE_TAC[REAL_SGN; REAL_ABS_MUL; real_div; REAL_INV_MUL] THEN
1415 let REAL_SGN_INV = prove
1416 (`!x. real_sgn(inv x) = real_sgn x`,
1417 REWRITE_TAC[real_sgn; REAL_LT_INV_EQ; GSYM REAL_INV_NEG;
1418 REAL_ARITH `x < &0 <=> &0 < --x`]);;
1420 let REAL_SGN_DIV = prove
1421 (`!x y. real_sgn(x / y) = real_sgn(x) / real_sgn(y)`,
1422 REWRITE_TAC[REAL_SGN; REAL_ABS_DIV] THEN
1423 REWRITE_TAC[real_div; REAL_INV_MUL; REAL_INV_INV] THEN
1426 let REAL_SGN_EQ = prove
1427 (`(!x. real_sgn x = &0 <=> x = &0) /\
1428 (!x. real_sgn x = &1 <=> x > &0) /\
1429 (!x. real_sgn x = -- &1 <=> x < &0)`,
1430 REWRITE_TAC[real_sgn] THEN REAL_ARITH_TAC);;
1432 let REAL_SGN_CASES = prove
1433 (`!x. real_sgn x = &0 \/ real_sgn x = &1 \/ real_sgn x = -- &1`,
1434 REWRITE_TAC[real_sgn] THEN MESON_TAC[]);;
1436 let REAL_SGN_INEQS = prove
1437 (`(!x. &0 <= real_sgn x <=> &0 <= x) /\
1438 (!x. &0 < real_sgn x <=> &0 < x) /\
1439 (!x. &0 >= real_sgn x <=> &0 >= x) /\
1440 (!x. &0 > real_sgn x <=> &0 > x) /\
1441 (!x. &0 = real_sgn x <=> &0 = x) /\
1442 (!x. real_sgn x <= &0 <=> x <= &0) /\
1443 (!x. real_sgn x < &0 <=> x < &0) /\
1444 (!x. real_sgn x >= &0 <=> x >= &0) /\
1445 (!x. real_sgn x > &0 <=> x > &0) /\
1446 (!x. real_sgn x = &0 <=> x = &0)`,
1447 REWRITE_TAC[real_sgn] THEN REAL_ARITH_TAC);;
1449 let REAL_SGN_POW = prove
1450 (`!x n. real_sgn(x pow n) = real_sgn(x) pow n`,
1451 GEN_TAC THEN INDUCT_TAC THEN ASM_REWRITE_TAC[REAL_SGN_MUL; real_pow] THEN
1452 REWRITE_TAC[real_sgn; REAL_LT_01]);;
1454 let REAL_SGN_POW_2 = prove
1455 (`!x. real_sgn(x pow 2) = real_sgn(abs x)`,
1456 REWRITE_TAC[real_sgn] THEN
1457 SIMP_TAC[GSYM REAL_NOT_LE; REAL_ABS_POS; REAL_LE_POW_2;
1458 REAL_ARITH `&0 <= x ==> (x <= &0 <=> x = &0)`] THEN
1459 REWRITE_TAC[REAL_POW_EQ_0; REAL_ABS_ZERO; ARITH]);;
1461 let REAL_SGN_REAL_SGN = prove
1462 (`!x. real_sgn(real_sgn x) = real_sgn x`,
1463 REWRITE_TAC[real_sgn] THEN REAL_ARITH_TAC);;
1465 let REAL_INV_SGN = prove
1466 (`!x. real_inv(real_sgn x) = real_sgn x`,
1467 GEN_TAC THEN REWRITE_TAC[real_sgn] THEN
1468 REPEAT COND_CASES_TAC THEN
1469 REWRITE_TAC[REAL_INV_0; REAL_INV_1; REAL_INV_NEG]);;
1471 (* ------------------------------------------------------------------------- *)
1472 (* Useful "without loss of generality" lemmas. *)
1473 (* ------------------------------------------------------------------------- *)
1475 let REAL_WLOG_LE = prove
1476 (`(!x y. P x y <=> P y x) /\ (!x y. x <= y ==> P x y) ==> !x y. P x y`,
1477 MESON_TAC[REAL_LE_TOTAL]);;
1479 let REAL_WLOG_LT = prove
1480 (`(!x. P x x) /\ (!x y. P x y <=> P y x) /\ (!x y. x < y ==> P x y)
1482 MESON_TAC[REAL_LT_TOTAL]);;