Update from HH
[Flyspeck/.git] / formal_ineqs / jordan / real_ext.hl
1 (* ========================================================================== *)
2 (* FLYSPECK - BOOK FORMALIZATION                                              *)
3 (*                                                                            *)
4 (* Chapter: Jordan                                                            *)
5 (* Copied from HOL Light jordan directory                                     *)
6 (* Author: Thomas C. Hales                                                    *)
7 (* Date: 2010-07-08                                                           *)
8 (* ========================================================================== *)
9
10 module Real_ext = struct
11
12 open Parse_ext_override_interface;;
13 (* open Tactics_jordan;; *)
14
15
16
17 (* ------------------------------------------------------------------ *)
18 (*   Theorems that construct and propagate equality and inequality    *)
19 (* ------------------------------------------------------------------ *)
20
21 (* ------------------------------------------------------------------ *)
22 (* Propagation of =EQUAL=  *)
23 (* ------------------------------------------------------------------ *)
24
25 unambiguous_interface();;
26 prioritize_num();;
27
28 let REAL_LE = REAL_OF_NUM_LE;;
29
30 let pow = real_pow;;
31
32
33 let REAL_INV2 = prove(
34   `(inv(&. 2)*(&. 2) = (&.1)) /\ ((&. 2)*inv(&. 2) = (&.1))`,
35   SUBGOAL_THEN `~((&.2) = (&.0))` MP_TAC
36 THENL[
37   REAL_ARITH_TAC;
38   SIMP_TAC[REAL_MUL_RINV;REAL_MUL_LINV]]);;
39
40
41
42
43 let REAL_MUL_LTIMES = prove (`!x a b. (x*.a = x*.b) ==> (~(x=(&.0))) ==> (a =b)`,
44    MESON_TAC[REAL_EQ_MUL_LCANCEL]);;
45
46 let REAL_MUL_RTIMES = prove (`!x a b. (a*.x = b*.x) ==> (~(x=(&.0))) ==> (a =b)`,
47    MESON_TAC[REAL_EQ_MUL_RCANCEL]);;
48
49 let REAL_PROP_EQ_LMUL = REAL_MUL_LTIMES;;
50 let REAL_PROP_EQ_RMUL = REAL_MUL_RTIMES;;
51
52 let REAL_PROP_EQ_LMUL_' = REAL_EQ_MUL_LCANCEL (* |- !x y z. (x * y = x * z) = (x = &0) \/ (y = z) *);;
53 let REAL_PROP_EQ_RMUL_' = REAL_EQ_MUL_LCANCEL (* |- !x y z. (x * z = y * z) = (x = y) \/ (z = &0) *);;
54 (* see also minor variations REAL_LT_LMUL_EQ, REAL_LT_RMUL_EQ *)
55
56 let REAL_PROP_EQ_SQRT = SQRT_INJ;; (* |- !x y. &0 <= x /\ &0 <= y ==> ((sqrt x = sqrt y) = x = y) *)
57
58 (* ------------------------------------------------------------------ *)
59 (* Construction of <=. *)
60 (* ------------------------------------------------------------------ *)
61 let REAL_MK_LE_SQUARE = REAL_LE_POW_2 ;; (*  |- !x. &0 <= x pow 2 *)
62
63 (* ------------------------------------------------------------------ *)
64 (* Propagation of <=. *)
65 (* ------------------------------------------------------------------ *)
66
67 let REAL_MUL_LTIMES_LE = prove (`!x a b. (x*.a <=. x*.b) ==> (&.0 < x) ==> (a <=. b)`,
68    MESON_TAC[REAL_LE_LMUL_EQ]);;
69   (* virtually identical to REAL_LE_LCANCEL_IMP, REAL_LE_LMUL_EQ *)
70
71 let REAL_MUL_RTIMES_LE = prove (`!x a b. (a*.x <=. b*.x) ==> (&.0 < x) ==> (a <=. b)`,
72    MESON_TAC[REAL_LE_RMUL_EQ]);;
73   (* virtually identical to REAL_LE_RCANCEL_IMP, REAL_LE_RMUL_EQ *)
74
75 let REAL_PROP_LE_LCANCEL = REAL_MUL_LTIMES_LE;;
76 let REAL_PROP_LE_RCANCEL = REAL_MUL_RTIMES_LE;;
77 let REAL_PROP_LE_LMUL = REAL_LE_LMUL (* |- !x y z. &0 <= x /\ y <= z ==> x * y <= x * z *);;
78 let REAL_PROP_LE_RMUL = REAL_LE_RMUL (* |- !x y z. x <= y /\ &0 <= z ==> x * z <= y * z *);;
79 let REAL_PROP_LE_LRMUL = REAL_LE_MUL2;; (* |- !w x y z. &0 <= w /\ w <= x /\ &0 <= y /\ y <= z ==> w * y <= x * z *)
80 let REAL_PROP_LE_POW = REAL_POW_LE2;; (* 2010-07-08 thales: POW_LE;; *) (* |- !n x y. &0 <= x /\ x <= y ==> x pow n <= y pow n *)
81 let REAL_PROP_LE_SQRT = SQRT_MONO_LE_EQ;; (* |- !x y. &0 <= x /\ &0 <= y ==> (sqrt x <= sqrt y = x <= y) *)
82
83 (* ------------------------------------------------------------------ *)
84 (* Construction of LT *)
85 (* ------------------------------------------------------------------ *)
86
87 let REAL_MK_LT_SQUARE  = REAL_LT_SQUARE;; (* |- !x. &0 < x * x = ~(x = &0) *)
88
89 (* ------------------------------------------------------------------ *)
90 (* Propagation of LT *)
91 (* ------------------------------------------------------------------ *)
92
93 let REAL_PROP_LT_LCANCEL = REAL_LT_LCANCEL_IMP (* |- !x y z. &0 < x /\ x * y < x * z ==> y < z *);;
94 let REAL_PROP_LT_RCANCEL = REAL_LT_RCANCEL_IMP (* |- !x y z. &0 < z /\ x * z < y * z ==> x < y *);;
95 let REAL_PROP_LT_LMUL = REAL_LT_LMUL (* |- !x y z. &0 < x /\ y < z ==> x * y < x * z *);;
96 let REAL_PROP_LT_RMUL = REAL_LT_RMUL (* |- !x y z. x < y /\ &0 < z ==> x * z < y * z *);;
97 (* minor variation REAL_LT_LMUL_IMP, REAL_LT_RMUL_IMP *)
98
99 let REAL_PROP_LT_LRMUL= REAL_LT_MUL2;; (* |- !w x y z. &0 <= w /\ w < x /\ &0 <= y /\ y < z ==> w * y < x * z *)
100 let REAL_PROP_LT_SQRT = SQRT_MONO_LT_EQ;; (* |- !x y. &0 <= x /\ &0 <= y ==> (sqrt x < sqrt y = x < y) *)
101
102 (* ------------------------------------------------------------------ *)
103 (* Constructors of Non-negative *)
104 (* ------------------------------------------------------------------ *)
105
106 let REAL_MK_NN_SQUARE = REAL_LE_SQUARE;; (* |- !x. &0 <= x * x *)
107 let REAL_MK_NN_ABS = REAL_ABS_POS;; (* 2010 *) (* |- !x. &0 <= abs x *)
108
109 (* moved here from float.hl *)
110
111 (* from 778 *)
112
113
114 let REAL_LE_LMUL_LOCAL = prove(
115   `!x y z. &0 < x ==> ((x * y) <= (x * z) <=> y <= z)`,
116   REPEAT GEN_TAC THEN DISCH_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN
117   AP_TERM_TAC THEN MATCH_MP_TAC REAL_LT_LMUL_EQ THEN ASM_REWRITE_TAC[]);;
118
119
120 let ABS_TRIANGLE = prove(
121   `!x y. abs(x + y) <= abs(x) + abs(y)`,
122   REPEAT GEN_TAC THEN REWRITE_TAC[real_abs] THEN
123   REPEAT COND_CASES_TAC THEN
124   REWRITE_TAC[REAL_NEG_ADD; REAL_LE_REFL; REAL_LE_LADD; REAL_LE_RADD] THEN
125   ASM_REWRITE_TAC[GSYM REAL_NEG_ADD; REAL_LE_NEGL; REAL_LE_NEGR] THEN
126   RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE]) THEN
127   TRY(MATCH_MP_TAC REAL_LT_IMP_LE) THEN TRY(FIRST_ASSUM ACCEPT_TAC) THEN
128   TRY(UNDISCH_TAC `(x + y) < &0`) THEN SUBST1_TAC(SYM(SPEC `&0` REAL_ADD_LID))
129   THEN REWRITE_TAC[REAL_NOT_LT] THEN
130   MAP_FIRST MATCH_MP_TAC [REAL_LT_ADD2; REAL_LE_ADD2] THEN
131   ASM_REWRITE_TAC[]);;
132
133 let REAL_LE_LMUL_IMP = prove(
134   `!x y z. &0 <= x /\ y <= z ==> (x * y) <= (x * z)`,
135   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
136   DISCH_THEN(DISJ_CASES_TAC o REWRITE_RULE[REAL_LE_LT]) THENL
137    [FIRST_ASSUM(fun th -> ASM_REWRITE_TAC[MATCH_MP REAL_LE_LMUL_LOCAL th]);
138     FIRST_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[REAL_MUL_LZERO] THEN
139     MATCH_ACCEPT_TAC REAL_LE_REFL]);;
140
141
142 (*   from ? *)
143
144 let ABS_POS = prove(
145   `!x. &0 <= abs(x)`,
146   GEN_TAC THEN ASM_CASES_TAC `&0 <= x` THENL
147    [ALL_TAC;
148     MP_TAC(SPEC `x:real` REAL_LE_NEGTOTAL) THEN ASM_REWRITE_TAC[] THEN
149     DISCH_TAC] THEN
150   ASM_REWRITE_TAC[real_abs]);;
151
152
153 let REAL_PROP_LE_LABS = prove(
154   `!x y z. (y <=. z) ==> ((abs x)* y <=. (abs x) *z)`,(SIMP_TAC[REAL_LE_LMUL_IMP;ABS_POS]));;
155
156 let REAL_LE_RMUL_IMP = prove(
157   `!x y z. &0 <= x /\ y <= z ==> (y * x) <= (z * x)`,
158   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN MATCH_ACCEPT_TAC REAL_LE_LMUL_IMP);;
159
160
161 (* ------------------------------------------------------------------ *)
162 (* Propagation of Non-negative *)
163 (* ------------------------------------------------------------------ *)
164
165 let REAL_PROP_NN_POS = prove(`! x y. x<. y ==> x <= y`,MESON_TAC[REAL_LT_LE]);;
166 let REAL_PROP_NN_ADD2 = REAL_LE_ADD (* |- !x y. &0 <= x /\ &0 <= y ==> &0 <= x + y *);;
167 let REAL_PROP_NN_DOUBLE = REAL_LE_DOUBLE (* |- !x. &0 <= x + x <=> &0 <= x *);;
168 let REAL_PROP_NN_RCANCEL= prove(`!x y. &.0 <. x /\ (&.0) <=. y*.x ==> ((&.0) <=. y)`,
169   MESON_TAC[REAL_PROP_LE_RCANCEL;REAL_MUL_LZERO]);;
170 let REAL_PROP_NN_LCANCEL= prove(`!x y. &.0 <. x /\ (&.0) <=. x*.y ==> ((&.0) <=. y)`,
171   MESON_TAC[REAL_PROP_LE_LCANCEL;REAL_MUL_RZERO]);;
172 let REAL_PROP_NN_MUL2 = REAL_LE_MUL (* |- !x y. &0 <= x /\ &0 <= y ==> &0 <= x * y *);;
173 let REAL_PROP_NN_POW = REAL_POW_LE (* |- !x n. &0 <= x ==> &0 <= x pow n *);;
174 let REAL_PROP_NN_SQUARE = REAL_LE_POW_2;; (* |- !x. &0 <= x pow 2 *)
175 let REAL_PROP_NN_SQRT = SQRT_POS_LE;; (* |- !x. &0 <= x ==> &0 <= sqrt x *)
176 let REAL_PROP_NN_INV = REAL_LE_INV_EQ (* |- !x. &0 <= inv x = &0 <= x *);;
177 let REAL_PROP_NN_SIN = SIN_POS_PI_LE;; (* |- !x. &0 <= x /\ x <= pi ==> &0 <= sin x *)
178 let REAL_PROP_NN_ATN = ATN_POS_LE;; (* |- &0 <= atn x = &0 <= x *)
179
180
181 (* ------------------------------------------------------------------ *)
182 (* Constructor of POS *)
183 (* ------------------------------------------------------------------ *)
184
185 let REAL_MK_POS_ABS = REAL_ABS_NZ (* |- !x. ~(x = &0) = &0 < abs x *);;
186 let REAL_MK_POS_EXP = REAL_EXP_POS_LT;; (* |- !x. &0 < exp x *)
187
188 (* let REAL_MK_POS_LN = LN_POS_LT;; (* |- !x. &1 < x ==> &0 < ln x *)  *)
189
190 let REAL_MK_POS_PI = PI_POS;; (* |- &0 < pi *)
191
192
193 (* ------------------------------------------------------------------ *)
194 (* Propagation of POS *)
195 (* ------------------------------------------------------------------ *)
196
197 let REAL_PROP_POS_ADD2 = REAL_LT_ADD (* |- !x y. &0 < x /\ &0 < y ==> &0 < x + y *);;
198 let REAL_PROP_POS_LADD = REAL_LET_ADD (* |- !x y. &0 <= x /\ &0 < y ==> &0 < x + y *);;
199 let REAL_PROP_POS_RADD = REAL_LTE_ADD (* |- !x y. &0 < x /\ &0 <= y ==> &0 < x + y *);;
200 let REAL_PROP_POS_LMUL = REAL_LT_MUL_EQ;; (* REAL_LT_LMUL_0;; *) (* |- !x y. &0 < x ==> (&0 < x * y = &0 < y) *)
201 let REAL_PROP_POS_RMUL = REAL_LT_MUL_EQ;; (* REAL_LT_RMUL_0;; *) (* |- !x y. &0 < y ==> (&0 < x * y = &0 < x) *)
202 let REAL_PROP_POS_MUL2 = REAL_LT_MUL (* |- !x y. &0 < x /\ &0 < y ==> &0 < x * y *);;
203 let REAL_PROP_POS_SQRT = SQRT_POS_LT;; (* |- !x. &0 < x ==> &0 < sqrt x *)
204 let REAL_PROP_POS_POW =  REAL_POW_LT (*  |- !x n. &0 < x ==> &0 < x pow n *);;
205 let REAL_PROP_POS_INV = REAL_LT_INV (* |- !x. &0 < x ==> &0 < inv x *);;
206 let REAL_PROP_POS_SIN = SIN_POS_PI;; (*  |- !x. &0 < x /\ x < pi ==> &0 < sin x *)
207 let REAL_PROP_POS_TAN = TAN_POS_PI2;; (* |- !x. &0 < x /\ x < pi / &2 ==> &0 < tan x *)
208 let REAL_PROP_POS_ATN = ATN_POS_LT;; (* |- &0 < atn x = &0 < x *)
209
210 (* ------------------------------------------------------------------ *)
211 (* Construction of NZ *)
212 (* ------------------------------------------------------------------ *)
213
214 (* renamed from REAL_MK_NZ_OF_POS *)
215 let REAL_MK_NZ_POS = REAL_POS_NZ (* |- !x. &0 < x ==> ~(x = &0) *);;
216 let REAL_MK_NZ_EXP = REAL_EXP_NZ;; (*  |- !x. ~(exp x = &0) *)
217
218 (* ------------------------------------------------------------------ *)
219 (* Propagation of NZ *)
220 (* ------------------------------------------------------------------ *)
221
222 (* renamed from REAL_ABS_NZ, moved from float.ml *)
223 let REAL_PROP_NZ_ABS =  prove(`!x. (~(x = (&.0))) ==> (~(abs(x) = (&.0)))`,
224     REWRITE_TAC[REAL_ABS_ZERO]);;
225 let REAL_PROP_NZ_POW = REAL_POW_NZ (*  |- !x n. ~(x = &0) ==> ~(x pow n = &0) *);;
226
227 (*
228 let REAL_PROP_NZ_INV = REAL_INV_NZ;; (* |- !x. ~(x = &0) ==> ~(inv x = &0) *)
229 *)
230
231 (* ------------------------------------------------------------------ *)
232 (* Propagation of ZERO *)
233 (* ------------------------------------------------------------------ *)
234
235 let REAL_PROP_ZERO_ABS = REAL_ABS_ZERO (* |- !x. (abs x = &0) = x = &0); *);;
236 (* let REAL_PROP_ZERO_NEG = REAL_NEG_EQ_0 ;; (*  |- !x. (--x = &0) = x = &0 *) *)
237 let REAL_PROP_ZERO_INV = REAL_INV_EQ_0 (* |- !x. (inv x = &0) = x = &0 *);;
238 (* let REAL_PROP_ZERO_NEG = REAL_NEG_EQ0;; (* |- !x. (--x = &0) = x = &0 *) *)
239 (* let REAL_PROP_ZERO_SUMSQ = REAL_SUMSQ;; (* |- !x y. (x * x + y * y = &0) = (x = &0) /\ (y = &0) *) *)
240 let REAL_PROP_ZERO_POW = REAL_POW_EQ_0;; (* |- !x n. (x pow n = &0) = (x = &0) /\ ~(n = 0) *)
241 let REAL_PROP_ZERO_SQRT = SQRT_EQ_0;; (* |- !x. &0 <= x ==> (x / sqrt x = sqrt x) *)
242
243 (* ------------------------------------------------------------------ *)
244 (* Special values of functions *)
245 (* ------------------------------------------------------------------ *)
246
247 let REAL_SV_LADD_0 = REAL_ADD_LID (* |- !x. &0 + x = x); *);;
248 let REAL_SV_INV_0 = REAL_INV_0 (*  |- inv (&0) = &0 *);;
249 let REAL_SV_RMUL_0 = REAL_MUL_RZERO (* |- !x. x * &0 = &0 *);;
250 let REAL_SV_LMUL_0 = REAL_MUL_LZERO (* |- !x. &0 * x = &0 *);;
251 let REAL_SV_NEG_0 = REAL_NEG_0 (*  |- -- &0 = &0 *);;
252 let REAL_SV_ABS_0 = REAL_ABS_0 (* |- abs (&0) = &0 *);;
253 let REAL_SV_EXP_0 = REAL_EXP_0;; (* |- exp (&0) = &1 *)
254 (* let REAL_SV_LN_1 = LN_1;; (* |- ln (&1) = &0 *) *)
255 let REAL_SV_SQRT_0 = SQRT_0;; (* |- sqrt (&0) = &0 *)
256 let REAL_SV_TAN_0 = TAN_0;; (*  |- tan (&0) = &0 *)
257 let REAL_SV_TAN_PI = TAN_PI;; (* |- tan pi = &0 *)
258
259 (* ------------------------------------------------------------------ *)
260 (* A tactic that multiplies a real on the left *)
261 (* ------------------------------------------------------------------ *)
262
263 (**
264 #g `a:real = b:real`;;
265 #e (REAL_LMUL_TAC `c:real`);;
266 it : goalstack = 2 subgoals (2 total)
267 `~(c = &0)`
268
269 `c * a = c * b`
270
271  0 [`~(c = &0)`]
272 #
273 **)
274 (* ------------------------------------------------------------------ *)
275
276
277
278 let REAL_LMUL_TAC t =
279   let REAL_MUL_LTIMES =
280         prove ((`!x a b.
281         (((~(x=(&0)) ==> (x*a = x*b)) /\ ~(x=(&0))) ==>  (a = b))`),
282                 MESON_TAC[REAL_EQ_MUL_LCANCEL]) in
283    (MATCH_MP_TAC (SPEC t REAL_MUL_LTIMES))
284    THEN CONJ_TAC
285    THENL [DISCH_TAC; ALL_TAC];;
286
287 (* ------------------------------------------------------------------ *)
288 (* Right multiply by a real *)
289 (* ------------------------------------------------------------------ *)
290
291 let REAL_RMUL_TAC t =
292   let REAL_MUL_RTIMES =
293         prove (`!x a b.
294                 ((~(x=(&0))==>(a*x = b*x)) /\ ~(x=(&0))) ==>  (a = b)`,
295                 MESON_TAC[REAL_EQ_MUL_RCANCEL]) in
296    (MATCH_MP_TAC (SPEC t REAL_MUL_RTIMES))
297    THEN CONJ_TAC
298    THENL [DISCH_TAC; ALL_TAC];;
299
300
301 pop_priority();;
302
303 end;;