Update from HH
[Multivariate Analysis/.git] / Multivariate / transcendentals.ml
1 (* ========================================================================= *)
2 (* Complex transcendentals and their real counterparts.                      *)
3 (*                                                                           *)
4 (*              (c) Copyright, John Harrison 1998-2008                       *)
5 (* ========================================================================= *)
6
7 needs "Multivariate/determinants.ml";;
8 needs "Multivariate/canal.ml";;
9
10 prioritize_complex();;
11
12 (* ------------------------------------------------------------------------- *)
13 (* The complex exponential function.                                         *)
14 (* ------------------------------------------------------------------------- *)
15
16 let cexp = new_definition
17  `cexp z = infsum (from 0) (\n. z pow n / Cx(&(FACT n)))`;;
18
19 let CEXP_0 = prove
20  (`cexp(Cx(&0)) = Cx(&1)`,
21   REWRITE_TAC[cexp] THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
22   MP_TAC(ISPECL [`\i. Cx(&0) pow i / Cx(&(FACT i))`; `{0}`; `from 0`]
23          SERIES_FINITE_SUPPORT) THEN
24   SIMP_TAC[FROM_0; INTER_UNIV; FINITE_INSERT; FINITE_RULES] THEN ANTS_TAC THENL
25    [INDUCT_TAC THEN REWRITE_TAC[IN_SING; NOT_SUC] THEN
26     REWRITE_TAC[complex_div; complex_pow; COMPLEX_MUL_LZERO; COMPLEX_VEC_0];
27     REWRITE_TAC[VSUM_SING; FACT; COMPLEX_DIV_1; complex_pow]]);;
28
29 let CEXP_CONVERGES_UNIFORMLY_CAUCHY = prove
30  (`!R e. &0 < e /\ &0 < R
31          ==> ?N. !m n z. m >= N /\ norm(z) <= R
32                          ==> norm(vsum(m..n) (\i. z pow i / Cx(&(FACT i))))
33                                      < e`,
34   REPEAT STRIP_TAC THEN
35   MP_TAC(ISPECL [`&1 / &2`; `\i. Cx(R) pow i / Cx(&(FACT i))`;
36                  `from 0`] SERIES_RATIO) THEN
37   REWRITE_TAC[SERIES_CAUCHY; LEFT_FORALL_IMP_THM] THEN
38   MP_TAC(SPEC `&2 * norm(Cx(R))` REAL_ARCH_SIMPLE) THEN
39   REWRITE_TAC[COMPLEX_NORM_CX; COMPLEX_NORM_DIV; COMPLEX_NORM_POW] THEN
40   CONV_TAC REAL_RAT_REDUCE_CONV THEN
41   MATCH_MP_TAC(TAUT `(a ==> b) /\ (c ==> d) ==> a ==> (b ==> c) ==> d`) THEN
42   CONJ_TAC THENL
43    [MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN
44     X_GEN_TAC `n:num` THEN REWRITE_TAC[GE] THEN DISCH_TAC THEN
45     SIMP_TAC[FACT; real_pow; GSYM REAL_OF_NUM_MUL; real_div; REAL_INV_MUL] THEN
46     REWRITE_TAC[REAL_ARITH
47      `(z * zn) * (is * ik) <= (&1 * inv(&2)) * zn * ik <=>
48       &0 <= (&1 - (&2 * z) * is) * zn * ik`] THEN
49     MATCH_MP_TAC REAL_LE_MUL THEN
50     SIMP_TAC[REAL_LE_MUL; REAL_POS; REAL_POW_LE; REAL_SUB_LE;
51              REAL_LE_INV_EQ; REAL_ABS_POS] THEN
52     ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LT_0] THEN
53     REPEAT(POP_ASSUM MP_TAC) THEN
54     REWRITE_TAC[GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_SUC] THEN
55     REAL_ARITH_TAC;
56     DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
57     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
58     REWRITE_TAC[FROM_0; INTER_UNIV] THEN
59     REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
60     DISCH_THEN(fun th -> REPEAT STRIP_TAC THEN MP_TAC th) THEN
61     ASM_SIMP_TAC[GSYM CX_DIV; GSYM CX_POW; VSUM_CX_NUMSEG; COMPLEX_NORM_CX] THEN
62     MATCH_MP_TAC(REAL_ARITH `x <= y ==> y < e ==> x < e`) THEN
63     SUBGOAL_THEN `abs (sum (m..n) (\i. R pow i / &(FACT i))) =
64                   sum (m..n) (\i. R pow i / &(FACT i))`
65     SUBST1_TAC THENL
66      [REWRITE_TAC[REAL_ABS_REFL] THEN MATCH_MP_TAC SUM_POS_LE_NUMSEG THEN
67       ASM_SIMP_TAC[REAL_LT_IMP_LE;REAL_LT_DIV; REAL_OF_NUM_LT;
68                    FACT_LT; REAL_POW_LT];
69       ALL_TAC] THEN
70     MATCH_MP_TAC VSUM_NORM_LE THEN REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG] THEN
71     X_GEN_TAC `i:num` THEN
72     REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_POW; COMPLEX_NORM_CX] THEN
73     SIMP_TAC[REAL_ABS_NUM; REAL_LE_DIV2_EQ; REAL_OF_NUM_LT; FACT_LT] THEN
74     ASM_SIMP_TAC[REAL_POW_LE2; NORM_POS_LE]]);;
75
76 let CEXP_CONVERGES = prove
77  (`!z. ((\n. z pow n / Cx(&(FACT n))) sums cexp(z)) (from 0)`,
78   GEN_TAC THEN REWRITE_TAC[cexp; SUMS_INFSUM; summable; SERIES_CAUCHY] THEN
79   REWRITE_TAC[FROM_0; INTER_UNIV] THEN
80   MP_TAC(SPEC `norm(z:complex) + &1` CEXP_CONVERGES_UNIFORMLY_CAUCHY) THEN
81   SIMP_TAC[REAL_ARITH `&0 <= x ==> &0 < x + &1`; NORM_POS_LE] THEN
82   MESON_TAC[REAL_ARITH `x <= x + &1`]);;
83
84 let CEXP_CONVERGES_UNIQUE = prove
85  (`!w z. ((\n. z pow n / Cx(&(FACT n))) sums w) (from 0) <=> w = cexp(z)`,
86   REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[CEXP_CONVERGES] THEN
87   DISCH_THEN(MP_TAC o C CONJ (SPEC `z:complex` CEXP_CONVERGES)) THEN
88   REWRITE_TAC[SERIES_UNIQUE]);;
89
90 let CEXP_CONVERGES_UNIFORMLY = prove
91  (`!R e. &0 < R /\ &0 < e
92          ==> ?N. !n z. n >= N /\ norm(z) < R
93                        ==> norm(vsum(0..n) (\i. z pow i / Cx(&(FACT i))) -
94                                 cexp(z)) <= e`,
95   REPEAT STRIP_TAC THEN
96   MP_TAC(SPECL [`R:real`; `e / &2`] CEXP_CONVERGES_UNIFORMLY_CAUCHY) THEN
97   ASM_REWRITE_TAC[REAL_HALF] THEN MATCH_MP_TAC MONO_EXISTS THEN
98   X_GEN_TAC `N:num` THEN DISCH_TAC THEN
99   MAP_EVERY X_GEN_TAC [`n:num`; `z:complex`] THEN STRIP_TAC THEN
100   MP_TAC(SPEC `z:complex` CEXP_CONVERGES) THEN
101   REWRITE_TAC[sums; LIM_SEQUENTIALLY; FROM_0; INTER_UNIV; dist] THEN
102   DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
103   DISCH_THEN(X_CHOOSE_THEN `M:num` (MP_TAC o SPEC `n + M + 1`)) THEN
104   FIRST_X_ASSUM(MP_TAC o SPECL [`n + 1`; `n + M + 1`; `z:complex`]) THEN
105   ASM_SIMP_TAC[ARITH_RULE `(n >= N ==> n + 1 >= N) /\ M <= n + M + 1`] THEN
106   ASM_SIMP_TAC[REAL_LT_IMP_LE; VSUM_ADD_SPLIT; LE_0] THEN
107   CONV_TAC(ONCE_DEPTH_CONV(ALPHA_CONV `i:num`)) THEN NORM_ARITH_TAC);;
108
109 let HAS_COMPLEX_DERIVATIVE_CEXP = prove
110  (`!z. (cexp has_complex_derivative cexp(z)) (at z)`,
111   REPEAT GEN_TAC THEN MP_TAC(ISPECL
112    [`ball(Cx(&0),norm(z:complex) + &1)`;
113     `\n z. z pow n / Cx(&(FACT n))`;
114     `\n z. if n = 0 then Cx(&0) else z pow (n-1) / Cx(&(FACT(n-1)))`;
115     `cexp:complex->complex`;
116     `(from 0)`]
117    HAS_COMPLEX_DERIVATIVE_SERIES) THEN
118   REWRITE_TAC[CONVEX_BALL; OPEN_BALL; IN_BALL; dist] THEN
119   SIMP_TAC[HAS_COMPLEX_DERIVATIVE_WITHIN_OPEN; OPEN_BALL; IN_BALL;
120            dist; COMPLEX_SUB_LZERO; COMPLEX_SUB_RZERO; NORM_NEG] THEN
121   ANTS_TAC THEN REPEAT CONJ_TAC THENL
122    [X_GEN_TAC `n:num` THEN REPEAT STRIP_TAC THEN COMPLEX_DIFF_TAC THEN
123     SPEC_TAC(`n:num`,`n:num`) THEN INDUCT_TAC THEN
124     REWRITE_TAC[ARITH; complex_div; COMPLEX_MUL_LZERO] THEN
125     MP_TAC(SPECL [`&n + &1`; `&0`] CX_INJ) THEN
126     REWRITE_TAC[NOT_SUC; SUC_SUB1; GSYM REAL_OF_NUM_SUC; FACT;
127          CX_ADD; CX_MUL; GSYM REAL_OF_NUM_MUL; COMPLEX_INV_MUL] THEN
128     REWRITE_TAC[REAL_ARITH `~(&n + &1 = &0)`] THEN
129     ABBREV_TAC `a = inv(Cx(&(FACT n)))` THEN CONV_TAC COMPLEX_FIELD;
130     REPEAT STRIP_TAC THEN
131     MP_TAC(SPECL [`norm(z:complex) + &1`; `e:real`]
132        CEXP_CONVERGES_UNIFORMLY) THEN
133     ASM_SIMP_TAC[NORM_POS_LE; REAL_ARITH `&0 <= x ==> &0 < x + &1`] THEN
134     DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN EXISTS_TAC `N + 1` THEN
135     MAP_EVERY X_GEN_TAC [`n:num`; `w:complex`] THEN STRIP_TAC THEN
136     FIRST_X_ASSUM(MP_TAC o SPECL [`n - 1`; `w:complex`]) THEN
137     ASM_SIMP_TAC[ARITH_RULE `n >= m + 1 ==> n - 1 >= m`] THEN
138     REWRITE_TAC[FROM_0; INTER_UNIV] THEN MATCH_MP_TAC EQ_IMP THEN
139     AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
140     AP_THM_TAC THEN AP_TERM_TAC THEN
141     SUBGOAL_THEN `0..n = 0 INSERT (IMAGE SUC (0..n-1))` SUBST1_TAC THENL
142      [REWRITE_TAC[EXTENSION; IN_INSERT; IN_IMAGE; IN_NUMSEG] THEN
143       INDUCT_TAC THEN REWRITE_TAC[LE_0; NOT_SUC; SUC_INJ; UNWIND_THM1] THEN
144       UNDISCH_TAC `n >= N + 1` THEN ARITH_TAC;
145       ALL_TAC] THEN
146     SIMP_TAC[VSUM_CLAUSES; FINITE_IMAGE; FINITE_NUMSEG] THEN
147     REWRITE_TAC[IN_IMAGE; NOT_SUC; COMPLEX_ADD_LID] THEN
148     SIMP_TAC[VSUM_IMAGE; FINITE_NUMSEG; SUC_INJ] THEN
149     MATCH_MP_TAC VSUM_EQ THEN SIMP_TAC[IN_NUMSEG; NOT_SUC; o_THM; SUC_SUB1];
150     MAP_EVERY EXISTS_TAC [`Cx(&0)`; `cexp(Cx(&0))`] THEN
151     REWRITE_TAC[CEXP_CONVERGES; COMPLEX_NORM_0] THEN
152     SIMP_TAC[REAL_ARITH `&0 <= z ==> &0 < z + &1`; NORM_POS_LE];
153     DISCH_THEN(X_CHOOSE_THEN `g:complex->complex` MP_TAC) THEN
154     REWRITE_TAC[CEXP_CONVERGES_UNIQUE] THEN STRIP_TAC THEN
155     MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_AT THEN
156     MAP_EVERY EXISTS_TAC [`g:complex->complex`; `&1`] THEN
157     REWRITE_TAC[REAL_LT_01] THEN CONJ_TAC THENL
158      [ALL_TAC;
159       FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN
160       ANTS_TAC THENL [REAL_ARITH_TAC; SIMP_TAC[]]] THEN
161     POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_FORALL THEN
162     X_GEN_TAC `w:complex` THEN MATCH_MP_TAC MONO_IMP THEN SIMP_TAC[] THEN
163     NORM_ARITH_TAC]);;
164
165 let COMPLEX_DIFFERENTIABLE_AT_CEXP = prove
166  (`!z. cexp complex_differentiable at z`,
167   REWRITE_TAC[complex_differentiable] THEN
168   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CEXP]);;
169
170 let COMPLEX_DIFFERENTIABLE_WITHIN_CEXP = prove
171  (`!s z. cexp complex_differentiable (at z within s)`,
172   MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN;
173             COMPLEX_DIFFERENTIABLE_AT_CEXP]);;
174
175 let CONTINUOUS_AT_CEXP = prove
176  (`!z. cexp continuous at z`,
177   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CEXP;
178             HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);;
179
180 let CONTINUOUS_WITHIN_CEXP = prove
181  (`!s z. cexp continuous (at z within s)`,
182   MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CEXP]);;
183
184 let CONTINUOUS_ON_CEXP = prove
185  (`!s. cexp continuous_on s`,
186   MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CEXP]);;
187
188 let HOLOMORPHIC_ON_CEXP = prove
189  (`!s. cexp holomorphic_on s`,
190   REWRITE_TAC [holomorphic_on] THEN
191   MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CEXP]);;
192
193 (* ------------------------------------------------------------------------- *)
194 (* Add it to the database.                                                   *)
195 (* ------------------------------------------------------------------------- *)
196
197 add_complex_differentiation_theorems
198  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
199    (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN_UNIV
200              HAS_COMPLEX_DERIVATIVE_CEXP)));;
201
202 (* ------------------------------------------------------------------------- *)
203 (* Hence the main results.                                                   *)
204 (* ------------------------------------------------------------------------- *)
205
206 let CEXP_ADD_MUL = prove
207  (`!w z. cexp(w + z) * cexp(--z) = cexp(w)`,
208   GEN_TAC THEN
209   ONCE_REWRITE_TAC[SET_RULE `(!x. P x) <=> (!x. x IN UNIV ==> P x)`] THEN
210   MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_ZERO_UNIQUE THEN
211   EXISTS_TAC `Cx(&0)` THEN REWRITE_TAC[OPEN_UNIV; CONVEX_UNIV; IN_UNIV] THEN
212   REWRITE_TAC[COMPLEX_ADD_RID; COMPLEX_NEG_0; CEXP_0; COMPLEX_MUL_RID] THEN
213   GEN_TAC THEN COMPLEX_DIFF_TAC THEN CONV_TAC COMPLEX_RING);;
214
215 let CEXP_NEG_RMUL = prove
216  (`!z. cexp(z) * cexp(--z) = Cx(&1)`,
217   MP_TAC(SPEC `Cx(&0)` CEXP_ADD_MUL) THEN MATCH_MP_TAC MONO_FORALL THEN
218   SIMP_TAC[COMPLEX_ADD_LID; CEXP_0]);;
219
220 let CEXP_NEG_LMUL = prove
221  (`!z. cexp(--z) * cexp(z) = Cx(&1)`,
222   ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN REWRITE_TAC[CEXP_NEG_RMUL]);;
223
224 let CEXP_NEG = prove
225  (`!z. cexp(--z) = inv(cexp z)`,
226   MP_TAC CEXP_NEG_LMUL THEN MATCH_MP_TAC MONO_FORALL THEN
227   CONV_TAC COMPLEX_FIELD);;
228
229 let CEXP_ADD = prove
230  (`!w z. cexp(w + z) = cexp(w) * cexp(z)`,
231   REPEAT GEN_TAC THEN
232   MP_TAC(SPECL [`w:complex`; `z:complex`] CEXP_ADD_MUL) THEN
233   MP_TAC(SPEC `z:complex` CEXP_NEG_LMUL) THEN CONV_TAC COMPLEX_FIELD);;
234
235 let CEXP_SUB = prove
236  (`!w z. cexp(w - z) = cexp(w) / cexp(z)`,
237   REPEAT GEN_TAC THEN
238   REWRITE_TAC[complex_sub; complex_div; CEXP_ADD; CEXP_NEG]);;
239
240 let CEXP_NZ = prove
241  (`!z. ~(cexp(z) = Cx(&0))`,
242   MP_TAC CEXP_NEG_LMUL THEN MATCH_MP_TAC MONO_FORALL THEN
243   CONV_TAC COMPLEX_FIELD);;
244
245 let CEXP_N = prove
246  (`!n x. cexp(Cx(&n) * x) = cexp(x) pow n`,
247   INDUCT_TAC THEN REWRITE_TAC[GSYM REAL_OF_NUM_SUC; CX_ADD] THEN
248   REWRITE_TAC[COMPLEX_MUL_LZERO; complex_pow; CEXP_0] THEN
249   ASM_REWRITE_TAC[COMPLEX_ADD_RDISTRIB; CEXP_ADD; COMPLEX_MUL_LID] THEN
250   REWRITE_TAC[COMPLEX_MUL_AC]);;
251
252 let CEXP_VSUM = prove
253  (`!f s. FINITE s ==> cexp(vsum s f) = cproduct s (\x. cexp(f x))`,
254   GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
255   SIMP_TAC[VSUM_CLAUSES; CPRODUCT_CLAUSES; CEXP_ADD; COMPLEX_VEC_0; CEXP_0]);;
256
257 let LIM_CEXP_MINUS_1 = prove
258  (`((\z. (cexp(z) - Cx(&1)) / z) --> Cx(&1)) (at (Cx(&0)))`,
259   MP_TAC(COMPLEX_DIFF_CONV
260       `((\z. cexp(z) - Cx(&1)) has_complex_derivative f') (at(Cx(&0)))`) THEN
261   REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_AT; CEXP_0; COMPLEX_SUB_REFL] THEN
262   REWRITE_TAC[COMPLEX_MUL_LID; COMPLEX_SUB_RZERO]);;
263
264 (* ------------------------------------------------------------------------- *)
265 (* Crude bounds on complex exponential function, usable to get tighter ones. *)
266 (* ------------------------------------------------------------------------- *)
267
268 let CEXP_BOUND_BLEMMA = prove
269  (`!B. (!z. norm(z) <= &1 / &2 ==> norm(cexp z) <= B)
270        ==> !z. norm(z) <= &1 / &2 ==> norm(cexp z) <= &1 + B / &2`,
271   REPEAT STRIP_TAC THEN
272   MP_TAC(ISPECL [`cexp`; `cexp`; `cball(Cx(&0),&1 / &2)`; `B:real`]
273                 COMPLEX_DIFFERENTIABLE_BOUND) THEN
274   ASM_SIMP_TAC[CONVEX_CBALL; IN_CBALL; dist; COMPLEX_SUB_LZERO; NORM_NEG;
275     HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CEXP] THEN
276   DISCH_THEN(MP_TAC o SPECL [`z:complex`; `Cx(&0)`]) THEN
277   REWRITE_TAC[COMPLEX_NORM_0; CEXP_0; COMPLEX_SUB_RZERO] THEN
278   CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN
279   MATCH_MP_TAC(NORM_ARITH
280    `norm(y) = &1 /\ d <= e ==> norm(x - y) <= d ==> norm(x) <= &1 + e`) THEN
281   REWRITE_TAC[COMPLEX_NORM_CX; real_div; REAL_ABS_NUM] THEN
282   MATCH_MP_TAC REAL_LE_LMUL THEN FIRST_X_ASSUM(MP_TAC o SPEC `Cx(&0)`) THEN
283   REWRITE_TAC[COMPLEX_NORM_CX] THEN POP_ASSUM MP_TAC THEN
284   NORM_ARITH_TAC);;
285
286 let CEXP_BOUND_HALF = prove
287  (`!z. norm(z) <= &1 / &2 ==> norm(cexp z) <= &2`,
288   REPEAT STRIP_TAC THEN
289   MP_TAC(ISPECL [`IMAGE cexp (cball(Cx(&0),&1 / &2))`; `Cx(&0)`]
290     DISTANCE_ATTAINS_SUP) THEN
291   SIMP_TAC[COMPACT_CONTINUOUS_IMAGE; COMPACT_CBALL; CONTINUOUS_ON_CEXP;
292            IMAGE_EQ_EMPTY; CBALL_EQ_EMPTY; FORALL_IN_IMAGE; EXISTS_IN_IMAGE;
293            IN_CBALL; dist; COMPLEX_SUB_LZERO; NORM_NEG] THEN
294   CONV_TAC REAL_RAT_REDUCE_CONV THEN
295   DISCH_THEN(X_CHOOSE_THEN `w:complex` STRIP_ASSUME_TAC) THEN
296   FIRST_ASSUM(MP_TAC o SPEC `w:complex` o MATCH_MP CEXP_BOUND_BLEMMA) THEN
297   FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN
298   ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
299
300 let CEXP_BOUND_LEMMA = prove
301  (`!z. norm(z) <= &1 / &2 ==> norm(cexp z) <= &1 + &2 * norm(z)`,
302   REPEAT STRIP_TAC THEN
303   MP_TAC(ISPECL [`cexp`; `cexp`; `cball(Cx(&0),&1 / &2)`; `&2`]
304                 COMPLEX_DIFFERENTIABLE_BOUND) THEN
305   ASM_SIMP_TAC[CONVEX_CBALL; IN_CBALL; dist; COMPLEX_SUB_LZERO; NORM_NEG;
306                HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CEXP;
307                CEXP_BOUND_HALF] THEN
308   DISCH_THEN(MP_TAC o SPECL [`z:complex`; `Cx(&0)`]) THEN
309   REWRITE_TAC[COMPLEX_NORM_0; CEXP_0; COMPLEX_SUB_RZERO] THEN
310   CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN
311   MATCH_MP_TAC(NORM_ARITH
312    `norm(y) = &1 ==> norm(x - y) <= d ==> norm(x) <= &1 + d`) THEN
313   REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM]);;
314
315 (* ------------------------------------------------------------------------- *)
316 (* Complex trig functions.                                                   *)
317 (* ------------------------------------------------------------------------- *)
318
319 let ccos = new_definition
320   `ccos z = (cexp(ii * z) + cexp(--ii * z)) / Cx(&2)`;;
321
322 let csin = new_definition
323   `csin z = (cexp(ii * z) - cexp(--ii * z)) / (Cx(&2) * ii)`;;
324
325 let CSIN_0 = prove
326  (`csin(Cx(&0)) = Cx(&0)`,
327   REWRITE_TAC[csin; COMPLEX_MUL_RZERO; COMPLEX_SUB_REFL] THEN
328   CONV_TAC COMPLEX_FIELD);;
329
330 let CCOS_0 = prove
331  (`ccos(Cx(&0)) = Cx(&1)`,
332   REWRITE_TAC[ccos; COMPLEX_MUL_RZERO; CEXP_0] THEN
333   CONV_TAC COMPLEX_FIELD);;
334
335 let CSIN_CIRCLE = prove
336  (`!z. csin(z) pow 2 + ccos(z) pow 2 = Cx(&1)`,
337   GEN_TAC THEN REWRITE_TAC[csin; ccos] THEN
338   MP_TAC(SPEC `ii * z` CEXP_NEG_LMUL) THEN
339   REWRITE_TAC[COMPLEX_MUL_LNEG] THEN
340   CONV_TAC COMPLEX_FIELD);;
341
342 let CSIN_ADD = prove
343  (`!w z. csin(w + z) = csin(w) * ccos(z) + ccos(w) * csin(z)`,
344   REPEAT GEN_TAC THEN
345   REWRITE_TAC[csin; ccos; COMPLEX_ADD_LDISTRIB; CEXP_ADD] THEN
346   CONV_TAC COMPLEX_FIELD);;
347
348 let CCOS_ADD = prove
349  (`!w z. ccos(w + z) = ccos(w) * ccos(z) - csin(w) * csin(z)`,
350   REPEAT GEN_TAC THEN
351   REWRITE_TAC[csin; ccos; COMPLEX_ADD_LDISTRIB; CEXP_ADD] THEN
352   CONV_TAC COMPLEX_FIELD);;
353
354 let CSIN_NEG = prove
355  (`!z. csin(--z) = --(csin(z))`,
356   REWRITE_TAC[csin; COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG; COMPLEX_NEG_NEG] THEN
357   CONV_TAC COMPLEX_FIELD);;
358
359 let CCOS_NEG = prove
360  (`!z. ccos(--z) = ccos(z)`,
361   REWRITE_TAC[ccos; COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG; COMPLEX_NEG_NEG] THEN
362   CONV_TAC COMPLEX_FIELD);;
363
364 let CSIN_DOUBLE = prove
365  (`!z. csin(Cx(&2) * z) = Cx(&2) * csin(z) * ccos(z)`,
366   REWRITE_TAC[COMPLEX_RING `Cx(&2) * x = x + x`; CSIN_ADD] THEN
367   CONV_TAC COMPLEX_RING);;
368
369 let CCOS_DOUBLE = prove
370  (`!z. ccos(Cx(&2) * z) = (ccos(z) pow 2) - (csin(z) pow 2)`,
371   REWRITE_TAC[COMPLEX_RING `Cx(&2) * x = x + x`; CCOS_ADD] THEN
372   CONV_TAC COMPLEX_RING);;
373
374 let CSIN_SUB = prove
375  (`!w z. csin(w - z) = csin(w) * ccos(z) - ccos(w) * csin(z)`,
376   REWRITE_TAC[complex_sub; COMPLEX_MUL_RNEG; CSIN_ADD; CSIN_NEG; CCOS_NEG]);;
377
378 let CCOS_SUB = prove
379  (`!w z. ccos(w - z) = ccos(w) * ccos(z) + csin(w) * csin(z)`,
380   REWRITE_TAC[complex_sub; CCOS_ADD; CSIN_NEG; CCOS_NEG;
381               COMPLEX_MUL_RNEG; COMPLEX_NEG_NEG]);;
382
383 let COMPLEX_MUL_CSIN_CSIN = prove
384  (`!w z. csin(w) * csin(z) = (ccos(w - z) - ccos(w + z)) / Cx(&2)`,
385   REWRITE_TAC[CCOS_ADD; CCOS_SUB] THEN CONV_TAC COMPLEX_RING);;
386
387 let COMPLEX_MUL_CSIN_CCOS = prove
388  (`!w z. csin(w) * ccos(z) = (csin(w + z) + csin(w - z)) / Cx(&2)`,
389   REWRITE_TAC[CSIN_ADD; CSIN_SUB] THEN CONV_TAC COMPLEX_RING);;
390
391 let COMPLEX_MUL_CCOS_CSIN = prove
392  (`!w z. ccos(w) * csin(z) = (csin(w + z) - csin(w - z)) / Cx(&2)`,
393   REWRITE_TAC[CSIN_ADD; CSIN_SUB] THEN CONV_TAC COMPLEX_RING);;
394
395 let COMPLEX_MUL_CCOS_CCOS = prove
396  (`!w z. ccos(w) * ccos(z) = (ccos(w - z) + ccos(w + z)) / Cx(&2)`,
397   REWRITE_TAC[CCOS_ADD; CCOS_SUB] THEN CONV_TAC COMPLEX_RING);;
398
399 let COMPLEX_ADD_CSIN = prove
400  (`!w z. csin(w) + csin(z) =
401          Cx(&2) * csin((w + z) / Cx(&2)) * ccos((w - z) / Cx(&2))`,
402   SIMP_TAC[COMPLEX_MUL_CSIN_CCOS; COMPLEX_RING `Cx(&2) * x / Cx(&2) = x`] THEN
403   REPEAT GEN_TAC THEN BINOP_TAC THEN AP_TERM_TAC THEN CONV_TAC COMPLEX_RING);;
404
405 let COMPLEX_SUB_CSIN = prove
406  (`!w z. csin(w) - csin(z) =
407          Cx(&2) * csin((w - z) / Cx(&2)) * ccos((w + z) / Cx(&2))`,
408   SIMP_TAC[COMPLEX_MUL_CSIN_CCOS; COMPLEX_RING `Cx(&2) * x / Cx(&2) = x`] THEN
409   REPEAT GEN_TAC THEN REWRITE_TAC[complex_sub; GSYM CSIN_NEG] THEN
410   BINOP_TAC THEN AP_TERM_TAC THEN CONV_TAC COMPLEX_RING);;
411
412 let COMPLEX_ADD_CCOS = prove
413  (`!w z. ccos(w) + ccos(z) =
414          Cx(&2) * ccos((w + z) / Cx(&2)) * ccos((w - z) / Cx(&2))`,
415   SIMP_TAC[COMPLEX_MUL_CCOS_CCOS; COMPLEX_RING `Cx(&2) * x / Cx(&2) = x`] THEN
416   REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [COMPLEX_ADD_SYM] THEN
417   BINOP_TAC THEN AP_TERM_TAC THEN CONV_TAC COMPLEX_RING);;
418
419 let COMPLEX_SUB_CCOS = prove
420  (`!w z. ccos(w) - ccos(z) =
421          Cx(&2) * csin((w + z) / Cx(&2)) * csin((z - w) / Cx(&2))`,
422   SIMP_TAC[COMPLEX_MUL_CSIN_CSIN; COMPLEX_RING `Cx(&2) * x / Cx(&2) = x`] THEN
423   REPEAT GEN_TAC THEN BINOP_TAC THEN AP_TERM_TAC THEN CONV_TAC COMPLEX_RING);;
424
425 let CCOS_DOUBLE_CCOS = prove
426  (`!z. ccos(Cx(&2) * z) = Cx(&2) * ccos z pow 2 - Cx(&1)`,
427   GEN_TAC THEN REWRITE_TAC[COMPLEX_RING `Cx(&2) * x = x + x`; CCOS_ADD] THEN
428   MP_TAC(SPEC `z:complex` CSIN_CIRCLE) THEN CONV_TAC COMPLEX_RING);;
429
430 let CCOS_DOUBLE_CSIN = prove
431  (`!z. ccos(Cx(&2) * z) = Cx(&1) - Cx(&2) * csin z pow 2`,
432   GEN_TAC THEN REWRITE_TAC[COMPLEX_RING `Cx(&2) * x = x + x`; CCOS_ADD] THEN
433   MP_TAC(SPEC `z:complex` CSIN_CIRCLE) THEN CONV_TAC COMPLEX_RING);;
434
435 (* ------------------------------------------------------------------------- *)
436 (* Euler and de Moivre formulas.                                             *)
437 (* ------------------------------------------------------------------------- *)
438
439 let CEXP_EULER = prove
440  (`!z. cexp(ii * z) = ccos(z) + ii * csin(z)`,
441   REWRITE_TAC[ccos; csin] THEN CONV_TAC COMPLEX_FIELD);;
442
443 let DEMOIVRE = prove
444  (`!z n. (ccos z + ii * csin z) pow n =
445          ccos(Cx(&n) * z) + ii * csin(Cx(&n) * z)`,
446   REWRITE_TAC[GSYM CEXP_EULER; GSYM CEXP_N] THEN
447   REWRITE_TAC[COMPLEX_MUL_AC]);;
448
449 (* ------------------------------------------------------------------------- *)
450 (* Real exponential function. Same names as old Library/transc.ml.           *)
451 (* ------------------------------------------------------------------------- *)
452
453 let exp = new_definition `exp(x) = Re(cexp(Cx x))`;;
454
455 let CNJ_CEXP = prove
456  (`!z. cnj(cexp z) = cexp(cnj z)`,
457   GEN_TAC THEN MATCH_MP_TAC SERIES_UNIQUE THEN
458   MAP_EVERY EXISTS_TAC [`\n. cnj(z pow n / Cx(&(FACT n)))`; `from 0`] THEN
459   CONJ_TAC THENL
460    [REWRITE_TAC[SUMS_CNJ; CEXP_CONVERGES];
461     REWRITE_TAC[CNJ_DIV; CNJ_CX; CNJ_POW; CEXP_CONVERGES]]);;
462
463 let REAL_EXP = prove
464  (`!z. real z ==> real(cexp z)`,
465   SIMP_TAC[REAL_CNJ; CNJ_CEXP]);;
466
467 let CX_EXP = prove
468  (`!x. Cx(exp x) = cexp(Cx x)`,
469   REWRITE_TAC[exp] THEN MESON_TAC[REAL; REAL_CX; REAL_EXP]);;
470
471 let REAL_EXP_ADD = prove
472  (`!x y. exp(x + y) = exp(x) * exp(y)`,
473   REWRITE_TAC[GSYM CX_INJ; CX_MUL; CX_EXP; CX_ADD; CEXP_ADD]);;
474
475 let REAL_EXP_0 = prove
476  (`exp(&0) = &1`,
477   REWRITE_TAC[GSYM CX_INJ; CX_EXP; CEXP_0]);;
478
479 let REAL_EXP_ADD_MUL = prove
480  (`!x y. exp(x + y) * exp(--x) = exp(y)`,
481   ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN
482   REWRITE_TAC[GSYM CX_INJ; CX_MUL; CX_EXP; CX_ADD; CX_NEG; CEXP_ADD_MUL]);;
483
484 let REAL_EXP_NEG_MUL = prove
485  (`!x. exp(x) * exp(--x) = &1`,
486   REWRITE_TAC[GSYM CX_INJ; CX_MUL; CX_EXP; CX_NEG; CEXP_NEG_RMUL]);;
487
488 let REAL_EXP_NEG_MUL2 = prove
489  (`!x. exp(--x) * exp(x) = &1`,
490   REWRITE_TAC[GSYM CX_INJ; CX_MUL; CX_EXP; CX_NEG; CEXP_NEG_LMUL]);;
491
492 let REAL_EXP_NEG = prove
493  (`!x. exp(--x) = inv(exp(x))`,
494   REWRITE_TAC[GSYM CX_INJ; CX_INV; CX_EXP; CX_NEG; CEXP_NEG]);;
495
496 let REAL_EXP_N = prove
497  (`!n x. exp(&n * x) = exp(x) pow n`,
498   REWRITE_TAC[GSYM CX_INJ; CX_EXP; CX_POW; CX_MUL; CEXP_N]);;
499
500 let REAL_EXP_SUB = prove
501  (`!x y. exp(x - y) = exp(x) / exp(y)`,
502   REWRITE_TAC[GSYM CX_INJ; CX_SUB; CX_DIV; CX_EXP; CEXP_SUB]);;
503
504 let REAL_EXP_NZ = prove
505  (`!x. ~(exp(x) = &0)`,
506   REWRITE_TAC[GSYM CX_INJ; CX_EXP; CEXP_NZ]);;
507
508 let REAL_EXP_POS_LE = prove
509  (`!x. &0 <= exp(x)`,
510   GEN_TAC THEN SUBST1_TAC(REAL_ARITH `x = x / &2 + x / &2`) THEN
511   REWRITE_TAC[REAL_EXP_ADD; REAL_LE_SQUARE]);;
512
513 let REAL_EXP_POS_LT = prove
514  (`!x. &0 < exp(x)`,
515   REWRITE_TAC[REAL_LT_LE; REAL_EXP_NZ; REAL_EXP_POS_LE]);;
516
517 let REAL_EXP_LE_X = prove
518  (`!x. &0 <= x ==> &1 + x <= exp(x)`,
519   REPEAT STRIP_TAC THEN REWRITE_TAC[exp; RE_DEF] THEN
520   MATCH_MP_TAC(MATCH_MP
521    (ONCE_REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`]
522         LIM_COMPONENT_LBOUND)
523    (REWRITE_RULE[sums] (SPEC `Cx x` CEXP_CONVERGES))) THEN
524   SIMP_TAC[DIMINDEX_2; ARITH; TRIVIAL_LIMIT_SEQUENTIALLY;
525            VSUM_COMPONENT; EVENTUALLY_SEQUENTIALLY; FROM_0; INTER_UNIV] THEN
526   REWRITE_TAC[GSYM CX_DIV; GSYM RE_DEF; RE_CX; GSYM CX_POW] THEN
527   EXISTS_TAC `1` THEN SIMP_TAC[SUM_CLAUSES_LEFT; LE_0; ADD_CLAUSES] THEN
528   CONV_TAC NUM_REDUCE_CONV THEN
529   SIMP_TAC[real_pow; REAL_POW_1; REAL_DIV_1; REAL_LE_ADDR; REAL_ADD_ASSOC] THEN
530   ASM_SIMP_TAC[SUM_POS_LE_NUMSEG; REAL_LE_DIV; REAL_POW_LE; REAL_POS]);;
531
532 let REAL_EXP_LT_1 = prove
533  (`!x. &0 < x ==> &1 < exp(x)`,
534   MP_TAC REAL_EXP_LE_X THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);;
535
536 let REAL_EXP_MONO_IMP = prove
537  (`!x y. x < y ==> exp(x) < exp(y)`,
538   REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM REAL_SUB_LT] THEN
539   DISCH_THEN(MP_TAC o MATCH_MP REAL_EXP_LT_1) THEN
540   SIMP_TAC[REAL_EXP_SUB; REAL_LT_RDIV_EQ; REAL_EXP_POS_LT; REAL_MUL_LID]);;
541
542 let REAL_EXP_MONO_LT = prove
543  (`!x y. exp(x) < exp(y) <=> x < y`,
544   REPEAT GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH
545    `(x < y ==> f < g) /\ (x = y ==> f = g) /\ (y < x ==> g < f)
546     ==> (f < g <=> x < y)`) THEN
547   SIMP_TAC[REAL_EXP_MONO_IMP]);;
548
549 let REAL_EXP_MONO_LE = prove
550  (`!x y. exp(x) <= exp(y) <=> x <= y`,
551   REWRITE_TAC[GSYM REAL_NOT_LT; REAL_EXP_MONO_LT]);;
552
553 let REAL_EXP_INJ = prove
554  (`!x y. (exp(x) = exp(y)) <=> (x = y)`,
555   REWRITE_TAC[GSYM REAL_LE_ANTISYM; REAL_EXP_MONO_LE]);;
556
557 let REAL_EXP_EQ_1 = prove
558  (`!x. exp(x) = &1 <=> x = &0`,
559   ONCE_REWRITE_TAC[GSYM REAL_EXP_0] THEN REWRITE_TAC[REAL_EXP_INJ]);;
560
561 let REAL_ABS_EXP = prove
562  (`!x. abs(exp x) = exp x`,
563   REWRITE_TAC[real_abs; REAL_EXP_POS_LE]);;
564
565 let REAL_EXP_SUM = prove
566  (`!f s. FINITE s ==> exp(sum s f) = product s (\x. exp(f x))`,
567   GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
568   SIMP_TAC[SUM_CLAUSES; PRODUCT_CLAUSES; REAL_EXP_ADD; REAL_EXP_0]);;
569
570 let REAL_EXP_BOUND_LEMMA = prove
571  (`!x. &0 <= x /\ x <= inv(&2) ==> exp(x) <= &1 + &2 * x`,
572   REPEAT STRIP_TAC THEN MP_TAC(SPEC `Cx x` CEXP_BOUND_LEMMA) THEN
573   REWRITE_TAC[GSYM CX_EXP; COMPLEX_NORM_CX; RE_CX] THEN
574   ASM_REAL_ARITH_TAC);;
575
576 (* ------------------------------------------------------------------------- *)
577 (* Real trig functions, their reality,  derivatives of complex versions.     *)
578 (* ------------------------------------------------------------------------- *)
579
580 let sin = new_definition `sin(x) = Re(csin(Cx x))`;;
581
582 let cos = new_definition `cos(x) = Re(ccos(Cx x))`;;
583
584 let CNJ_CSIN = prove
585  (`!z. cnj(csin z) = csin(cnj z)`,
586   REWRITE_TAC[csin; CNJ_DIV; CNJ_SUB; CNJ_MUL; CNJ_CX; CNJ_CEXP;
587               CNJ_NEG; CNJ_II; COMPLEX_NEG_NEG] THEN
588   CONV_TAC COMPLEX_FIELD);;
589
590 let CNJ_CCOS = prove
591  (`!z. cnj(ccos z) = ccos(cnj z)`,
592   REWRITE_TAC[ccos; CNJ_DIV; CNJ_ADD; CNJ_MUL; CNJ_CX; CNJ_CEXP;
593               CNJ_NEG; CNJ_II; COMPLEX_NEG_NEG; COMPLEX_ADD_AC]);;
594
595 let REAL_SIN = prove
596  (`!z. real z ==> real(csin z)`,
597   SIMP_TAC[REAL_CNJ; CNJ_CSIN]);;
598
599 let REAL_COS = prove
600  (`!z. real z ==> real(ccos z)`,
601   SIMP_TAC[REAL_CNJ; CNJ_CCOS]);;
602
603 let CX_SIN = prove
604  (`!x. Cx(sin x) = csin(Cx x)`,
605   REWRITE_TAC[sin] THEN MESON_TAC[REAL; REAL_CX; REAL_SIN]);;
606
607 let CX_COS = prove
608  (`!x. Cx(cos x) = ccos(Cx x)`,
609   REWRITE_TAC[cos] THEN MESON_TAC[REAL; REAL_CX; REAL_COS]);;
610
611 let HAS_COMPLEX_DERIVATIVE_CSIN = prove
612  (`!z. (csin has_complex_derivative ccos z) (at z)`,
613   GEN_TAC THEN GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
614   REWRITE_TAC[csin; ccos] THEN COMPLEX_DIFF_TAC THEN
615   CONV_TAC COMPLEX_FIELD);;
616
617 let COMPLEX_DIFFERENTIABLE_AT_CSIN = prove
618  (`!z. csin complex_differentiable at z`,
619   REWRITE_TAC[complex_differentiable] THEN
620   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CSIN]);;
621
622 let COMPLEX_DIFFERENTIABLE_WITHIN_CSIN = prove
623  (`!s z. csin complex_differentiable (at z within s)`,
624   MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN;
625             COMPLEX_DIFFERENTIABLE_AT_CSIN]);;
626
627 add_complex_differentiation_theorems
628  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
629    (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN_UNIV
630              HAS_COMPLEX_DERIVATIVE_CSIN)));;
631
632 let HAS_COMPLEX_DERIVATIVE_CCOS = prove
633  (`!z. (ccos has_complex_derivative --csin z) (at z)`,
634   GEN_TAC THEN GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
635   REWRITE_TAC[csin; ccos] THEN COMPLEX_DIFF_TAC THEN
636   CONV_TAC COMPLEX_FIELD);;
637
638 let COMPLEX_DIFFERENTIABLE_AT_CCOS = prove
639  (`!z. ccos complex_differentiable at z`,
640   REWRITE_TAC[complex_differentiable] THEN
641   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CCOS]);;
642
643 let COMPLEX_DIFFERENTIABLE_WITHIN_CCOS = prove
644  (`!s z. ccos complex_differentiable (at z within s)`,
645   MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN;
646             COMPLEX_DIFFERENTIABLE_AT_CCOS]);;
647
648 add_complex_differentiation_theorems
649  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
650    (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN_UNIV
651              HAS_COMPLEX_DERIVATIVE_CCOS)));;
652
653 let CONTINUOUS_AT_CSIN = prove
654  (`!z. csin continuous at z`,
655   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CSIN;
656             HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);;
657
658 let CONTINUOUS_WITHIN_CSIN = prove
659  (`!s z. csin continuous (at z within s)`,
660   MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CSIN]);;
661
662 let CONTINUOUS_ON_CSIN = prove
663  (`!s. csin continuous_on s`,
664   MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CSIN]);;
665
666 let HOLOMORPHIC_ON_CSIN = prove
667  (`!s. csin holomorphic_on s`,
668   REWRITE_TAC [holomorphic_on] THEN
669   MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CSIN]);;
670
671 let CONTINUOUS_AT_CCOS = prove
672  (`!z. ccos continuous at z`,
673   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CCOS;
674             HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);;
675
676 let CONTINUOUS_WITHIN_CCOS = prove
677  (`!s z. ccos continuous (at z within s)`,
678   MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CCOS]);;
679
680 let CONTINUOUS_ON_CCOS = prove
681  (`!s. ccos continuous_on s`,
682   MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CCOS]);;
683
684 let HOLOMORPHIC_ON_CCOS = prove
685  (`!s. ccos holomorphic_on s`,
686   REWRITE_TAC [holomorphic_on] THEN
687   MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CCOS]);;
688
689 (* ------------------------------------------------------------------------- *)
690 (* Slew of theorems for compatibility with old transc.ml file.               *)
691 (* ------------------------------------------------------------------------- *)
692
693 let SIN_0 = prove
694  (`sin(&0) = &0`,
695   REWRITE_TAC[GSYM CX_INJ; CX_SIN; CSIN_0]);;
696
697 let COS_0 = prove
698  (`cos(&0) = &1`,
699   REWRITE_TAC[GSYM CX_INJ; CX_COS; CCOS_0]);;
700
701 let SIN_CIRCLE = prove
702  (`!x. (sin(x) pow 2) + (cos(x) pow 2) = &1`,
703   REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_POW; CSIN_CIRCLE]);;
704
705 let SIN_ADD = prove
706  (`!x y. sin(x + y) = sin(x) * cos(y) + cos(x) * sin(y)`,
707   REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_MUL; CSIN_ADD]);;
708
709 let COS_ADD = prove
710  (`!x y. cos(x + y) = cos(x) * cos(y) - sin(x) * sin(y)`,
711   REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CCOS_ADD]);;
712
713 let SIN_NEG = prove
714  (`!x. sin(--x) = --(sin(x))`,
715   REWRITE_TAC[GSYM CX_INJ; CX_SIN; CX_NEG; CSIN_NEG]);;
716
717 let COS_NEG = prove
718  (`!x. cos(--x) = cos(x)`,
719   REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_NEG; CCOS_NEG]);;
720
721 let SIN_DOUBLE = prove
722  (`!x. sin(&2 * x) = &2 * sin(x) * cos(x)`,
723   REWRITE_TAC[GSYM CX_INJ; CX_SIN; CX_COS; CX_MUL; CSIN_DOUBLE]);;
724
725 let COS_DOUBLE = prove
726  (`!x. cos(&2 * x) = (cos(x) pow 2) - (sin(x) pow 2)`,
727   SIMP_TAC[GSYM CX_INJ; CX_SIN; CX_COS; CX_SUB; CX_MUL; CX_POW; CCOS_DOUBLE]);;
728
729 let COS_DOUBLE_COS = prove
730  (`!x. cos(&2 * x) = &2 * cos(x) pow 2 - &1`,
731   MP_TAC SIN_CIRCLE THEN MATCH_MP_TAC MONO_FORALL THEN
732   REWRITE_TAC[COS_DOUBLE] THEN REAL_ARITH_TAC);;
733
734 let (SIN_BOUND,COS_BOUND) = (CONJ_PAIR o prove)
735  (`(!x. abs(sin x) <= &1) /\ (!x. abs(cos x) <= &1)`,
736   CONJ_TAC THEN GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_ABS_NUM] THEN
737   ONCE_REWRITE_TAC[REAL_LE_SQUARE_ABS] THEN
738   MP_TAC(SPEC `x:real` SIN_CIRCLE) THEN
739   MAP_EVERY (MP_TAC o C SPEC REAL_LE_SQUARE) [`sin x`; `cos x`] THEN
740   REAL_ARITH_TAC);;
741
742 let SIN_BOUNDS = prove
743  (`!x. --(&1) <= sin(x) /\ sin(x) <= &1`,
744   MP_TAC SIN_BOUND THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);;
745
746 let COS_BOUNDS = prove
747  (`!x. --(&1) <= cos(x) /\ cos(x) <= &1`,
748   MP_TAC COS_BOUND THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);;
749
750 let COS_ABS = prove
751  (`!x. cos(abs x) = cos(x)`,
752   REWRITE_TAC[real_abs] THEN MESON_TAC[COS_NEG]);;
753
754 let SIN_SUB = prove
755  (`!w z. sin(w - z) = sin(w) * cos(z) - cos(w) * sin(z)`,
756   REWRITE_TAC[GSYM CX_INJ; CX_SIN; CX_COS; CX_SUB; CX_MUL; CSIN_SUB]);;
757
758 let COS_SUB = prove
759  (`!w z. cos(w - z) = cos(w) * cos(z) + sin(w) * sin(z)`,
760   REWRITE_TAC[GSYM CX_INJ; CX_SIN; CX_COS; CX_SUB; CX_ADD; CX_MUL; CCOS_SUB]);;
761
762 let REAL_MUL_SIN_SIN = prove
763  (`!x y. sin(x) * sin(y) = (cos(x - y) - cos(x + y)) / &2`,
764   REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN
765   REWRITE_TAC[COMPLEX_MUL_CSIN_CSIN]);;
766
767 let REAL_MUL_SIN_COS = prove
768  (`!x y. sin(x) * cos(y) = (sin(x + y) + sin(x - y)) / &2`,
769   REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN
770   REWRITE_TAC[COMPLEX_MUL_CSIN_CCOS]);;
771
772 let REAL_MUL_COS_SIN = prove
773  (`!x y. cos(x) * sin(y) = (sin(x + y) - sin(x - y)) / &2`,
774   REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN
775   REWRITE_TAC[COMPLEX_MUL_CCOS_CSIN]);;
776
777 let REAL_MUL_COS_COS = prove
778  (`!x y. cos(x) * cos(y) = (cos(x - y) + cos(x + y)) / &2`,
779   REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN
780   REWRITE_TAC[COMPLEX_MUL_CCOS_CCOS]);;
781
782 let REAL_ADD_SIN = prove
783  (`!x y. sin(x) + sin(y) = &2 * sin((x + y) / &2) * cos((x - y) / &2)`,
784   REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN
785   REWRITE_TAC[COMPLEX_ADD_CSIN]);;
786
787 let REAL_SUB_SIN = prove
788  (`!x y. sin(x) - sin(y) = &2 * sin((x - y) / &2) * cos((x + y) / &2)`,
789   REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN
790   REWRITE_TAC[COMPLEX_SUB_CSIN]);;
791
792 let REAL_ADD_COS = prove
793  (`!x y. cos(x) + cos(y) = &2 * cos((x + y) / &2) * cos((x - y) / &2)`,
794   REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN
795   REWRITE_TAC[COMPLEX_ADD_CCOS]);;
796
797 let REAL_SUB_COS = prove
798  (`!x y. cos(x) - cos(y) = &2 * sin((x + y) / &2) * sin((y - x) / &2)`,
799   REWRITE_TAC[GSYM CX_INJ; CX_COS; CX_SIN; CX_ADD; CX_SUB; CX_MUL; CX_DIV] THEN
800   REWRITE_TAC[COMPLEX_SUB_CCOS]);;
801
802 let COS_DOUBLE_SIN = prove
803  (`!x. cos(&2 * x) = &1 - &2 * sin x pow 2`,
804   GEN_TAC THEN REWRITE_TAC[REAL_RING `&2 * x = x + x`; COS_ADD] THEN
805   MP_TAC(SPEC `x:real` SIN_CIRCLE) THEN CONV_TAC REAL_RING);;
806
807 (* ------------------------------------------------------------------------- *)
808 (* Get a nice real/imaginary separation in Euler's formula.                  *)
809 (* ------------------------------------------------------------------------- *)
810
811 let EULER = prove
812  (`!z. cexp(z) = Cx(exp(Re z)) * (Cx(cos(Im z)) + ii * Cx(sin(Im z)))`,
813   GEN_TAC THEN GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [COMPLEX_EXPAND] THEN
814   REWRITE_TAC[CEXP_ADD; CEXP_EULER; GSYM CX_SIN; GSYM CX_COS; GSYM CX_EXP]);;
815
816 let RE_CEXP = prove
817  (`!z. Re(cexp z) = exp(Re z) * cos(Im z)`,
818   REWRITE_TAC[EULER; RE_ADD; RE_MUL_CX; RE_MUL_II; IM_CX; RE_CX] THEN
819   REAL_ARITH_TAC);;
820
821 let IM_CEXP = prove
822  (`!z. Im(cexp z) = exp(Re z) * sin(Im z)`,
823   REWRITE_TAC[EULER; IM_ADD; IM_MUL_CX; IM_MUL_II; IM_CX; RE_CX] THEN
824   REAL_ARITH_TAC);;
825
826 let RE_CSIN = prove
827  (`!z. Re(csin z) = (exp(Im z) + exp(--(Im z))) / &2 * sin(Re z)`,
828   GEN_TAC THEN REWRITE_TAC[csin] THEN
829   SIMP_TAC[COMPLEX_FIELD `x / (Cx(&2) * ii) = ii * --(x / Cx(&2))`] THEN
830   REWRITE_TAC[IM_MUL_II; IM_DIV_CX; RE_NEG; IM_SUB; IM_CEXP;
831               RE_MUL_II; COMPLEX_MUL_LNEG; IM_NEG] THEN
832   REWRITE_TAC[REAL_NEG_NEG; SIN_NEG] THEN CONV_TAC REAL_RING);;
833
834 let IM_CSIN = prove
835  (`!z. Im(csin z) = (exp(Im z) - exp(--(Im z))) / &2 * cos(Re z)`,
836   GEN_TAC THEN REWRITE_TAC[csin] THEN
837   SIMP_TAC[COMPLEX_FIELD `x / (Cx(&2) * ii) = ii * --(x / Cx(&2))`] THEN
838   REWRITE_TAC[IM_MUL_II; RE_DIV_CX; RE_NEG; RE_SUB; RE_CEXP;
839               RE_MUL_II; COMPLEX_MUL_LNEG; IM_NEG] THEN
840   REWRITE_TAC[REAL_NEG_NEG; COS_NEG] THEN CONV_TAC REAL_RING);;
841
842 let RE_CCOS = prove
843  (`!z. Re(ccos z) = (exp(Im z) + exp(--(Im z))) / &2 * cos(Re z)`,
844   GEN_TAC THEN REWRITE_TAC[ccos] THEN
845   REWRITE_TAC[RE_DIV_CX; RE_ADD; RE_CEXP; COMPLEX_MUL_LNEG;
846               RE_MUL_II; IM_MUL_II; RE_NEG; IM_NEG; COS_NEG] THEN
847   REWRITE_TAC[REAL_NEG_NEG] THEN CONV_TAC REAL_RING);;
848
849 let IM_CCOS = prove
850  (`!z. Im(ccos z) = (exp(--(Im z)) - exp(Im z)) / &2 * sin(Re z)`,
851   GEN_TAC THEN REWRITE_TAC[ccos] THEN
852   REWRITE_TAC[IM_DIV_CX; IM_ADD; IM_CEXP; COMPLEX_MUL_LNEG;
853               RE_MUL_II; IM_MUL_II; RE_NEG; IM_NEG; SIN_NEG] THEN
854   REWRITE_TAC[REAL_NEG_NEG] THEN CONV_TAC REAL_RING);;
855
856 (* ------------------------------------------------------------------------- *)
857 (* Some special intermediate value theorems over the reals.                  *)
858 (* ------------------------------------------------------------------------- *)
859
860 let IVT_INCREASING_RE = prove
861  (`!f a b y.
862         a <= b /\
863         (!x. a <= x /\ x <= b ==> f continuous at (Cx x)) /\
864         Re(f(Cx a)) <= y /\ y <= Re(f(Cx b))
865         ==> ?x. a <= x /\ x <= b /\ Re(f(Cx x)) = y`,
866   REPEAT STRIP_TAC THEN
867   MP_TAC(ISPECL [`(f:complex->complex) o Cx o drop`;
868                  `lift a`; `lift b`; `y:real`; `1`]
869         IVT_INCREASING_COMPONENT_1) THEN
870   REWRITE_TAC[EXISTS_DROP; GSYM drop; LIFT_DROP; o_THM; GSYM RE_DEF] THEN
871   ASM_REWRITE_TAC[IN_INTERVAL_1; GSYM CONJ_ASSOC; LIFT_DROP] THEN
872   DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[DIMINDEX_2; ARITH] THEN
873   REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN
874   ASM_SIMP_TAC[o_THM] THEN REWRITE_TAC[continuous_at; o_THM] THEN
875   REWRITE_TAC[dist; GSYM CX_SUB; GSYM DROP_SUB; COMPLEX_NORM_CX] THEN
876   REWRITE_TAC[GSYM ABS_DROP] THEN MESON_TAC[]);;
877
878 let IVT_DECREASING_RE = prove
879  (`!f a b y.
880         a <= b /\
881         (!x. a <= x /\ x <= b ==> f continuous at (Cx x)) /\
882         Re(f(Cx b)) <= y /\ y <= Re(f(Cx a))
883         ==> ?x. a <= x /\ x <= b /\ Re(f(Cx x)) = y`,
884   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EQ_NEG2] THEN
885   REWRITE_TAC[GSYM RE_NEG] THEN MATCH_MP_TAC IVT_INCREASING_RE THEN
886   ASM_SIMP_TAC[CONTINUOUS_NEG; RE_NEG; REAL_LE_NEG2]);;
887
888 let IVT_INCREASING_IM = prove
889  (`!f a b y.
890         a <= b /\
891         (!x. a <= x /\ x <= b ==> f continuous at (Cx x)) /\
892         Im(f(Cx a)) <= y /\ y <= Im(f(Cx b))
893         ==> ?x. a <= x /\ x <= b /\ Im(f(Cx x)) = y`,
894   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EQ_NEG2] THEN
895   REWRITE_TAC[SYM(CONJUNCT2(SPEC_ALL RE_MUL_II))] THEN
896   MATCH_MP_TAC IVT_DECREASING_RE THEN
897   ASM_SIMP_TAC[CONTINUOUS_COMPLEX_MUL; ETA_AX; CONTINUOUS_CONST] THEN
898   ASM_REWRITE_TAC[RE_MUL_II; REAL_LE_NEG2]);;
899
900 let IVT_DECREASING_IM = prove
901  (`!f a b y.
902         a <= b /\
903         (!x. a <= x /\ x <= b ==> f continuous at (Cx x)) /\
904         Im(f(Cx b)) <= y /\ y <= Im(f(Cx a))
905         ==> ?x. a <= x /\ x <= b /\ Im(f(Cx x)) = y`,
906   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EQ_NEG2] THEN
907   REWRITE_TAC[GSYM IM_NEG] THEN MATCH_MP_TAC IVT_INCREASING_IM THEN
908   ASM_SIMP_TAC[CONTINUOUS_NEG; IM_NEG; REAL_LE_NEG2]);;
909
910 (* ------------------------------------------------------------------------- *)
911 (* Some minimal properties of real logs help to define complex logs.         *)
912 (* ------------------------------------------------------------------------- *)
913
914 let log_def = new_definition
915  `log y = @x. exp(x) = y`;;
916
917 let EXP_LOG = prove
918  (`!x. &0 < x ==> exp(log x) = x`,
919   REPEAT STRIP_TAC THEN REWRITE_TAC[log_def] THEN CONV_TAC SELECT_CONV THEN
920   SUBGOAL_THEN `?y. --inv(x) <= y /\ y <= x /\ Re(cexp(Cx y)) = x`
921   MP_TAC THENL [ALL_TAC; MESON_TAC[CX_EXP; RE_CX]] THEN
922   MATCH_MP_TAC IVT_INCREASING_RE THEN
923   SIMP_TAC[GSYM CX_EXP; RE_CX; CONTINUOUS_AT_CEXP] THEN REPEAT CONJ_TAC THENL
924    [MATCH_MP_TAC(REAL_ARITH `&0 < x /\ &0 < y ==> --y <= x`) THEN
925     ASM_SIMP_TAC[REAL_LT_INV_EQ];
926     ONCE_REWRITE_TAC[GSYM REAL_INV_INV] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
927     ASM_REWRITE_TAC[REAL_EXP_NEG; REAL_INV_INV; REAL_LT_INV_EQ];
928     ALL_TAC] THEN
929   MATCH_MP_TAC(REAL_ARITH `&1 + x <= y ==> x <= y`) THEN
930   ASM_SIMP_TAC[REAL_EXP_LE_X; REAL_LE_INV_EQ; REAL_LT_IMP_LE]);;
931
932 let LOG_EXP = prove
933  (`!x. log(exp x) = x`,
934   GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EXP_INJ] THEN
935   SIMP_TAC[EXP_LOG; REAL_EXP_POS_LT]);;
936
937 let REAL_EXP_LOG = prove
938  (`!x. (exp(log x) = x) <=> &0 < x`,
939   MESON_TAC[EXP_LOG; REAL_EXP_POS_LT]);;
940
941 let LOG_MUL = prove
942  (`!x y. &0 < x /\ &0 < y ==> (log(x * y) = log(x) + log(y))`,
943   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EXP_INJ] THEN
944   ASM_SIMP_TAC[REAL_EXP_ADD; REAL_LT_MUL; EXP_LOG]);;
945
946 let LOG_INJ = prove
947  (`!x y. &0 < x /\ &0 < y ==> (log(x) = log(y) <=> x = y)`,
948   REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM REAL_EXP_INJ] THEN
949   ASM_SIMP_TAC[EXP_LOG]);;
950
951 let LOG_1 = prove
952  (`log(&1) = &0`,
953   ONCE_REWRITE_TAC[GSYM REAL_EXP_INJ] THEN
954   REWRITE_TAC[REAL_EXP_0; REAL_EXP_LOG; REAL_LT_01]);;
955
956 let LOG_INV = prove
957  (`!x. &0 < x ==> (log(inv x) = --(log x))`,
958   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EXP_INJ] THEN
959   ASM_SIMP_TAC[REAL_EXP_NEG; EXP_LOG; REAL_LT_INV_EQ]);;
960
961 let LOG_DIV = prove
962  (`!x y. &0 < x /\ &0 < y ==> log(x / y) = log(x) - log(y)`,
963   SIMP_TAC[real_div; real_sub; LOG_MUL; LOG_INV; REAL_LT_INV_EQ]);;
964
965 let LOG_MONO_LT = prove
966  (`!x y. &0 < x /\ &0 < y ==> (log(x) < log(y) <=> x < y)`,
967   REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM REAL_EXP_MONO_LT] THEN
968   ASM_SIMP_TAC[EXP_LOG]);;
969
970 let LOG_MONO_LT_IMP = prove
971  (`!x y. &0 < x /\ x < y ==> log(x) < log(y)`,
972   MESON_TAC[LOG_MONO_LT; REAL_LT_TRANS]);;
973
974 let LOG_MONO_LE = prove
975  (`!x y. &0 < x /\ &0 < y ==> (log(x) <= log(y) <=> x <= y)`,
976   REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM REAL_EXP_MONO_LE] THEN
977   ASM_SIMP_TAC[EXP_LOG]);;
978
979 let LOG_MONO_LE_IMP = prove
980  (`!x y. &0 < x /\ x <= y ==> log(x) <= log(y)`,
981   MESON_TAC[LOG_MONO_LE; REAL_LT_IMP_LE; REAL_LTE_TRANS]);;
982
983 let LOG_POW = prove
984  (`!n x. &0 < x ==> (log(x pow n) = &n * log(x))`,
985   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EXP_INJ] THEN
986   ASM_SIMP_TAC[REAL_EXP_N; EXP_LOG; REAL_POW_LT]);;
987
988 let LOG_LE = prove
989  (`!x. &0 <= x ==> log(&1 + x) <= x`,
990   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LE] THEN
991   ASM_SIMP_TAC[EXP_LOG; REAL_ARITH `&0 <= x ==> &0 < &1 + x`; REAL_EXP_LE_X]);;
992
993 let LOG_LT_X = prove
994  (`!x. &0 < x ==> log(x) < x`,
995   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LT] THEN
996   ASM_SIMP_TAC[EXP_LOG] THEN MP_TAC(SPEC `x:real` REAL_EXP_LE_X) THEN
997   POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);;
998
999 let LOG_POS = prove
1000  (`!x. &1 <= x ==> &0 <= log(x)`,
1001   REWRITE_TAC[GSYM LOG_1] THEN
1002   SIMP_TAC[LOG_MONO_LE; ARITH_RULE `&1 <= x ==> &0 < x`; REAL_LT_01]);;
1003
1004 let LOG_POS_LT = prove
1005  (`!x. &1 < x ==> &0 < log(x)`,
1006   REWRITE_TAC[GSYM LOG_1] THEN
1007   SIMP_TAC[LOG_MONO_LT; ARITH_RULE `&1 < x ==> &0 < x`; REAL_LT_01]);;
1008
1009 (* ------------------------------------------------------------------------- *)
1010 (* Deduce periodicity just from derivative and zero values.                  *)
1011 (* ------------------------------------------------------------------------- *)
1012
1013 let SIN_NEARZERO = prove
1014  (`?x. &0 < x /\ !y. &0 < y /\ y <= x ==> &0 < sin(y)`,
1015   MP_TAC(SPEC `&1 / &2` (CONJUNCT2
1016    (REWRITE_RULE[has_complex_derivative; HAS_DERIVATIVE_AT_ALT]
1017     (ISPEC `Cx(&0)` HAS_COMPLEX_DERIVATIVE_CSIN)))) THEN
1018   CONV_TAC REAL_RAT_REDUCE_CONV THEN
1019   REWRITE_TAC[CSIN_0; COMPLEX_SUB_RZERO; CCOS_0; COMPLEX_MUL_LZERO;
1020               COMPLEX_MUL_LID] THEN
1021   DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
1022   EXISTS_TAC `d / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN
1023   X_GEN_TAC `y:real` THEN STRIP_TAC THEN
1024   FIRST_X_ASSUM(MP_TAC o SPEC `Cx y`) THEN
1025   ASM_REWRITE_TAC[GSYM CX_SIN; COMPLEX_NORM_CX; GSYM CX_SUB] THEN
1026   ASM_REAL_ARITH_TAC);;
1027
1028 let SIN_NONTRIVIAL = prove
1029  (`?x. &0 < x /\ ~(sin x = &0)`,
1030   MESON_TAC[REAL_LE_REFL; REAL_LT_REFL; SIN_NEARZERO]);;
1031
1032 let COS_NONTRIVIAL = prove
1033  (`?x. &0 < x /\ ~(cos x = &1)`,
1034   MP_TAC SIN_NONTRIVIAL THEN MATCH_MP_TAC MONO_EXISTS THEN
1035   MP_TAC SIN_CIRCLE THEN MATCH_MP_TAC MONO_FORALL THEN
1036   CONV_TAC REAL_FIELD);;
1037
1038 let COS_DOUBLE_BOUND = prove
1039  (`!x. &0 <= cos x ==> &2 * (&1 - cos x) <= &1 - cos(&2 * x)`,
1040   REWRITE_TAC[COS_DOUBLE_COS] THEN REWRITE_TAC[REAL_ARITH
1041    `&2 * (&1 - a) <= &1 - (&2 * b - &1) <=> b <= &1 * a`] THEN
1042   SIMP_TAC[REAL_POW_2; REAL_LE_RMUL; COS_BOUNDS]);;
1043
1044 let COS_GOESNEGATIVE_LEMMA = prove
1045  (`!x. cos(x) < &1 ==> ?n. cos(&2 pow n * x) < &0`,
1046   GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(TAUT `(~p ==> p) ==> p`) THEN
1047   REWRITE_TAC[NOT_EXISTS_THM; REAL_NOT_LT] THEN DISCH_TAC THEN
1048   SUBGOAL_THEN `!n.  &2  pow n * (&1 - cos x) <= &1 - cos(&2 pow n * x)`
1049   ASSUME_TAC THENL
1050    [INDUCT_TAC THEN REWRITE_TAC[real_pow; REAL_MUL_LID; REAL_LE_REFL] THEN
1051     MATCH_MP_TAC REAL_LE_TRANS THEN
1052     EXISTS_TAC `&2 * (&1 - cos(&2 pow n * x))` THEN
1053     ASM_SIMP_TAC[GSYM REAL_MUL_ASSOC; REAL_LE_LMUL; REAL_POS; COS_DOUBLE_BOUND];
1054     MP_TAC(ISPEC `&1 / (&1 - cos(x))` REAL_ARCH_POW2) THEN
1055     ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_SUB_LT] THEN
1056     DISCH_THEN(X_CHOOSE_THEN `n:num` MP_TAC) THEN
1057     REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `n:num`)) THEN REAL_ARITH_TAC]);;
1058
1059 let COS_GOESNEGATIVE = prove
1060  (`?x. &0 < x /\ cos(x) < &0`,
1061   X_CHOOSE_TAC `x:real` COS_NONTRIVIAL THEN
1062   MP_TAC(SPEC `x:real` COS_GOESNEGATIVE_LEMMA) THEN ANTS_TAC THENL
1063    [MP_TAC(SPEC `x:real` COS_BOUNDS) THEN
1064     ASM_REAL_ARITH_TAC;
1065     ASM_MESON_TAC[REAL_LT_MUL; REAL_POW_LT; REAL_ARITH `&0 < &2`]]);;
1066
1067 let COS_HASZERO = prove
1068  (`?x. &0 < x /\ cos(x) = &0`,
1069   X_CHOOSE_THEN `z:real` STRIP_ASSUME_TAC COS_GOESNEGATIVE THEN
1070   SUBGOAL_THEN `?x. &0 <= x /\ x <= z /\ Re(ccos(Cx x)) = &0` MP_TAC THENL
1071    [MATCH_MP_TAC IVT_DECREASING_RE THEN
1072     ASM_SIMP_TAC[GSYM CX_COS; RE_CX; REAL_LT_IMP_LE; COS_0; REAL_POS] THEN
1073     MESON_TAC[HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT;
1074               HAS_COMPLEX_DERIVATIVE_CCOS];
1075     MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[GSYM CX_COS; RE_CX] THEN
1076     MESON_TAC[COS_0; REAL_LE_LT; REAL_ARITH `~(&1 = &0)`]]);;
1077
1078 let SIN_HASZERO = prove
1079  (`?x. &0 < x /\ sin(x) = &0`,
1080   X_CHOOSE_THEN `x:real` STRIP_ASSUME_TAC COS_HASZERO THEN
1081   EXISTS_TAC `&2 * x` THEN ASM_SIMP_TAC[SIN_DOUBLE] THEN
1082   ASM_REAL_ARITH_TAC);;
1083
1084 let SIN_HASZERO_MINIMAL = prove
1085  (`?p. &0 < p /\ sin p = &0 /\ !x. &0 < x /\ x < p ==> ~(sin x = &0)`,
1086   X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC SIN_NEARZERO THEN
1087   MP_TAC(ISPECL
1088     [`{z | z IN IMAGE Cx {x | x >= e} /\ csin z IN {Cx(&0)}}`; `Cx(&0)`]
1089     DISTANCE_ATTAINS_INF) THEN
1090   ANTS_TAC THENL
1091    [ALL_TAC;
1092     REWRITE_TAC[IN_ELIM_THM; GSYM CONJ_ASSOC; IMP_CONJ] THEN
1093     REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
1094     REWRITE_TAC[IN_ELIM_THM; IN_SING; real_ge; GSYM CX_COS; CX_INJ] THEN
1095     REWRITE_TAC[dist; GSYM CX_SUB; GSYM CX_SIN; CX_INJ; COMPLEX_NORM_CX] THEN
1096     MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
1097     REWRITE_TAC[REAL_ARITH `abs(&0 - x) = abs x`] THEN
1098     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
1099      [ALL_TAC;
1100       X_GEN_TAC `x:real` THEN
1101       REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x:real`))] THEN
1102     ASM_REAL_ARITH_TAC] THEN
1103   X_CHOOSE_TAC `a:real` SIN_HASZERO THEN CONJ_TAC THENL
1104    [ALL_TAC;
1105     REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `Cx a` THEN
1106     ASM_REWRITE_TAC[IN_SING; IN_IMAGE; IN_ELIM_THM; GSYM CX_SIN] THEN
1107     ASM_MESON_TAC[REAL_ARITH `x >= w \/ x <= w`; REAL_LT_REFL]] THEN
1108   MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN
1109   REWRITE_TAC[CONTINUOUS_ON_CSIN; CLOSED_SING] THEN
1110   SUBGOAL_THEN
1111    `IMAGE Cx {x | x >= e} = {z | Im(z) = &0} INTER {z | Re(z) >= e}`
1112    (fun th -> SIMP_TAC[th; CLOSED_INTER; CLOSED_HALFSPACE_IM_EQ;
1113                            CLOSED_HALFSPACE_RE_GE]) THEN
1114   REWRITE_TAC[EXTENSION; IN_IMAGE; IN_INTER; IN_ELIM_THM] THEN
1115   REWRITE_TAC[FORALL_COMPLEX; COMPLEX_EQ; RE; IM; RE_CX; IM_CX] THEN
1116   MESON_TAC[]);;
1117
1118 let pi = new_definition
1119  `pi = @p. &0 < p /\ sin(p) = &0 /\ !x. &0 < x /\ x < p ==> ~(sin(x) = &0)`;;
1120
1121 let PI_WORKS = prove
1122  (`&0 < pi /\ sin(pi) = &0 /\ !x. &0 < x /\ x < pi ==> ~(sin x = &0)`,
1123   REWRITE_TAC[pi] THEN CONV_TAC SELECT_CONV THEN
1124   REWRITE_TAC[SIN_HASZERO_MINIMAL]);;
1125
1126 (* ------------------------------------------------------------------------- *)
1127 (* Now more relatively easy consequences.                                    *)
1128 (* ------------------------------------------------------------------------- *)
1129
1130 let PI_POS = prove
1131  (`&0 < pi`,
1132   REWRITE_TAC[PI_WORKS]);;
1133
1134 let PI_POS_LE = prove
1135  (`&0 <= pi`,
1136   REWRITE_TAC[REAL_LE_LT; PI_POS]);;
1137
1138 let PI_NZ = prove
1139  (`~(pi = &0)`,
1140   SIMP_TAC[PI_POS; REAL_LT_IMP_NZ]);;
1141
1142 let REAL_ABS_PI = prove
1143  (`abs pi = pi`,
1144   REWRITE_TAC[real_abs; PI_POS_LE]);;
1145
1146 let SIN_PI = prove
1147  (`sin(pi) = &0`,
1148   REWRITE_TAC[PI_WORKS]);;
1149
1150 let SIN_POS_PI = prove
1151  (`!x. &0 < x /\ x < pi ==> &0 < sin(x)`,
1152   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_NOT_LE] THEN DISCH_TAC THEN
1153   X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC SIN_NEARZERO THEN
1154   MP_TAC(ISPECL [`csin`; `e:real`; `x:real`; `&0`] IVT_DECREASING_RE) THEN
1155   ASM_SIMP_TAC[NOT_IMP; CONTINUOUS_AT_CSIN; GSYM CX_SIN; RE_CX; SIN_0] THEN
1156   ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LET_ANTISYM; PI_WORKS; REAL_LET_TRANS;
1157                 REAL_LTE_TRANS]);;
1158
1159 let COS_PI2 = prove
1160  (`cos(pi / &2) = &0`,
1161   MP_TAC(SYM(SPEC `pi / &2` SIN_DOUBLE)) THEN
1162   REWRITE_TAC[REAL_HALF; SIN_PI; REAL_ENTIRE; REAL_OF_NUM_EQ; ARITH] THEN
1163   MATCH_MP_TAC(REAL_ARITH `&0 < y ==> y = &0 \/ z = &0 ==> z = &0`) THEN
1164   MATCH_MP_TAC SIN_POS_PI THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);;
1165
1166 let COS_PI = prove
1167  (`cos(pi) = -- &1`,
1168   ONCE_REWRITE_TAC[REAL_ARITH `pi = &2 * pi / &2`] THEN
1169   REWRITE_TAC[COS_DOUBLE_COS; COS_PI2] THEN REAL_ARITH_TAC);;
1170
1171 let SIN_PI2 = prove
1172  (`sin(pi / &2) = &1`,
1173   MP_TAC(SPEC `pi / &2` SIN_CIRCLE) THEN
1174   REWRITE_TAC[COS_PI2; REAL_POW_2; REAL_ADD_RID; REAL_MUL_LZERO] THEN
1175   REWRITE_TAC[REAL_RING `x * x = &1 <=> x = &1 \/ x = -- &1`] THEN
1176   MP_TAC(SPEC `pi / &2` SIN_POS_PI) THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);;
1177
1178 let SIN_COS = prove
1179  (`!x. sin(x) = cos(pi / &2 - x)`,
1180   REWRITE_TAC[COS_SUB; COS_PI2; SIN_PI2] THEN REAL_ARITH_TAC);;
1181
1182 let COS_SIN = prove
1183  (`!x. cos(x) = sin(pi / &2 - x)`,
1184   REWRITE_TAC[SIN_SUB; COS_PI2; SIN_PI2] THEN REAL_ARITH_TAC);;
1185
1186 let SIN_PERIODIC_PI = prove
1187  (`!x. sin(x + pi) = --(sin(x))`,
1188   REWRITE_TAC[SIN_ADD; SIN_PI; COS_PI] THEN REAL_ARITH_TAC);;
1189
1190 let COS_PERIODIC_PI = prove
1191  (`!x. cos(x + pi) = --(cos(x))`,
1192   REWRITE_TAC[COS_ADD; SIN_PI; COS_PI] THEN REAL_ARITH_TAC);;
1193
1194 let SIN_PERIODIC = prove
1195  (`!x. sin(x + &2 * pi) = sin(x)`,
1196   REWRITE_TAC[REAL_MUL_2; REAL_ADD_ASSOC; SIN_PERIODIC_PI; REAL_NEG_NEG]);;
1197
1198 let COS_PERIODIC = prove
1199  (`!x. cos(x + &2 * pi) = cos(x)`,
1200   REWRITE_TAC[REAL_MUL_2; REAL_ADD_ASSOC; COS_PERIODIC_PI; REAL_NEG_NEG]);;
1201
1202 let SIN_NPI = prove
1203  (`!n. sin(&n * pi) = &0`,
1204   INDUCT_TAC THEN
1205   ASM_REWRITE_TAC[GSYM REAL_OF_NUM_SUC; REAL_MUL_LID; REAL_ADD_RDISTRIB;
1206                   REAL_NEG_0; SIN_PERIODIC_PI; REAL_MUL_LZERO; SIN_0]);;
1207
1208 let COS_NPI = prove
1209  (`!n. cos(&n * pi) = --(&1) pow n`,
1210   INDUCT_TAC THEN
1211   ASM_REWRITE_TAC[real_pow; REAL_MUL_LZERO; COS_0; COS_PERIODIC_PI;
1212     REAL_MUL_LID; REAL_MUL_LNEG; GSYM REAL_OF_NUM_SUC; REAL_ADD_RDISTRIB]);;
1213
1214 let COS_POS_PI2 = prove
1215  (`!x. &0 < x /\ x < pi / &2 ==> &0 < cos(x)`,
1216   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_NOT_LE] THEN DISCH_TAC THEN
1217   MP_TAC(ISPECL [`ccos`; `&0`; `x:real`; `&0`] IVT_DECREASING_RE) THEN
1218   ASM_SIMP_TAC[CONTINUOUS_AT_CCOS; REAL_LT_IMP_LE; GSYM CX_COS; RE_CX] THEN
1219   REWRITE_TAC[COS_0; REAL_POS] THEN DISCH_THEN(X_CHOOSE_TAC `y:real`) THEN
1220   MP_TAC(SPEC `y:real` SIN_DOUBLE) THEN ASM_REWRITE_TAC[REAL_MUL_RZERO] THEN
1221   MATCH_MP_TAC(last(CONJUNCTS PI_WORKS)) THEN REPEAT(POP_ASSUM MP_TAC) THEN
1222   ASM_CASES_TAC `y = &0` THEN ASM_REWRITE_TAC[COS_0] THEN
1223   POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);;
1224
1225 let SIN_POS_PI2 = prove
1226  (`!x. &0 < x /\ x < pi / &2 ==> &0 < sin(x)`,
1227   REPEAT STRIP_TAC THEN MATCH_MP_TAC SIN_POS_PI THEN
1228   ASM_REAL_ARITH_TAC);;
1229
1230 let COS_POS_PI = prove
1231  (`!x. --(pi / &2) < x /\ x < pi / &2 ==> &0 < cos(x)`,
1232   GEN_TAC THEN MP_TAC(SPEC `abs x` COS_POS_PI2) THEN REWRITE_TAC[COS_ABS] THEN
1233   ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[COS_0] THEN
1234   POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);;
1235
1236 let COS_POS_PI_LE = prove
1237  (`!x. --(pi / &2) <= x /\ x <= pi / &2 ==> &0 <= cos(x)`,
1238   REWRITE_TAC[REAL_LE_LT] THEN MESON_TAC[COS_PI2; COS_NEG; COS_POS_PI]);;
1239
1240 let SIN_POS_PI_LE = prove
1241  (`!x. &0 <= x /\ x <= pi ==> &0 <= sin(x)`,
1242   REWRITE_TAC[REAL_LE_LT] THEN MESON_TAC[SIN_0; SIN_PI; SIN_POS_PI]);;
1243
1244 let SIN_PIMUL_EQ_0 = prove
1245  (`!n. sin(n * pi) = &0 <=> integer(n)`,
1246   SUBGOAL_THEN `!n. integer n ==> sin(n * pi) = &0 /\ ~(cos(n * pi) = &0)`
1247   ASSUME_TAC THENL
1248    [REWRITE_TAC[INTEGER_CASES] THEN GEN_TAC THEN STRIP_TAC THEN CONJ_TAC THEN
1249     ASM_SIMP_TAC[REAL_MUL_LNEG; COS_NPI; SIN_NPI;
1250                  SIN_NEG; COS_NEG; REAL_POW_EQ_0] THEN REAL_ARITH_TAC;
1251     ALL_TAC] THEN
1252   GEN_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[] THEN
1253   SUBST1_TAC(last(CONJUNCTS(SPEC `n:real` FLOOR_FRAC))) THEN
1254   ASM_SIMP_TAC[REAL_ADD_RDISTRIB; FLOOR; SIN_ADD; REAL_MUL_LZERO] THEN
1255   ASM_SIMP_TAC[REAL_ADD_LID; REAL_ENTIRE; FLOOR] THEN
1256   DISCH_TAC THEN MP_TAC(SPEC `frac n * pi` SIN_POS_PI) THEN
1257   ASM_SIMP_TAC[REAL_LT_REFL; GSYM REAL_LT_RDIV_EQ; GSYM REAL_LT_LDIV_EQ;
1258                PI_POS; REAL_DIV_REFL; REAL_LT_IMP_NZ] THEN
1259   MP_TAC(SPEC `n:real` FLOOR_FRAC) THEN ASM_CASES_TAC `frac n = &0` THEN
1260   ASM_REWRITE_TAC[FLOOR; REAL_ADD_RID] THEN
1261   ASM_REAL_ARITH_TAC);;
1262
1263 let SIN_EQ_0 = prove
1264  (`!x. sin(x) = &0 <=> ?n. integer n /\ x = n * pi`,
1265   GEN_TAC THEN MP_TAC(SPEC `x / pi` SIN_PIMUL_EQ_0) THEN
1266   SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NZ; GSYM REAL_EQ_LDIV_EQ; PI_POS] THEN
1267   ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[UNWIND_THM1]);;
1268
1269 let COS_EQ_0 = prove
1270  (`!x. cos(x) = &0 <=> ?n. integer n /\ x = (n + &1 / &2) * pi`,
1271   GEN_TAC THEN REWRITE_TAC[COS_SIN; SIN_EQ_0] THEN
1272   EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC) THEN
1273   EXISTS_TAC `--n:real` THEN ASM_REWRITE_TAC[INTEGER_NEG] THEN
1274   ASM_REAL_ARITH_TAC);;
1275
1276 let SIN_ZERO_PI = prove
1277  (`!x. sin(x) = &0 <=> (?n. x = &n * pi) \/ (?n. x = --(&n * pi))`,
1278   REWRITE_TAC[SIN_EQ_0; INTEGER_CASES] THEN MESON_TAC[REAL_MUL_LNEG]);;
1279
1280 let COS_ZERO_PI = prove
1281  (`!x. cos(x) = &0 <=>
1282        (?n. x = (&n + &1 / &2) * pi) \/ (?n. x = --((&n + &1 / &2) * pi))`,
1283   GEN_TAC THEN REWRITE_TAC[COS_EQ_0; INTEGER_CASES; RIGHT_OR_DISTRIB] THEN
1284   REWRITE_TAC[EXISTS_OR_THM; LEFT_AND_EXISTS_THM] THEN
1285   ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN SIMP_TAC[UNWIND_THM2] THEN EQ_TAC THEN
1286   DISCH_THEN(DISJ_CASES_THEN (X_CHOOSE_THEN `n:num` SUBST1_TAC)) THENL
1287    [DISJ1_TAC THEN EXISTS_TAC `n:num`;
1288     ASM_CASES_TAC `n = 0` THENL
1289      [DISJ1_TAC THEN EXISTS_TAC `0`;
1290       DISJ2_TAC THEN EXISTS_TAC `n - 1`];
1291     DISJ1_TAC THEN EXISTS_TAC `n:num`;
1292     DISJ2_TAC THEN EXISTS_TAC `n + 1`] THEN
1293   ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUB; GSYM REAL_OF_NUM_ADD;
1294                ARITH_RULE `1 <= n <=> ~(n = 0)`] THEN
1295   REAL_ARITH_TAC);;
1296
1297 let SIN_ZERO = prove
1298  (`!x. (sin(x) = &0) <=> (?n. EVEN n /\ x = &n * (pi / &2)) \/
1299                          (?n. EVEN n /\ x = --(&n * (pi / &2)))`,
1300   REWRITE_TAC[SIN_ZERO_PI; EVEN_EXISTS; LEFT_AND_EXISTS_THM] THEN
1301   ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN
1302   SIMP_TAC[GSYM REAL_OF_NUM_MUL; REAL_ARITH `(&2 * x) * y / &2 = x * y`]);;
1303
1304 let COS_ZERO = prove
1305  (`!x. cos(x) = &0 <=> (?n. ~EVEN n /\ (x = &n * (pi / &2))) \/
1306                        (?n. ~EVEN n /\ (x = --(&n * (pi / &2))))`,
1307   REWRITE_TAC[COS_ZERO_PI; NOT_EVEN; ODD_EXISTS; LEFT_AND_EXISTS_THM] THEN
1308   ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN
1309   SIMP_TAC[GSYM REAL_OF_NUM_MUL; GSYM REAL_OF_NUM_SUC;
1310            REAL_ARITH `(&2 * x + &1) * y / &2 = (x + &1 / &2) * y`]);;
1311
1312 let COS_ONE_2PI = prove
1313  (`!x. (cos(x) = &1) <=> (?n. x = &n * &2 * pi) \/ (?n. x = --(&n * &2 * pi))`,
1314   GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL
1315    [FIRST_ASSUM(MP_TAC o SPEC `sin(x)` o MATCH_MP (REAL_RING
1316      `c = &1 ==> !s. s pow 2 + c pow 2 = &1 ==> s = &0`)) THEN
1317     REWRITE_TAC[SIN_ZERO_PI; SIN_CIRCLE] THEN
1318     DISCH_THEN(DISJ_CASES_THEN(X_CHOOSE_THEN `n:num` SUBST_ALL_TAC)) THEN
1319     POP_ASSUM MP_TAC THEN REWRITE_TAC[COS_NEG; COS_NPI; REAL_POW_NEG] THEN
1320     COND_CASES_TAC THEN REWRITE_TAC[REAL_POW_ONE] THEN
1321     CONV_TAC REAL_RAT_REDUCE_CONV THEN
1322     FIRST_X_ASSUM(MP_TAC o REWRITE_RULE[EVEN_EXISTS]) THEN
1323     REWRITE_TAC[OR_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
1324     SIMP_TAC[GSYM REAL_OF_NUM_MUL] THEN REAL_ARITH_TAC;
1325     FIRST_X_ASSUM (DISJ_CASES_THEN CHOOSE_TAC) THEN
1326     ASM_REWRITE_TAC[COS_NEG; REAL_MUL_ASSOC; REAL_OF_NUM_MUL; COS_NPI;
1327                     REAL_POW_NEG; EVEN_MULT; ARITH; REAL_POW_ONE]]);;
1328
1329 let SIN_COS_SQRT = prove
1330  (`!x. &0 <= sin(x) ==> (sin(x) = sqrt(&1 - (cos(x) pow 2)))`,
1331   REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC SQRT_UNIQUE THEN
1332   ASM_REWRITE_TAC[SIN_CIRCLE; REAL_EQ_SUB_LADD]);;
1333
1334 let SIN_EQ_0_PI = prove
1335  (`!x. --pi < x /\ x < pi /\ sin(x) = &0 ==> x = &0`,
1336   GEN_TAC THEN REWRITE_TAC[SIN_EQ_0; CONJ_ASSOC] THEN
1337   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC
1338    (X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC)) THEN
1339   ASM_REWRITE_TAC[REAL_ARITH
1340    `--p < n * p /\ n * p < p <=> -- &1 * p < n * p /\ n * p < &1 * p`] THEN
1341   SIMP_TAC[REAL_ENTIRE; REAL_LT_IMP_NZ; REAL_LT_RMUL_EQ; PI_POS] THEN
1342   MP_TAC(SPEC `n:real` REAL_ABS_INTEGER_LEMMA) THEN
1343   ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
1344
1345 let COS_TREBLE_COS = prove
1346  (`!x. cos(&3 * x) = &4 * cos(x) pow 3 - &3 * cos x`,
1347   GEN_TAC THEN REWRITE_TAC[COS_ADD; REAL_ARITH `&3 * x = &2 * x + x`] THEN
1348   REWRITE_TAC[SIN_DOUBLE; COS_DOUBLE_COS] THEN
1349   MP_TAC(SPEC `x:real` SIN_CIRCLE) THEN CONV_TAC REAL_RING);;
1350
1351 let COS_PI6 = prove
1352  (`cos(pi / &6) = sqrt(&3) / &2`,
1353   MP_TAC(ISPEC `pi / &6` COS_TREBLE_COS) THEN
1354   REWRITE_TAC[REAL_ARITH `&3 * x / &6 = x / &2`; COS_PI2] THEN
1355   REWRITE_TAC[REAL_RING `&0 = &4 * c pow 3 - &3 * c <=>
1356                          c = &0 \/ (&2 * c) pow 2 = &3`] THEN
1357   SUBGOAL_THEN `&0 < cos(pi / &6)` ASSUME_TAC THENL
1358    [MATCH_MP_TAC COS_POS_PI THEN MP_TAC PI_POS THEN REAL_ARITH_TAC;
1359     DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL
1360      [ASM_MESON_TAC[REAL_LT_REFL]; ALL_TAC] THEN
1361     DISCH_THEN(MP_TAC o AP_TERM `sqrt`) THEN
1362     ASM_SIMP_TAC[POW_2_SQRT; REAL_LE_MUL; REAL_LT_IMP_LE; REAL_POS] THEN
1363     REAL_ARITH_TAC]);;
1364
1365 let SIN_PI6 = prove
1366  (`sin(pi / &6) = &1 / &2`,
1367   MP_TAC(SPEC `pi / &6` SIN_CIRCLE) THEN REWRITE_TAC[COS_PI6] THEN
1368   SIMP_TAC[REAL_POW_DIV; SQRT_POW_2; REAL_POS] THEN MATCH_MP_TAC(REAL_FIELD
1369    `~(s + &1 / &2 = &0) ==> s pow 2 + &3 / &2 pow 2 = &1 ==> s = &1 / &2`) THEN
1370   MATCH_MP_TAC(REAL_ARITH `&0 < x ==> ~(x + &1 / &2 = &0)`) THEN
1371   MATCH_MP_TAC SIN_POS_PI THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);;
1372
1373 let SIN_POS_PI_REV = prove
1374  (`!x. &0 <= x /\ x <= &2 * pi /\ &0 < sin x ==> &0 < x /\ x < pi`,
1375   GEN_TAC THEN ASM_CASES_TAC `x = &0` THEN
1376   ASM_REWRITE_TAC[SIN_0; REAL_LT_REFL] THEN
1377   ASM_CASES_TAC `x = pi` THEN
1378   ASM_REWRITE_TAC[SIN_PI; REAL_LT_REFL] THEN
1379   ASM_CASES_TAC `x = &2 * pi` THEN
1380   ASM_REWRITE_TAC[SIN_NPI; REAL_LT_REFL] THEN
1381   REPEAT STRIP_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
1382   REWRITE_TAC[GSYM REAL_NOT_LE] THEN DISCH_TAC THEN
1383   SUBGOAL_THEN `&0 < sin(&2 * pi - x)` MP_TAC THENL
1384    [MATCH_MP_TAC SIN_POS_PI THEN ASM_REAL_ARITH_TAC;
1385     REWRITE_TAC[SIN_SUB; SIN_NPI; COS_NPI] THEN ASM_REAL_ARITH_TAC]);;
1386
1387 (* ------------------------------------------------------------------------- *)
1388 (* Prove totality of trigs.                                                  *)
1389 (* ------------------------------------------------------------------------- *)
1390
1391 let SIN_TOTAL_POS = prove
1392  (`!y. &0 <= y /\ y <= &1
1393        ==> ?x. &0 <= x /\ x <= pi / &2 /\ sin(x) = y`,
1394   REPEAT STRIP_TAC THEN
1395   MP_TAC(SPECL [`csin`; `&0`; `pi / &2`; `y:real`] IVT_INCREASING_RE) THEN
1396   ASM_REWRITE_TAC[GSYM CX_SIN; RE_CX; SIN_0; SIN_PI2] THEN
1397   SIMP_TAC[CONTINUOUS_AT_CSIN; PI_POS; REAL_ARITH `&0 < x ==> &0 <= x / &2`]);;
1398
1399 let SINCOS_TOTAL_PI2 = prove
1400  (`!x y. &0 <= x /\ &0 <= y /\ x pow 2 + y pow 2 = &1
1401          ==> ?t. &0 <= t /\ t <= pi / &2 /\ x = cos t /\ y = sin t`,
1402   REPEAT STRIP_TAC THEN MP_TAC(SPEC `y:real` SIN_TOTAL_POS) THEN ANTS_TAC THENL
1403    [ASM_REWRITE_TAC[] THEN FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
1404      `x pow 2 + y pow 2 = &1
1405       ==> (&1 < y ==> &1 pow 2 < y pow 2) /\ &0 <= x * x
1406           ==> y <= &1`)) THEN
1407     SIMP_TAC[REAL_LE_SQUARE; REAL_POW_LT2; REAL_POS; ARITH];
1408     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real` THEN
1409     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1410     SUBGOAL_THEN `x = cos t \/ x = --(cos t)` MP_TAC THENL
1411      [MP_TAC(SPEC `t:real` SIN_CIRCLE);
1412       MP_TAC(SPEC `t:real` COS_POS_PI_LE)] THEN
1413     REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD]);;
1414
1415 let SINCOS_TOTAL_PI = prove
1416  (`!x y. &0 <= y /\ x pow 2 + y pow 2 = &1
1417          ==> ?t. &0 <= t /\ t <= pi /\ x = cos t /\ y = sin t`,
1418   REPEAT STRIP_TAC THEN DISJ_CASES_TAC(REAL_ARITH `&0 <= x \/ &0 <= --x`) THENL
1419    [MP_TAC(SPECL [`x:real`; `y:real`] SINCOS_TOTAL_PI2);
1420     MP_TAC(SPECL [`--x:real`; `y:real`] SINCOS_TOTAL_PI2)] THEN
1421   ASM_REWRITE_TAC[REAL_POW_NEG; ARITH] THEN
1422   DISCH_THEN(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THENL
1423    [EXISTS_TAC `t:real`; EXISTS_TAC `pi - t`] THEN
1424   ASM_REWRITE_TAC[SIN_SUB; COS_SUB; SIN_PI; COS_PI] THEN
1425   ASM_REAL_ARITH_TAC);;
1426
1427 let SINCOS_TOTAL_2PI = prove
1428  (`!x y. x pow 2 + y pow 2 = &1
1429          ==> ?t. &0 <= t /\ t < &2 * pi /\ x = cos t /\ y = sin t`,
1430   REPEAT STRIP_TAC THEN ASM_CASES_TAC `x = &1 /\ y = &0` THENL
1431    [EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[SIN_0; COS_0] THEN
1432     MP_TAC PI_POS THEN REAL_ARITH_TAC;
1433     ALL_TAC] THEN
1434   DISJ_CASES_TAC(REAL_ARITH `&0 <= y \/ &0 <= --y`) THENL
1435    [MP_TAC(SPECL [`x:real`; `y:real`] SINCOS_TOTAL_PI);
1436     MP_TAC(SPECL [`x:real`; `--y:real`] SINCOS_TOTAL_PI)] THEN
1437   ASM_REWRITE_TAC[REAL_POW_NEG; ARITH] THEN
1438   DISCH_THEN(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THENL
1439    [EXISTS_TAC `t:real`; EXISTS_TAC `&2 * pi - t`] THEN
1440   ASM_REWRITE_TAC[SIN_SUB; COS_SUB; SIN_NPI; COS_NPI] THENL
1441    [MP_TAC PI_POS THEN ASM_REAL_ARITH_TAC;
1442     ALL_TAC] THEN
1443   REPEAT(POP_ASSUM MP_TAC) THEN ASM_CASES_TAC `t = &0` THEN
1444   ASM_REWRITE_TAC[SIN_0; COS_0] THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);;
1445
1446 let CIRCLE_SINCOS = prove
1447  (`!x y. x pow 2 + y pow 2 = &1 ==> ?t. x = cos(t) /\ y = sin(t)`,
1448   MESON_TAC[SINCOS_TOTAL_2PI]);;
1449
1450 (* ------------------------------------------------------------------------- *)
1451 (* Polar representation.                                                     *)
1452 (* ------------------------------------------------------------------------- *)
1453
1454 let CX_PI_NZ = prove
1455  (`~(Cx pi = Cx(&0))`,
1456   SIMP_TAC[CX_INJ; REAL_LT_IMP_NZ; PI_POS]);;
1457
1458 let COMPLEX_UNIMODULAR_POLAR = prove
1459  (`!z. (norm z = &1) ==> ?x. z = complex(cos(x),sin(x))`,
1460   GEN_TAC THEN
1461   DISCH_THEN(MP_TAC o C AP_THM `2` o AP_TERM `(pow):real->num->real`) THEN
1462   REWRITE_TAC[complex_norm] THEN
1463   SIMP_TAC[REAL_POW_2; REWRITE_RULE[REAL_POW_2] SQRT_POW_2;
1464            REAL_LE_SQUARE; REAL_LE_ADD] THEN
1465   REWRITE_TAC[GSYM REAL_POW_2; REAL_MUL_LID] THEN
1466   DISCH_THEN(X_CHOOSE_TAC `t:real` o MATCH_MP CIRCLE_SINCOS) THEN
1467   EXISTS_TAC `t:real` THEN ASM_REWRITE_TAC[COMPLEX_EQ; RE; IM]);;
1468
1469 let SIN_INTEGER_2PI = prove
1470  (`!n. integer n ==> sin((&2 * pi) * n) = &0`,
1471   REWRITE_TAC[SIN_EQ_0; REAL_ARITH `(&2 * pi) * n = (&2 * n) * pi`] THEN
1472   MESON_TAC[INTEGER_CLOSED]);;
1473
1474 let SIN_INTEGER_PI = prove
1475  (`!n. integer n ==> sin (n * pi) = &0`,
1476   REWRITE_TAC[INTEGER_CASES] THEN REPEAT STRIP_TAC THEN
1477   ASM_REWRITE_TAC[REAL_MUL_LNEG; SIN_NPI; SIN_NEG; REAL_NEG_0]);;
1478
1479 let COS_INTEGER_2PI = prove
1480  (`!n. integer n ==> cos((&2 * pi) * n) = &1`,
1481   REWRITE_TAC[INTEGER_CASES; REAL_ARITH `(&2 * pi) * n = (&2 * n) * pi`] THEN
1482   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[REAL_MUL_RNEG; REAL_OF_NUM_MUL] THEN
1483   SIMP_TAC[COS_NEG; COS_NPI; REAL_POW_NEG; REAL_MUL_LNEG;
1484            ARITH; EVEN_MULT; REAL_POW_ONE]);;
1485
1486 let SINCOS_PRINCIPAL_VALUE = prove
1487  (`!x. ?y. (--pi < y /\ y <= pi) /\ (sin(y) = sin(x) /\ cos(y) = cos(x))`,
1488   GEN_TAC THEN EXISTS_TAC `pi - (&2 * pi) * frac((pi - x) / (&2 * pi))` THEN
1489   CONJ_TAC THENL
1490    [SIMP_TAC[REAL_ARITH `--p < p - x <=> x < (&2 * p) * &1`;
1491              REAL_ARITH `p - x <= p <=> (&2 * p) * &0 <= x`;
1492              REAL_LT_LMUL_EQ; REAL_LE_LMUL_EQ; REAL_LT_MUL;
1493              PI_POS; REAL_OF_NUM_LT; ARITH; FLOOR_FRAC];
1494    REWRITE_TAC[FRAC_FLOOR; REAL_SUB_LDISTRIB] THEN
1495    SIMP_TAC[REAL_DIV_LMUL; REAL_ENTIRE; REAL_OF_NUM_EQ; ARITH; REAL_LT_IMP_NZ;
1496     PI_POS; REAL_ARITH `a - (a - b - c):real = b + c`; SIN_ADD; COS_ADD] THEN
1497    SIMP_TAC[FLOOR_FRAC; SIN_INTEGER_2PI; COS_INTEGER_2PI] THEN
1498    CONV_TAC REAL_RING]);;
1499
1500 let CEXP_COMPLEX = prove
1501  (`!r t. cexp(complex(r,t)) = Cx(exp r) * complex(cos t,sin t)`,
1502   REPEAT GEN_TAC THEN
1503   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [COMPLEX_EXPAND] THEN
1504   REWRITE_TAC[RE; IM; CEXP_ADD; CEXP_EULER; CX_EXP] THEN
1505   REWRITE_TAC[COMPLEX_TRAD; CX_SIN; CX_COS]);;
1506
1507 let NORM_COSSIN = prove
1508  (`!t. norm(complex(cos t,sin t)) = &1`,
1509   REWRITE_TAC[complex_norm; RE; IM] THEN ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN
1510   REWRITE_TAC[SIN_CIRCLE; SQRT_1]);;
1511
1512 let NORM_CEXP = prove
1513  (`!z. norm(cexp z) = exp(Re z)`,
1514   REWRITE_TAC[FORALL_COMPLEX; CEXP_COMPLEX; COMPLEX_NORM_MUL] THEN
1515   REWRITE_TAC[NORM_COSSIN; RE; COMPLEX_NORM_CX] THEN
1516   MP_TAC REAL_EXP_POS_LT THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);;
1517
1518 let NORM_CEXP_II = prove
1519  (`!t. norm (cexp (ii * Cx t)) = &1`,
1520   REWRITE_TAC [NORM_CEXP; RE_MUL_II; IM_CX; REAL_NEG_0; REAL_EXP_0]);;
1521
1522 let NORM_CEXP_IMAGINARY = prove
1523  (`!z. norm(cexp z) = &1 ==> Re(z) = &0`,
1524   REWRITE_TAC[NORM_CEXP; REAL_EXP_EQ_1]);;
1525
1526 let CEXP_EQ_1 = prove
1527  (`!z. cexp z = Cx(&1) <=> Re(z) = &0 /\ ?n. integer n /\ Im(z) = &2 * n * pi`,
1528   REWRITE_TAC[FORALL_COMPLEX; CEXP_COMPLEX; RE; IM] THEN
1529   MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN EQ_TAC THENL
1530    [DISCH_TAC THEN FIRST_ASSUM(MP_TAC o AP_TERM `norm:complex->real`) THEN
1531     SIMP_TAC[COMPLEX_NORM_MUL; CX_EXP; NORM_CEXP; RE_CX; COMPLEX_NORM_CX] THEN
1532     REWRITE_TAC[NORM_COSSIN; REAL_ABS_NUM; REAL_ABS_EXP; REAL_MUL_RID] THEN
1533     REWRITE_TAC[REAL_EXP_EQ_1] THEN DISCH_THEN SUBST_ALL_TAC THEN
1534     POP_ASSUM MP_TAC THEN REWRITE_TAC[REAL_EXP_0; COMPLEX_MUL_LID] THEN
1535     REWRITE_TAC[COMPLEX_EQ; RE; IM; RE_CX; IM_CX] THEN STRIP_TAC THEN
1536     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SIN_EQ_0]) THEN
1537     DISCH_THEN(X_CHOOSE_THEN `m:real`
1538      (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) THEN
1539     EXISTS_TAC `m / &2` THEN CONJ_TAC THENL [ALL_TAC; REAL_ARITH_TAC] THEN
1540     ONCE_REWRITE_TAC[GSYM INTEGER_ABS] THEN
1541     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE LAND_CONV [GSYM COS_ABS]) THEN
1542     REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_DIV; REAL_ABS_NUM] THEN
1543     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [integer]) THEN
1544     DISCH_THEN(X_CHOOSE_THEN `n:num` SUBST_ALL_TAC) THEN
1545     SIMP_TAC[real_abs; PI_POS; REAL_LT_IMP_LE; COS_NPI] THEN
1546     REWRITE_TAC[REAL_POW_NEG; REAL_POW_ONE] THEN
1547     COND_CASES_TAC THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
1548     FIRST_X_ASSUM(CHOOSE_THEN SUBST1_TAC o REWRITE_RULE[EVEN_EXISTS]) THEN
1549     REWRITE_TAC[GSYM REAL_OF_NUM_MUL; REAL_ARITH `(&2 * x) / &2 = x`] THEN
1550     REWRITE_TAC[INTEGER_CLOSED];
1551     DISCH_THEN(CONJUNCTS_THEN2 SUBST1_TAC (X_CHOOSE_TAC `n:real`)) THEN
1552     ASM_SIMP_TAC[REAL_EXP_0; COMPLEX_MUL_LID] THEN
1553     ONCE_REWRITE_TAC[REAL_ARITH `&2 * x * y = (&2 * y) * x`] THEN
1554     ASM_SIMP_TAC[SIN_INTEGER_2PI; COS_INTEGER_2PI] THEN
1555     SIMPLE_COMPLEX_ARITH_TAC]);;
1556
1557 let CEXP_EQ = prove
1558  (`!w z. cexp w = cexp z <=> ?n. integer n /\ w = z + Cx(&2 * n * pi) * ii`,
1559   SIMP_TAC[CEXP_NZ; COMPLEX_FIELD
1560    `~(z = Cx(&0)) ==> (w = z <=> w / z = Cx(&1))`] THEN
1561   REWRITE_TAC[GSYM CEXP_SUB; CEXP_EQ_1; RE_SUB; IM_SUB; REAL_SUB_0] THEN
1562   SIMP_TAC[COMPLEX_EQ; RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II; RE_CX; IM_CX] THEN
1563   REWRITE_TAC[REAL_NEG_0; REAL_ADD_RID; REAL_EQ_SUB_RADD] THEN
1564   MESON_TAC[REAL_ADD_SYM]);;
1565
1566 let COMPLEX_EQ_CEXP = prove
1567  (`!w z. abs(Im w - Im z) < &2 * pi /\ cexp w = cexp z ==> w = z`,
1568   SIMP_TAC[CEXP_NZ; GSYM CEXP_SUB; CEXP_EQ_1; COMPLEX_FIELD
1569    `~(a = Cx(&0)) /\ ~(b = Cx(&0)) ==> (a = b <=> a / b = Cx(&1))`] THEN
1570   REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
1571   FIRST_X_ASSUM(X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC) THEN
1572   UNDISCH_TAC `abs(Im w - Im z) < &2 * pi` THEN
1573   ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
1574   ASM_REWRITE_TAC[GSYM IM_SUB; REAL_ABS_MUL; REAL_ABS_PI; REAL_ABS_NUM] THEN
1575   SIMP_TAC[REAL_MUL_ASSOC; REAL_LT_RMUL_EQ; PI_POS] THEN
1576   MATCH_MP_TAC(REAL_ARITH `&1 <= x ==> ~(&2 * x < &2)`) THEN
1577   MATCH_MP_TAC REAL_ABS_INTEGER_LEMMA THEN ASM_REWRITE_TAC[] THEN
1578   DISCH_THEN SUBST_ALL_TAC THEN UNDISCH_TAC `~(w:complex = z)` THEN
1579   REWRITE_TAC[] THEN ONCE_REWRITE_TAC[GSYM COMPLEX_SUB_0] THEN
1580   ASM_REWRITE_TAC[COMPLEX_EQ; RE_CX; IM_CX; REAL_MUL_LZERO; REAL_MUL_RZERO]);;
1581
1582 let CEXP_INTEGER_2PI = prove
1583  (`!n. integer n ==> cexp(Cx(&2 * n * pi) * ii) = Cx(&1)`,
1584   REWRITE_TAC[CEXP_EQ_1; IM_MUL_II; RE_MUL_II; RE_CX; IM_CX] THEN
1585   REWRITE_TAC[REAL_NEG_0] THEN MESON_TAC[]);;
1586
1587 let SIN_COS_EQ = prove
1588  (`!x y. sin y = sin x /\ cos y = cos x <=>
1589          ?n. integer n /\ y = x + &2 * n * pi`,
1590   REPEAT GEN_TAC THEN MP_TAC(ISPECL [`ii * Cx y`; `ii * Cx x`] CEXP_EQ) THEN
1591   REWRITE_TAC[CEXP_EULER; GSYM CX_SIN; GSYM CX_COS] THEN
1592   REWRITE_TAC[COMPLEX_RING `ii * y = ii * x + z * ii <=> y = x + z`] THEN
1593   REWRITE_TAC[GSYM CX_ADD; CX_INJ] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
1594   REWRITE_TAC[COMPLEX_EQ; RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II; RE_CX; IM_CX;
1595               REAL_NEG_0; REAL_ADD_LID; REAL_ADD_RID] THEN
1596   MESON_TAC[]);;
1597
1598 let SIN_COS_INJ = prove
1599  (`!x y. sin x = sin y /\ cos x = cos y /\ abs(x - y) < &2 * pi ==> x = y`,
1600   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM CX_INJ] THEN
1601   MATCH_MP_TAC(COMPLEX_RING `ii * x = ii * y ==> x = y`) THEN
1602   MATCH_MP_TAC COMPLEX_EQ_CEXP THEN
1603   ASM_REWRITE_TAC[CEXP_EULER; GSYM CX_SIN; GSYM CX_COS] THEN
1604   ASM_REWRITE_TAC[IM_MUL_II; RE_CX]);;
1605
1606 let CEXP_II_NE_1 = prove
1607  (`!x. &0 < x /\ x < &2 * pi ==> ~(cexp(ii * Cx x) = Cx(&1))`,
1608   GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[CEXP_EQ_1] THEN
1609   REWRITE_TAC[RE_MUL_II; IM_CX; IM_MUL_II; IM_CX; REAL_NEG_0; RE_CX] THEN
1610   DISCH_THEN(X_CHOOSE_THEN `n:real`
1611    (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) THEN
1612   UNDISCH_TAC `&0 < &2 * n * pi` THEN ASM_CASES_TAC `n = &0` THEN
1613   ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO; REAL_LT_REFL] THEN
1614   MP_TAC(ISPEC `n:real` REAL_ABS_INTEGER_LEMMA) THEN ASM_REWRITE_TAC[] THEN
1615   DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH
1616    `&2 * n * pi < &2 * pi ==> &0 < (&1 - n) * &2 * pi`)) THEN
1617   ASM_SIMP_TAC[REAL_LT_MUL_EQ; PI_POS; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN
1618   ASM_REAL_ARITH_TAC);;
1619
1620 let CSIN_EQ_0 = prove
1621  (`!z. csin z = Cx(&0) <=> ?n. integer n /\ z = Cx(n * pi)`,
1622   GEN_TAC THEN REWRITE_TAC[csin; COMPLEX_MUL_LNEG; CEXP_NEG] THEN
1623   SIMP_TAC[CEXP_NZ; COMPLEX_FIELD `~(z = Cx(&0))
1624         ==> ((z - inv z) / (Cx(&2) * ii) = Cx(&0) <=> z pow 2 = Cx(&1))`] THEN
1625   REWRITE_TAC[GSYM CEXP_N; CEXP_EQ_1] THEN
1626   REWRITE_TAC[RE_MUL_CX; IM_MUL_CX; RE_MUL_II; IM_MUL_II] THEN
1627   REWRITE_TAC[COMPLEX_EQ; IM_CX; RE_CX; RIGHT_AND_EXISTS_THM] THEN
1628   EQ_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN REAL_ARITH_TAC);;
1629
1630 let CCOS_EQ_0 = prove
1631  (`!z. ccos z = Cx(&0) <=> ?n. integer n /\ z = Cx((n + &1 / &2) * pi)`,
1632   GEN_TAC THEN MP_TAC(SPEC `z - Cx(pi / &2)` CSIN_EQ_0) THEN
1633   REWRITE_TAC[CSIN_SUB; GSYM CX_SIN; GSYM CX_COS; SIN_PI2; COS_PI2] THEN
1634   SIMP_TAC[COMPLEX_RING `s * Cx(&0) - c * Cx(&1) = Cx(&0) <=> c = Cx(&0)`] THEN
1635   REWRITE_TAC[REAL_ADD_RDISTRIB; COMPLEX_EQ_SUB_RADD; CX_ADD] THEN
1636   REWRITE_TAC[REAL_ARITH `&1 / &2 * x = x / &2`]);;
1637
1638 let CCOS_EQ_1 = prove
1639  (`!z. ccos z = Cx(&1) <=> ?n. integer n /\ z = Cx(&2 * n * pi)`,
1640   GEN_TAC THEN GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o RAND_CONV)
1641    [COMPLEX_RING `z = Cx(&2) * z / Cx(&2)`] THEN
1642   REWRITE_TAC[CCOS_DOUBLE_CSIN; COMPLEX_RING
1643    `a - Cx(&2) * s pow 2 = a <=> s = Cx(&0)`] THEN
1644   REWRITE_TAC[CSIN_EQ_0; CX_MUL] THEN
1645   EQ_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN
1646   CONV_TAC COMPLEX_RING);;
1647
1648 let CSIN_EQ_1 = prove
1649  (`!z. csin z = Cx(&1) <=> ?n. integer n /\ z = Cx((&2 * n + &1 / &2) * pi)`,
1650   GEN_TAC THEN MP_TAC(SPEC `z - Cx(pi / &2)` CCOS_EQ_1) THEN
1651   REWRITE_TAC[CCOS_SUB; GSYM CX_SIN; GSYM CX_COS; SIN_PI2; COS_PI2] THEN
1652   SIMP_TAC[COMPLEX_RING `s * Cx(&0) + c * Cx(&1) = Cx(&1) <=> c = Cx(&1)`] THEN
1653   REWRITE_TAC[REAL_ADD_RDISTRIB; COMPLEX_EQ_SUB_RADD; CX_ADD] THEN
1654   REWRITE_TAC[REAL_MUL_ASSOC; REAL_ARITH `&1 / &2 * x = x / &2`]);;
1655
1656 let CSIN_EQ_MINUS1 = prove
1657  (`!z. csin z = --Cx(&1) <=>
1658        ?n. integer n /\ z = Cx((&2 * n + &3 / &2) * pi)`,
1659   GEN_TAC THEN REWRITE_TAC[COMPLEX_RING `z:complex = --w <=> --z = w`] THEN
1660   REWRITE_TAC[GSYM CSIN_NEG; CSIN_EQ_1] THEN
1661   REWRITE_TAC[COMPLEX_RING `--z:complex = w <=> z = --w`] THEN
1662   EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC) THEN
1663   ASM_REWRITE_TAC[GSYM CX_NEG; CX_INJ] THEN
1664   EXISTS_TAC `--(n + &1)` THEN
1665   ASM_SIMP_TAC[INTEGER_CLOSED] THEN REAL_ARITH_TAC);;
1666
1667 let CCOS_EQ_MINUS1 = prove
1668  (`!z. ccos z = --Cx(&1) <=>
1669        ?n. integer n /\ z = Cx((&2 * n + &1) * pi)`,
1670   GEN_TAC THEN MP_TAC(SPEC `z - Cx(pi / &2)` CSIN_EQ_1) THEN
1671   REWRITE_TAC[CSIN_SUB; GSYM CX_SIN; GSYM CX_COS; SIN_PI2; COS_PI2] THEN
1672   SIMP_TAC[COMPLEX_RING
1673     `s * Cx(&0) - c * Cx(&1) = Cx(&1) <=> c = --Cx(&1)`] THEN
1674   REWRITE_TAC[REAL_ADD_RDISTRIB; COMPLEX_EQ_SUB_RADD; GSYM CX_ADD] THEN
1675   DISCH_TAC THEN EQ_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN
1676   SIMP_TAC[CX_INJ] THEN REAL_ARITH_TAC);;
1677
1678 let COS_EQ_1 = prove
1679  (`!x. cos x = &1 <=> ?n. integer n /\ x = &2 * n * pi`,
1680   REWRITE_TAC[GSYM CX_INJ; CX_COS; CCOS_EQ_1]);;
1681
1682 let SIN_EQ_1 = prove
1683  (`!x. sin x = &1 <=> ?n. integer n /\ x = (&2 * n + &1 / &2) * pi`,
1684   REWRITE_TAC[GSYM CX_INJ; CX_SIN; CSIN_EQ_1]);;
1685
1686 let SIN_EQ_MINUS1 = prove
1687  (`!x. sin x = --(&1) <=> ?n. integer n /\ x = (&2 * n + &3 / &2) * pi`,
1688   REWRITE_TAC[GSYM CX_INJ; CX_NEG; CX_SIN; CSIN_EQ_MINUS1]);;
1689
1690 let COS_EQ_MINUS1 = prove
1691  (`!x. cos x = --(&1) <=>
1692        ?n. integer n /\ x = (&2 * n + &1) * pi`,
1693   REWRITE_TAC[GSYM CX_INJ; CX_NEG; CX_COS; CCOS_EQ_MINUS1]);;
1694
1695 let DIST_CEXP_II_1 = prove
1696  (`!z. norm(cexp(ii * Cx t) - Cx(&1)) = &2 * abs(sin(t / &2))`,
1697   GEN_TAC THEN REWRITE_TAC[NORM_EQ_SQUARE] THEN
1698   CONJ_TAC THENL [REAL_ARITH_TAC; REWRITE_TAC[GSYM NORM_POW_2]] THEN
1699   REWRITE_TAC[CEXP_EULER; COMPLEX_SQNORM; GSYM CX_COS; GSYM CX_SIN] THEN
1700   REWRITE_TAC[IM_ADD; RE_ADD; IM_SUB; RE_SUB; IM_MUL_II; RE_MUL_II] THEN
1701   REWRITE_TAC[RE_CX; IM_CX; REAL_POW2_ABS; REAL_POW_MUL] THEN
1702   MP_TAC(ISPEC `t / &2` COS_DOUBLE_SIN) THEN
1703   REWRITE_TAC[REAL_ARITH `&2 * t / &2 = t`] THEN
1704   MP_TAC(SPEC `t:real` SIN_CIRCLE) THEN CONV_TAC REAL_RING);;
1705
1706 let CX_SINH = prove
1707  (`Cx((exp x - inv(exp x)) / &2) = --ii * csin(ii * Cx x)`,
1708   REWRITE_TAC[csin; COMPLEX_RING `--ii * ii * z = z /\ ii * ii * z = --z`] THEN
1709   REWRITE_TAC[CEXP_NEG; GSYM CX_EXP; GSYM CX_INV; CX_SUB; CX_DIV] THEN
1710   CONV_TAC COMPLEX_FIELD);;
1711
1712 let CX_COSH = prove
1713  (`Cx((exp x + inv(exp x)) / &2) = ccos(ii * Cx x)`,
1714   REWRITE_TAC[ccos; COMPLEX_RING `--ii * ii * z = z /\ ii * ii * z = --z`] THEN
1715   REWRITE_TAC[CEXP_NEG; GSYM CX_EXP; GSYM CX_INV; CX_ADD; CX_DIV] THEN
1716   CONV_TAC COMPLEX_FIELD);;
1717
1718 let NORM_CCOS_POW_2 = prove
1719  (`!z. norm(ccos z) pow 2 =
1720        cos(Re z) pow 2 + (exp(Im z) - inv(exp(Im z))) pow 2 / &4`,
1721   REWRITE_TAC[FORALL_COMPLEX; RE; IM] THEN
1722   REWRITE_TAC[COMPLEX_TRAD; CCOS_ADD; COMPLEX_SQNORM] THEN
1723   SIMP_TAC[RE_SUB; IM_SUB; GSYM CX_COS; GSYM CX_SIN; IM_MUL_CX; RE_MUL_CX] THEN
1724   REWRITE_TAC[ccos; csin; CEXP_NEG; COMPLEX_FIELD
1725    `--ii * ii * z = z /\ ii * ii * z = --z /\
1726     z / (Cx(&2) * ii) = --(ii * z / Cx(&2))`] THEN
1727   REWRITE_TAC[RE_ADD; RE_SUB; IM_ADD; IM_SUB; RE_MUL_II; IM_MUL_II;
1728               RE_DIV_CX; IM_DIV_CX; RE_NEG; IM_NEG] THEN
1729   REWRITE_TAC[GSYM CX_EXP; GSYM CX_INV; IM_CX; RE_CX] THEN
1730   MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN
1731   MP_TAC(SPEC `x:real` SIN_CIRCLE) THEN MP_TAC(SPEC `y:real` REAL_EXP_NZ) THEN
1732   CONV_TAC REAL_FIELD);;
1733
1734 let NORM_CSIN_POW_2 = prove
1735  (`!z. norm(csin z) pow 2 =
1736        (exp(&2 * Im z) + inv(exp(&2 * Im z)) - &2 * cos(&2 * Re z)) / &4`,
1737   REWRITE_TAC[FORALL_COMPLEX; RE; IM] THEN
1738   REWRITE_TAC[COMPLEX_TRAD; CSIN_ADD; COMPLEX_SQNORM] THEN
1739   SIMP_TAC[RE_ADD; IM_ADD; GSYM CX_SIN; GSYM CX_SIN; IM_MUL_CX; RE_MUL_CX;
1740            GSYM CX_COS] THEN
1741   REWRITE_TAC[ccos; csin; CEXP_NEG; COMPLEX_FIELD
1742    `--ii * ii * z = z /\ ii * ii * z = --z /\
1743     z / (Cx(&2) * ii) = --(ii * z / Cx(&2))`] THEN
1744   REWRITE_TAC[RE_ADD; RE_SUB; IM_ADD; IM_SUB; RE_MUL_II; IM_MUL_II;
1745               RE_DIV_CX; IM_DIV_CX; RE_NEG; IM_NEG] THEN
1746   REWRITE_TAC[GSYM CX_EXP; GSYM CX_INV; IM_CX; RE_CX] THEN
1747   REWRITE_TAC[REAL_EXP_N; COS_DOUBLE] THEN
1748   MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN
1749   MP_TAC(SPEC `x:real` SIN_CIRCLE) THEN MP_TAC(SPEC `y:real` REAL_EXP_NZ) THEN
1750   CONV_TAC REAL_FIELD);;
1751
1752 let CSIN_EQ = prove
1753  (`!w z. csin w = csin z <=>
1754          ?n. integer n /\
1755              (w = z + Cx(&2 * n * pi) \/ w = --z + Cx((&2 * n + &1) * pi))`,
1756   REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM COMPLEX_SUB_0] THEN
1757   REWRITE_TAC[COMPLEX_SUB_CSIN; COMPLEX_ENTIRE; CSIN_EQ_0; CCOS_EQ_0] THEN
1758   REWRITE_TAC[CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ; OR_EXISTS_THM] THEN
1759   AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `n:real` THEN
1760   ASM_CASES_TAC `integer(n)` THEN
1761   ASM_REWRITE_TAC[COMPLEX_FIELD `a / Cx(&2) = b <=> a = Cx(&2) * b`] THEN
1762   REWRITE_TAC[GSYM CX_MUL; REAL_ARITH
1763     `&2 * (n + &1 / &2) * pi = (&2 * n + &1) * pi`] THEN
1764   CONV_TAC COMPLEX_RING);;
1765
1766 let CCOS_EQ = prove
1767  (`!w z. ccos(w) = ccos(z) <=>
1768          ?n. integer n /\
1769              (w = z + Cx(&2 * n * pi) \/ w = --z + Cx(&2 * n * pi))`,
1770   REPEAT GEN_TAC THEN CONV_TAC(LAND_CONV SYM_CONV) THEN
1771   GEN_REWRITE_TAC LAND_CONV [GSYM COMPLEX_SUB_0] THEN
1772   REWRITE_TAC[COMPLEX_SUB_CCOS; COMPLEX_ENTIRE; CSIN_EQ_0] THEN
1773   REWRITE_TAC[CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ; OR_EXISTS_THM] THEN
1774   AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `n:real` THEN
1775   ASM_CASES_TAC `integer(n)` THEN ASM_REWRITE_TAC[CX_MUL] THEN
1776   CONV_TAC COMPLEX_RING);;
1777
1778 let SIN_EQ = prove
1779  (`!x y. sin x = sin y <=>
1780          ?n. integer n /\
1781              (x = y + &2 * n * pi \/ x = --y + (&2 * n + &1) * pi)`,
1782   REWRITE_TAC[GSYM CX_INJ; CX_SIN; CSIN_EQ] THEN
1783   REWRITE_TAC[GSYM CX_ADD; GSYM CX_NEG; CX_INJ]);;
1784
1785 let COS_EQ = prove
1786  (`!x y. cos x = cos y <=>
1787          ?n. integer n /\
1788              (x = y + &2 * n * pi \/ x = --y + &2 * n * pi)`,
1789   REWRITE_TAC[GSYM CX_INJ; CX_COS; CCOS_EQ] THEN
1790   REWRITE_TAC[GSYM CX_ADD; GSYM CX_NEG; CX_INJ]);;
1791
1792 let NORM_CCOS_LE = prove
1793  (`!z. norm(ccos z) <= exp(norm z)`,
1794   GEN_TAC THEN REWRITE_TAC[ccos] THEN
1795   REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; REAL_ABS_NUM] THEN
1796   REWRITE_TAC[REAL_ARITH `x / &2 <= y <=> x <= &2 * y`] THEN
1797   MATCH_MP_TAC(NORM_ARITH
1798    `norm(a) + norm(b) <= d ==> norm(a + b) <= d`) THEN
1799   REWRITE_TAC[NORM_CEXP; COMPLEX_MUL_LNEG; RE_NEG; REAL_EXP_NEG] THEN
1800   REWRITE_TAC[COMPLEX_NORM_CX; RE_MUL_II; REAL_ABS_NUM] THEN
1801   MATCH_MP_TAC(REAL_ARITH
1802    `exp(&0) = &1 /\ (exp(&0) <= w \/ exp(&0) <= z) /\ (w <= u /\ z <= u)
1803     ==> w + z <= &2 * u`) THEN
1804   REWRITE_TAC[GSYM REAL_EXP_NEG; REAL_EXP_MONO_LE] THEN
1805   REWRITE_TAC[REAL_EXP_0] THEN
1806   MP_TAC(SPEC `z:complex` COMPLEX_NORM_GE_RE_IM) THEN
1807   REAL_ARITH_TAC);;
1808
1809 let NORM_CCOS_PLUS1_LE = prove
1810  (`!z. norm(Cx(&1) + ccos z) <= &2 * exp(norm z)`,
1811   GEN_TAC THEN REWRITE_TAC[ccos] THEN
1812   REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; REAL_ABS_NUM; COMPLEX_RING
1813    `Cx(&1) + (z + z') / Cx(&2) = (Cx(&2) + z + z') / Cx(&2)`] THEN
1814   REWRITE_TAC[REAL_ARITH `x / &2 <= &2 * y <=> x <= &4 * y`] THEN
1815   MATCH_MP_TAC(NORM_ARITH
1816    `norm(a) + norm(b) + norm(c) <= d ==> norm(a + b + c) <= d`) THEN
1817   REWRITE_TAC[NORM_CEXP; COMPLEX_MUL_LNEG; RE_NEG; REAL_EXP_NEG] THEN
1818   REWRITE_TAC[COMPLEX_NORM_CX; RE_MUL_II; REAL_ABS_NUM] THEN
1819   MATCH_MP_TAC(REAL_ARITH
1820    `exp(&0) = &1 /\ (exp(&0) <= w \/ exp(&0) <= z) /\ (w <= u /\ z <= u)
1821     ==> &2 + w + z <= &4 * u`) THEN
1822   REWRITE_TAC[GSYM REAL_EXP_NEG; REAL_EXP_MONO_LE] THEN
1823   REWRITE_TAC[REAL_EXP_0] THEN
1824   MP_TAC(SPEC `z:complex` COMPLEX_NORM_GE_RE_IM) THEN
1825   REAL_ARITH_TAC);;
1826
1827 (* ------------------------------------------------------------------------- *)
1828 (* Taylor series for complex exponential.                                    *)
1829 (* ------------------------------------------------------------------------- *)
1830
1831 let TAYLOR_CEXP = prove
1832  (`!n z. norm(cexp z - vsum(0..n) (\k. z pow k / Cx(&(FACT k))))
1833          <= exp(abs(Re z)) * (norm z) pow (n + 1) / &(FACT n)`,
1834   REPEAT GEN_TAC THEN MP_TAC(ISPECL
1835    [`\k:num. cexp`; `n:num`; `segment[Cx(&0),z]`; `exp(abs(Re z))`]
1836         COMPLEX_TAYLOR) THEN
1837   REWRITE_TAC[CONVEX_SEGMENT; NORM_CEXP; REAL_EXP_MONO_LE] THEN ANTS_TAC THENL
1838    [REWRITE_TAC[IN_SEGMENT] THEN REPEAT STRIP_TAC THENL
1839      [GEN_REWRITE_TAC(RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
1840       COMPLEX_DIFF_TAC THEN REWRITE_TAC[COMPLEX_MUL_LID];
1841       ASM_REWRITE_TAC[GSYM COMPLEX_VEC_0; VECTOR_MUL_RZERO] THEN
1842       REWRITE_TAC[VECTOR_ADD_LID; COMPLEX_CMUL; COMPLEX_NORM_MUL] THEN
1843       GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN
1844       MATCH_MP_TAC(REAL_ARITH `abs x <= a ==> x <= a`) THEN
1845       REWRITE_TAC[RE_MUL_CX; REAL_ABS_MUL] THEN MATCH_MP_TAC REAL_LE_RMUL THEN
1846       ASM_REAL_ARITH_TAC];
1847     DISCH_THEN(MP_TAC o SPECL [`Cx(&0)`; `z:complex`]) THEN
1848     SIMP_TAC[ENDS_IN_SEGMENT; COMPLEX_SUB_RZERO; CEXP_0; COMPLEX_MUL_LID]]);;
1849
1850 (* ------------------------------------------------------------------------- *)
1851 (* Approximation to e.                                                       *)
1852 (* ------------------------------------------------------------------------- *)
1853
1854 let E_APPROX_32 = prove
1855  (`abs(exp(&1) - &11674931555 / &4294967296) <= inv(&2 pow 32)`,
1856   let lemma = prove
1857    (`abs(e - x) <= e * d
1858      ==> &0 <= d /\ d < &1
1859          ==> abs(e - x) <= x * d / (&1 - d)`,
1860     DISCH_THEN(fun th -> STRIP_TAC THEN ASSUME_TAC th THEN MP_TAC th) THEN
1861     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
1862     ASM_SIMP_TAC[REAL_ARITH `e * d <= x * d / i <=> d * e <= d * x / i`] THEN
1863     MATCH_MP_TAC REAL_LE_LMUL THEN ASM_REWRITE_TAC[] THEN
1864    ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN ASM_REAL_ARITH_TAC) in
1865   MP_TAC(ISPECL [`14`; `Cx(&1)`] TAYLOR_CEXP) THEN
1866   SIMP_TAC[GSYM CX_EXP; RE_CX; COMPLEX_NORM_CX; REAL_ABS_NUM;
1867            REAL_POW_ONE; GSYM CX_DIV; GSYM CX_POW] THEN
1868   CONV_TAC(ONCE_DEPTH_CONV EXPAND_VSUM_CONV) THEN
1869   REWRITE_TAC[GSYM CX_ADD; GSYM CX_SUB; COMPLEX_NORM_CX] THEN
1870   CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
1871   DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN REAL_ARITH_TAC);;
1872
1873 (* ------------------------------------------------------------------------- *)
1874 (* Taylor series for complex sine and cosine.                                *)
1875 (* ------------------------------------------------------------------------- *)
1876
1877 let TAYLOR_CSIN_RAW = prove
1878  (`!n z. norm(csin z -
1879               vsum(0..n) (\k. if ODD k
1880                               then --ii * (ii * z) pow k / Cx(&(FACT k))
1881                               else Cx(&0)))
1882          <= exp(abs(Im z)) * (norm z) pow (n + 1) / &(FACT n)`,
1883   MP_TAC TAYLOR_CEXP THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:num` THEN
1884   DISCH_TAC THEN X_GEN_TAC `z:complex` THEN REWRITE_TAC[csin] THEN
1885   REWRITE_TAC[COMPLEX_FIELD
1886     `a / (Cx(&2) * ii) - b = (a - Cx(&2) * ii * b) / (Cx(&2) * ii)`] THEN
1887   FIRST_ASSUM(fun th ->
1888     MP_TAC(SPEC `ii * z` th) THEN MP_TAC(SPEC `--ii * z` th)) THEN
1889   REWRITE_TAC[COMPLEX_MUL_LNEG; RE_NEG; REAL_ABS_NEG; RE_MUL_II] THEN
1890   REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_MUL; COMPLEX_NORM_CX; NORM_NEG;
1891               COMPLEX_NORM_II; REAL_ABS_NUM; REAL_MUL_RID; REAL_MUL_LID;
1892               REAL_ARITH `x / &2 <= y <=> x <= &2 * y`] THEN
1893   MATCH_MP_TAC(NORM_ARITH
1894    `sp - sn = s2
1895     ==> norm(en - sn) <= d
1896         ==> norm(ep - sp) <= d ==> norm(ep - en - s2) <= &2 * d`) THEN
1897   SIMP_TAC[GSYM VSUM_SUB; GSYM VSUM_COMPLEX_LMUL; FINITE_NUMSEG] THEN
1898   MATCH_MP_TAC VSUM_EQ THEN X_GEN_TAC `k:num` THEN DISCH_TAC THEN
1899   REWRITE_TAC[COMPLEX_POW_NEG; GSYM NOT_EVEN] THEN ASM_CASES_TAC `EVEN k` THEN
1900   ASM_REWRITE_TAC[COMPLEX_SUB_REFL; COMPLEX_MUL_RZERO] THEN
1901   REWRITE_TAC[COMPLEX_RING `Cx(&2) * ii * --(ii * z) = Cx(&2) * z`] THEN
1902   SIMPLE_COMPLEX_ARITH_TAC);;
1903
1904 let TAYLOR_CSIN = prove
1905  (`!n z. norm(csin z -
1906               vsum(0..n) (\k. --Cx(&1) pow k *
1907                               z pow (2 * k + 1) / Cx(&(FACT(2 * k + 1)))))
1908          <= exp(abs(Im z)) * norm(z) pow (2 * n + 3) / &(FACT(2 * n + 2))`,
1909   REPEAT STRIP_TAC THEN
1910   MP_TAC(ISPECL [`SUC(2 * n + 1)`; `z:complex`] TAYLOR_CSIN_RAW) THEN
1911   SIMP_TAC[VSUM_CLAUSES_NUMSEG; VSUM_PAIR_0; ODD_ADD; ODD_MULT; ARITH_ODD;
1912            LE_0; ODD; COMPLEX_ADD_LID; COMPLEX_ADD_RID] THEN
1913   SIMP_TAC[ARITH_RULE `SUC(2 * n + 1) = 2 * n + 2`; GSYM ADD_ASSOC; ARITH] THEN
1914   MATCH_MP_TAC(NORM_ARITH
1915    `s = t ==> norm(x - s) <= e ==> norm(x - t) <= e`) THEN
1916   MATCH_MP_TAC VSUM_EQ THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
1917   REWRITE_TAC[COMPLEX_POW_MUL; complex_div; COMPLEX_MUL_ASSOC] THEN
1918   AP_THM_TAC THEN AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
1919   REWRITE_TAC[COMPLEX_POW_ADD; GSYM COMPLEX_POW_POW] THEN
1920   REWRITE_TAC[COMPLEX_POW_II_2] THEN CONV_TAC COMPLEX_RING);;
1921
1922 let TAYLOR_CCOS_RAW = prove
1923  (`!n z. norm(ccos z -
1924               vsum(0..n) (\k. if EVEN k
1925                               then (ii * z) pow k / Cx(&(FACT k))
1926                               else Cx(&0)))
1927          <= exp(abs(Im z)) * (norm z) pow (n + 1) / &(FACT n)`,
1928   MP_TAC TAYLOR_CEXP THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:num` THEN
1929   DISCH_TAC THEN X_GEN_TAC `z:complex` THEN REWRITE_TAC[ccos] THEN
1930   REWRITE_TAC[COMPLEX_FIELD
1931     `a / Cx(&2) - b = (a - Cx(&2) * b) / Cx(&2)`] THEN
1932   FIRST_ASSUM(fun th ->
1933     MP_TAC(SPEC `ii * z` th) THEN MP_TAC(SPEC `--ii * z` th)) THEN
1934   REWRITE_TAC[COMPLEX_MUL_LNEG; RE_NEG; REAL_ABS_NEG; RE_MUL_II] THEN
1935   REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_MUL; COMPLEX_NORM_CX; NORM_NEG;
1936               COMPLEX_NORM_II; REAL_ABS_NUM; REAL_MUL_RID; REAL_MUL_LID;
1937               REAL_ARITH `x / &2 <= y <=> x <= &2 * y`] THEN
1938   MATCH_MP_TAC(NORM_ARITH
1939    `sp + sn = s2
1940     ==> norm(en - sn) <= d
1941         ==> norm(ep - sp) <= d ==> norm((ep + en) - s2) <= &2 * d`) THEN
1942   SIMP_TAC[GSYM VSUM_ADD; GSYM VSUM_COMPLEX_LMUL; FINITE_NUMSEG] THEN
1943   MATCH_MP_TAC VSUM_EQ THEN X_GEN_TAC `k:num` THEN DISCH_TAC THEN
1944   REWRITE_TAC[COMPLEX_POW_NEG; GSYM NOT_EVEN] THEN ASM_CASES_TAC `EVEN k` THEN
1945   ASM_REWRITE_TAC[COMPLEX_ADD_RINV; COMPLEX_MUL_RZERO] THEN
1946   SIMPLE_COMPLEX_ARITH_TAC);;
1947
1948 let TAYLOR_CCOS = prove
1949  (`!n z. norm(ccos z -
1950               vsum(0..n) (\k. --Cx(&1) pow k *
1951                               z pow (2 * k) / Cx(&(FACT(2 * k)))))
1952          <= exp(abs(Im z)) * norm(z) pow (2 * n + 2) / &(FACT(2 * n + 1))`,
1953   REPEAT STRIP_TAC THEN
1954   MP_TAC(ISPECL [`2 * n + 1`; `z:complex`] TAYLOR_CCOS_RAW) THEN
1955   SIMP_TAC[VSUM_PAIR_0; EVEN_ADD; EVEN_MULT; ARITH_EVEN;
1956            LE_0; EVEN; COMPLEX_ADD_LID; COMPLEX_ADD_RID] THEN
1957   SIMP_TAC[ARITH_RULE `(2 * n + 1) + 1 = 2 * n + 2`] THEN
1958   MATCH_MP_TAC(NORM_ARITH
1959    `s = t ==> norm(x - s) <= e ==> norm(x - t) <= e`) THEN
1960   MATCH_MP_TAC VSUM_EQ THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
1961   REWRITE_TAC[COMPLEX_POW_MUL; complex_div; COMPLEX_MUL_ASSOC] THEN
1962   AP_THM_TAC THEN AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
1963   REWRITE_TAC[GSYM COMPLEX_POW_POW; COMPLEX_POW_II_2]);;
1964
1965 (* ------------------------------------------------------------------------- *)
1966 (* The argument of a complex number, where 0 <= arg(z) < 2 pi                *)
1967 (* ------------------------------------------------------------------------- *)
1968
1969 let Arg_DEF = new_definition
1970  `Arg z = if z = Cx(&0) then &0
1971           else @t. &0 <= t /\ t < &2 * pi /\
1972                    z = Cx(norm(z)) * cexp(ii * Cx t)`;;
1973
1974 let ARG_0 = prove
1975  (`Arg(Cx(&0)) = &0`,
1976   REWRITE_TAC[Arg_DEF]);;
1977
1978 let ARG = prove
1979  (`!z. &0 <= Arg(z) /\ Arg(z) < &2 * pi /\
1980        z = Cx(norm z) * cexp(ii * Cx(Arg z))`,
1981   GEN_TAC THEN REWRITE_TAC[Arg_DEF] THEN
1982   COND_CASES_TAC THEN ASM_REWRITE_TAC[COMPLEX_NORM_0; COMPLEX_MUL_LZERO] THEN
1983   SIMP_TAC[REAL_LE_REFL; REAL_LT_MUL; PI_POS; REAL_ARITH `&0 < &2`] THEN
1984   CONV_TAC SELECT_CONV THEN
1985   MP_TAC(SPECL [`Re(z) / norm z`; `Im(z) / norm z`]
1986         SINCOS_TOTAL_2PI) THEN
1987   ASM_SIMP_TAC[COMPLEX_SQNORM; COMPLEX_NORM_ZERO; REAL_FIELD
1988     `~(z = &0) /\ x pow 2 + y pow 2 = z pow 2
1989       ==> (x / z) pow 2 + (y / z) pow 2 = &1`] THEN
1990   MATCH_MP_TAC MONO_EXISTS THEN
1991   ASM_SIMP_TAC[COMPLEX_NORM_ZERO; REAL_FIELD
1992    `~(z = &0) ==> (x / z = y <=> x = z * y)`] THEN
1993   REWRITE_TAC[COMPLEX_EQ; RE_MUL_CX; IM_MUL_CX; CEXP_EULER; RE_ADD; IM_ADD;
1994         RE_MUL_II; IM_MUL_II; GSYM CX_SIN; GSYM CX_COS; RE_CX; IM_CX] THEN
1995   REAL_ARITH_TAC);;
1996
1997 let COMPLEX_NORM_EQ_1_CEXP = prove
1998  (`!z. norm z = &1 <=> (?t. z = cexp(ii * Cx t))`,
1999   GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN
2000   ASM_REWRITE_TAC [NORM_CEXP; RE_MUL_II; IM_CX; REAL_NEG_0; REAL_EXP_0] THEN
2001   MP_TAC (SPEC `z:complex` ARG) THEN ASM_REWRITE_TAC [COMPLEX_MUL_LID] THEN
2002   MESON_TAC[]);;
2003
2004 let ARG_UNIQUE = prove
2005  (`!a r z. &0 < r /\ Cx r * cexp(ii * Cx a) = z /\ &0 <= a /\ a < &2 * pi
2006            ==> Arg z = a`,
2007   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM CX_INJ] THEN
2008   MATCH_MP_TAC(COMPLEX_RING `ii * x = ii * y ==> x = y`) THEN
2009   MATCH_MP_TAC COMPLEX_EQ_CEXP THEN CONJ_TAC THENL
2010    [REWRITE_TAC[IM_MUL_II; RE_CX] THEN
2011     MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x < p /\ &0 <= y /\ y < p
2012                              ==> abs(x - y) < p`) THEN
2013     ASM_SIMP_TAC[ARG];
2014     MATCH_MP_TAC(COMPLEX_RING
2015      `!a b. Cx a = Cx b /\ ~(Cx b = Cx(&0)) /\
2016             Cx a * w = Cx b * z ==> w = z`) THEN
2017     MAP_EVERY EXISTS_TAC [`norm(z:complex)`; `r:real`] THEN
2018     ASM_REWRITE_TAC[GSYM ARG] THEN ASM_SIMP_TAC[CX_INJ; REAL_LT_IMP_NZ] THEN
2019     EXPAND_TAC "z" THEN
2020     REWRITE_TAC[NORM_CEXP_II; COMPLEX_NORM_MUL; COMPLEX_NORM_CX] THEN
2021     ASM_REAL_ARITH_TAC]);;
2022
2023 let ARG_MUL_CX = prove
2024  (`!r z. &0 < r ==> Arg(Cx r * z) = Arg(z)`,
2025   REPEAT STRIP_TAC THEN
2026   ASM_CASES_TAC `z = Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_MUL_RZERO] THEN
2027   MATCH_MP_TAC ARG_UNIQUE THEN EXISTS_TAC `r * norm(z:complex)` THEN
2028   ASM_REWRITE_TAC[CX_MUL; GSYM COMPLEX_MUL_ASSOC; GSYM ARG] THEN
2029   ASM_SIMP_TAC[REAL_LT_MUL; COMPLEX_NORM_NZ]);;
2030
2031 let ARG_DIV_CX = prove
2032  (`!r z. &0 < r ==> Arg(z / Cx r) = Arg(z)`,
2033   REWRITE_TAC[ONCE_REWRITE_RULE[COMPLEX_MUL_SYM] complex_div] THEN
2034   SIMP_TAC[GSYM CX_INV; ARG_MUL_CX; REAL_LT_INV_EQ]);;
2035
2036 let ARG_LT_NZ = prove
2037  (`!z. &0 < Arg z <=> ~(Arg z = &0)`,
2038   MP_TAC ARG THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);;
2039
2040 let ARG_LE_PI = prove
2041  (`!z. Arg z <= pi <=> &0 <= Im z`,
2042   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THENL
2043    [ASM_REWRITE_TAC[Arg_DEF; IM_CX; REAL_LE_REFL; PI_POS_LE]; ALL_TAC] THEN
2044   GEN_REWRITE_TAC (funpow 3 RAND_CONV) [ARG] THEN
2045   ASM_SIMP_TAC[IM_MUL_CX; CEXP_EULER; REAL_LE_MUL_EQ; COMPLEX_NORM_NZ] THEN
2046   REWRITE_TAC[IM_ADD; GSYM CX_SIN; GSYM CX_COS; IM_CX; IM_MUL_II; RE_CX] THEN
2047   REWRITE_TAC[REAL_ADD_LID] THEN EQ_TAC THEN SIMP_TAC[ARG; SIN_POS_PI_LE] THEN
2048   ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
2049   SUBGOAL_THEN `&0 < sin(&2 * pi - Arg z)` MP_TAC THENL
2050    [MATCH_MP_TAC SIN_POS_PI THEN MP_TAC(SPEC `z:complex` ARG) THEN
2051     ASM_REAL_ARITH_TAC;
2052     REWRITE_TAC[SIN_SUB; SIN_NPI; COS_NPI] THEN REAL_ARITH_TAC]);;
2053
2054 let ARG_LT_PI = prove
2055  (`!z. &0 < Arg z /\ Arg z < pi <=> &0 < Im z`,
2056   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THENL
2057    [ASM_REWRITE_TAC[Arg_DEF; IM_CX; REAL_LT_REFL; PI_POS_LE]; ALL_TAC] THEN
2058   GEN_REWRITE_TAC (funpow 3 RAND_CONV) [ARG] THEN
2059   ASM_SIMP_TAC[IM_MUL_CX; CEXP_EULER; REAL_LT_MUL_EQ; COMPLEX_NORM_NZ] THEN
2060   REWRITE_TAC[IM_ADD; GSYM CX_SIN; GSYM CX_COS; IM_CX; IM_MUL_II; RE_CX] THEN
2061   REWRITE_TAC[REAL_ADD_LID] THEN EQ_TAC THEN SIMP_TAC[SIN_POS_PI] THEN
2062   ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
2063   ASM_CASES_TAC `Arg z = &0` THEN
2064   ASM_REWRITE_TAC[SIN_0; REAL_LT_REFL] THEN
2065   ASM_SIMP_TAC[ARG; REAL_ARITH `~(x = &0) ==> (&0 < x <=> &0 <= x)`] THEN
2066   DISCH_TAC THEN
2067   SUBGOAL_THEN `&0 <= sin(&2 * pi - Arg z)` MP_TAC THENL
2068    [MATCH_MP_TAC SIN_POS_PI_LE THEN MP_TAC(SPEC `z:complex` ARG) THEN
2069     ASM_REAL_ARITH_TAC;
2070     REWRITE_TAC[SIN_SUB; SIN_NPI; COS_NPI] THEN REAL_ARITH_TAC]);;
2071
2072 let ARG_EQ_0 = prove
2073  (`!z. Arg z = &0 <=> real z /\ &0 <= Re z`,
2074   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THENL
2075    [ASM_REWRITE_TAC[REAL_CX; RE_CX; Arg_DEF; REAL_LE_REFL]; ALL_TAC] THEN
2076   CONV_TAC(RAND_CONV(SUBS_CONV[last(CONJUNCTS(SPEC `z:complex` ARG))])) THEN
2077   ASM_SIMP_TAC[RE_MUL_CX; REAL_MUL_CX; REAL_LE_MUL_EQ; COMPLEX_NORM_NZ] THEN
2078   ASM_REWRITE_TAC[COMPLEX_NORM_ZERO; CEXP_EULER] THEN
2079   REWRITE_TAC[real; RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II;
2080               GSYM CX_SIN; GSYM CX_COS; RE_CX; IM_CX] THEN
2081   REWRITE_TAC[REAL_ADD_RID; REAL_ADD_LID; REAL_NEG_0] THEN
2082   EQ_TAC THEN SIMP_TAC[SIN_0; COS_0; REAL_POS] THEN
2083   ASM_CASES_TAC `Arg z = pi` THENL
2084    [ASM_REWRITE_TAC[COS_PI] THEN REAL_ARITH_TAC; ALL_TAC] THEN
2085   MP_TAC(SPEC `z:complex` ARG) THEN REWRITE_TAC[CONJ_ASSOC] THEN
2086   DISCH_THEN(MP_TAC o CONJUNCT1) THEN DISCH_THEN(STRIP_ASSUME_TAC o MATCH_MP
2087    (REAL_ARITH `&0 <= x /\ x < &2 * pi
2088                 ==> --pi < x /\ x < pi \/ --pi < x - pi /\ x - pi < pi`)) THEN
2089   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[SIN_EQ_0_PI] THEN
2090   UNDISCH_TAC `~(Arg z = pi)` THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
2091   DISCH_TAC THEN REWRITE_TAC[REAL_ARITH `x = pi <=> x - pi = &0`] THEN
2092   MATCH_MP_TAC SIN_EQ_0_PI THEN ASM_REWRITE_TAC[SIN_SUB; SIN_PI] THEN
2093   REAL_ARITH_TAC);;
2094
2095 let ARG_NUM = prove
2096  (`!n. Arg(Cx(&n)) = &0`,
2097   REWRITE_TAC[ARG_EQ_0; REAL_CX; RE_CX; REAL_POS]);;
2098
2099 let ARG_EQ_PI = prove
2100  (`!z. Arg z = pi <=> real z /\ Re z < &0`,
2101   SIMP_TAC[ARG; PI_POS; REAL_ARITH
2102     `&0 < pi /\ &0 <= z
2103      ==> (z = pi <=> z <= pi /\ ~(z = &0) /\ ~(&0 < z /\ z < pi))`] THEN
2104   REWRITE_TAC[ARG_EQ_0; ARG; ARG_LT_PI; ARG_LE_PI; real] THEN
2105   REAL_ARITH_TAC);;
2106
2107 let ARG_EQ_0_PI = prove
2108  (`!z. Arg z = &0 \/ Arg z = pi <=> real z`,
2109   REWRITE_TAC[ARG_EQ_0; ARG_EQ_PI; real] THEN REAL_ARITH_TAC);;
2110
2111 let ARG_INV = prove
2112  (`!z. ~(real z /\ &0 <= Re z) ==> Arg(inv z) = &2 * pi - Arg z`,
2113   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN
2114   ASM_REWRITE_TAC[REAL_CX; RE_CX; REAL_LE_REFL] THEN
2115   REWRITE_TAC[real] THEN STRIP_TAC THEN MATCH_MP_TAC ARG_UNIQUE THEN
2116   EXISTS_TAC `inv(norm(z:complex))` THEN
2117   ASM_SIMP_TAC[COMPLEX_NORM_NZ; REAL_LT_INV_EQ] THEN
2118   REWRITE_TAC[CX_SUB; CX_MUL; COMPLEX_SUB_LDISTRIB; CEXP_SUB] THEN
2119   SUBST1_TAC(SPEC `Cx(&2) * Cx pi` CEXP_EULER) THEN
2120   REWRITE_TAC[GSYM CX_MUL; GSYM CX_SIN; GSYM CX_COS] THEN
2121   REWRITE_TAC[SIN_NPI; COS_NPI; COMPLEX_MUL_RZERO; COMPLEX_ADD_RID] THEN
2122   CONV_TAC REAL_RAT_REDUCE_CONV THEN
2123   REWRITE_TAC[complex_div; COMPLEX_MUL_LID; CX_INV; GSYM COMPLEX_INV_MUL] THEN
2124   REWRITE_TAC[GSYM ARG] THEN
2125   MP_TAC(SPEC `z:complex` ARG_EQ_0) THEN ASM_REWRITE_TAC[real] THEN
2126   MP_TAC(SPEC `z:complex` ARG) THEN REAL_ARITH_TAC);;
2127
2128 let ARG_EQ = prove
2129  (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0))
2130          ==> (Arg w = Arg z <=> ?x. &0 < x /\ w = Cx(x) * z)`,
2131   REPEAT STRIP_TAC THEN EQ_TAC THENL
2132    [ALL_TAC; STRIP_TAC THEN ASM_SIMP_TAC[ARG_MUL_CX]] THEN
2133   DISCH_TAC THEN
2134   MAP_EVERY (MP_TAC o CONJUNCT2 o CONJUNCT2 o C SPEC ARG)
2135    [`z:complex`; `w:complex`] THEN
2136   ASM_REWRITE_TAC[IMP_IMP] THEN
2137   DISCH_THEN(fun th -> CONV_TAC(SUBS_CONV(CONJUNCTS th))) THEN
2138   EXISTS_TAC `norm(w:complex) / norm(z:complex)` THEN
2139   ASM_SIMP_TAC[REAL_LT_DIV; COMPLEX_NORM_NZ; CX_DIV] THEN
2140   REWRITE_TAC[COMPLEX_MUL_ASSOC] THEN AP_THM_TAC THEN AP_TERM_TAC THEN
2141   ASM_SIMP_TAC[COMPLEX_DIV_RMUL; COMPLEX_NORM_ZERO; CX_INJ]);;
2142
2143 let ARG_INV_EQ_0 = prove
2144  (`!z. Arg(inv z) = &0 <=> Arg z = &0`,
2145   GEN_TAC THEN REWRITE_TAC[ARG_EQ_0; REAL_INV_EQ] THEN
2146   MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> (a /\ b <=> a /\ c)`) THEN
2147   REWRITE_TAC[real] THEN DISCH_TAC THEN ASM_REWRITE_TAC[complex_inv; RE] THEN
2148   CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[REAL_ADD_RID] THEN
2149   ASM_CASES_TAC `Re z = &0` THEN ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO] THEN
2150   ASM_SIMP_TAC[REAL_FIELD `~(x = &0) ==> x * inv(x pow 2) = inv x`] THEN
2151   REWRITE_TAC[REAL_LE_INV_EQ]);;
2152
2153 let ARG_LE_DIV_SUM = prove
2154  (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) /\ Arg(w) <= Arg(z)
2155          ==> Arg(z) = Arg(w) + Arg(z / w)`,
2156   REPEAT STRIP_TAC THEN
2157   ONCE_REWRITE_TAC[REAL_ARITH `a:real = b + c <=> c = a - b`] THEN
2158   MATCH_MP_TAC ARG_UNIQUE THEN EXISTS_TAC `norm(z / w)`THEN
2159   ASM_SIMP_TAC[ARG; REAL_ARITH
2160    `&0 <= a /\ a < &2 * pi /\ &0 <= b /\ b <= a ==> a - b < &2 * pi`] THEN
2161   ASM_REWRITE_TAC[REAL_SUB_LE] THEN
2162   ASM_SIMP_TAC[COMPLEX_NORM_DIV; CX_DIV] THEN
2163   ASM_SIMP_TAC[REAL_LT_DIV; COMPLEX_NORM_NZ] THEN
2164   REWRITE_TAC[COMPLEX_SUB_LDISTRIB; CEXP_SUB; CX_SUB] THEN
2165   REWRITE_TAC[complex_div] THEN
2166   ONCE_REWRITE_TAC[COMPLEX_RING
2167    `(a * b) * (c * d):complex = (a * c) * (b * d)`] THEN
2168   REWRITE_TAC[GSYM COMPLEX_INV_MUL] THEN ASM_SIMP_TAC[GSYM ARG]);;
2169
2170 let ARG_LE_DIV_SUM_EQ = prove
2171  (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0))
2172          ==> (Arg(w) <= Arg(z) <=> Arg(z) = Arg(w) + Arg(z / w))`,
2173   MESON_TAC[ARG_LE_DIV_SUM; REAL_LE_ADDR; ARG]);;
2174
2175 let REAL_SUB_ARG = prove
2176  (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0))
2177          ==> Arg w - Arg z = if Arg(z) <= Arg(w) then Arg(w / z)
2178                              else Arg(w / z) - &2 * pi`,
2179   REPEAT STRIP_TAC THEN COND_CASES_TAC THENL
2180    [MP_TAC(ISPECL [`z:complex`; `w:complex`] ARG_LE_DIV_SUM) THEN
2181     ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC;
2182     MP_TAC(ISPECL [`w:complex`; `z:complex`] ARG_LE_DIV_SUM) THEN
2183     ASM_REWRITE_TAC[] THEN
2184     ANTS_TAC THENL [ASM_REAL_ARITH_TAC; DISCH_THEN SUBST1_TAC] THEN
2185     REWRITE_TAC[REAL_ARITH `a - (a + b):real = --b`] THEN
2186     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM COMPLEX_INV_DIV] THEN
2187     MATCH_MP_TAC(REAL_ARITH `x = &2 * pi - y ==> --x = y - &2 * pi`) THEN
2188     MATCH_MP_TAC ARG_INV THEN REWRITE_TAC[GSYM ARG_EQ_0] THEN
2189     ONCE_REWRITE_TAC[GSYM COMPLEX_INV_DIV] THEN
2190     REWRITE_TAC[ARG_INV_EQ_0] THEN
2191     MP_TAC(ISPECL [`w:complex`; `z:complex`] ARG_LE_DIV_SUM) THEN
2192     ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]);;
2193
2194 let REAL_ADD_ARG = prove
2195  (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0))
2196          ==> Arg(w) + Arg(z) =
2197              if Arg w + Arg z < &2 * pi
2198              then Arg(w * z)
2199              else Arg(w * z) + &2 * pi`,
2200   REPEAT STRIP_TAC THEN
2201   MP_TAC(SPECL [`w * z:complex`; `z:complex`] REAL_SUB_ARG) THEN
2202   MP_TAC(SPECL [`z:complex`; `w * z:complex`] ARG_LE_DIV_SUM_EQ) THEN
2203   ASM_SIMP_TAC[COMPLEX_ENTIRE; COMPLEX_FIELD
2204    `~(z = Cx(&0)) ==> (w * z) / z = w`] THEN
2205   ASM_CASES_TAC `Arg (w * z) = Arg z + Arg w` THEN ASM_REWRITE_TAC[] THENL
2206    [ASM_MESON_TAC[ARG; REAL_ADD_SYM];
2207     SIMP_TAC[REAL_ARITH `wz - z = w - &2 * pi <=> w + z = wz + &2 * pi`] THEN
2208     REWRITE_TAC[REAL_ARITH `w + p < p <=> ~(&0 <= w)`; ARG]]);;
2209
2210 let ARG_MUL = prove
2211  (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0))
2212          ==> Arg(w * z) = if Arg w + Arg z < &2 * pi
2213                           then Arg w + Arg z
2214                           else (Arg w + Arg z) - &2 * pi`,
2215   REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP REAL_ADD_ARG) THEN
2216   REAL_ARITH_TAC);;
2217
2218 let ARG_CNJ = prove
2219  (`!z. Arg(cnj z) = if real z /\ &0 <= Re z then Arg z else &2 * pi - Arg z`,
2220   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN
2221   ASM_REWRITE_TAC[CNJ_CX; ARG_0; REAL_CX; RE_CX; REAL_LE_REFL] THEN
2222   COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_IMP_CNJ] THEN
2223   MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `Arg(inv z)` THEN CONJ_TAC THENL
2224    [REWRITE_TAC[COMPLEX_INV_CNJ] THEN
2225     ASM_SIMP_TAC[GSYM CX_POW; ARG_DIV_CX; REAL_POW_LT; COMPLEX_NORM_NZ];
2226     ASM_SIMP_TAC[ARG_INV]]);;
2227
2228 let ARG_REAL = prove
2229  (`!z. real z ==> Arg z = if &0 <= Re z then &0 else pi`,
2230   REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
2231   ASM_REWRITE_TAC[ARG_EQ_PI; ARG_EQ_0] THEN ASM_REAL_ARITH_TAC);;
2232
2233 let ARG_CEXP = prove
2234  (`!z. &0 <= Im z /\ Im z < &2 * pi ==> Arg(cexp(z)) = Im z`,
2235   REPEAT STRIP_TAC THEN MATCH_MP_TAC ARG_UNIQUE THEN
2236   EXISTS_TAC `exp(Re z)` THEN
2237   ASM_REWRITE_TAC[CX_EXP; GSYM CEXP_ADD; REAL_EXP_POS_LT] THEN
2238   REWRITE_TAC[GSYM COMPLEX_EXPAND]);;
2239
2240 (* ------------------------------------------------------------------------- *)
2241 (* Properties of 2-D rotations, and their interpretation using cexp.         *)
2242 (* ------------------------------------------------------------------------- *)
2243
2244 let rotate2d = new_definition
2245  `(rotate2d:real->real^2->real^2) t x =
2246         vector[x$1 * cos(t) - x$2 * sin(t);
2247                x$1 * sin(t) + x$2 * cos(t)]`;;
2248
2249 let LINEAR_ROTATE2D = prove
2250  (`!t. linear(rotate2d t)`,
2251   SIMP_TAC[linear; CART_EQ; DIMINDEX_2; FORALL_2; VECTOR_2;
2252            VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; rotate2d] THEN
2253   REAL_ARITH_TAC);;
2254
2255 let ROTATE2D_ADD_VECTORS = prove
2256  (`!t w z. rotate2d t (w + z) = rotate2d t w + rotate2d t z`,
2257   SIMP_TAC[LINEAR_ADD; LINEAR_ROTATE2D]);;
2258
2259 let ROTATE2D_SUB = prove
2260  (`!t w z. rotate2d t (w - z) = rotate2d t w - rotate2d t z`,
2261   SIMP_TAC[LINEAR_SUB; LINEAR_ROTATE2D]);;
2262
2263 let NORM_ROTATE2D = prove
2264  (`!t z. norm(rotate2d t z) = norm z`,
2265   REWRITE_TAC[NORM_EQ; rotate2d; DIMINDEX_2; DOT_2; VECTOR_2] THEN
2266   REPEAT GEN_TAC THEN MP_TAC(ISPEC `t:real` SIN_CIRCLE) THEN
2267   CONV_TAC REAL_RING);;
2268
2269 let ROTATE2D_0 = prove
2270  (`!t. rotate2d t (Cx(&0)) = Cx(&0)`,
2271   REWRITE_TAC[GSYM COMPLEX_NORM_ZERO; NORM_ROTATE2D; COMPLEX_NORM_0]);;
2272
2273 let ROTATE2D_EQ_0 = prove
2274  (`!t z. rotate2d t z = Cx(&0) <=> z = Cx(&0)`,
2275   REWRITE_TAC[GSYM COMPLEX_NORM_ZERO; NORM_ROTATE2D]);;
2276
2277 let ROTATE2D_ZERO = prove
2278  (`!z. rotate2d (&0) z = z`,
2279   REWRITE_TAC[rotate2d; SIN_0; COS_0] THEN
2280   REWRITE_TAC[CART_EQ; DIMINDEX_2; FORALL_2; VECTOR_2] THEN
2281   REAL_ARITH_TAC);;
2282
2283 let ORTHOGONAL_TRANSFORMATION_ROTATE2D = prove
2284  (`!t. orthogonal_transformation(rotate2d t)`,
2285   REWRITE_TAC[ORTHOGONAL_TRANSFORMATION; LINEAR_ROTATE2D; NORM_ROTATE2D]);;
2286
2287 let ROTATE2D_POLAR = prove
2288  (`!r t s. rotate2d t (vector[r * cos(s); r * sin(s)]) =
2289                         vector[r * cos(t + s); r * sin(t + s)]`,
2290   SIMP_TAC[rotate2d; DIMINDEX_2; VECTOR_2; CART_EQ; FORALL_2] THEN
2291   REWRITE_TAC[SIN_ADD; COS_ADD] THEN REAL_ARITH_TAC);;
2292
2293 let MATRIX_ROTATE2D = prove
2294  (`!t. matrix(rotate2d t) = vector[vector[cos t;--(sin t)];
2295                                    vector[sin t; cos t]]`,
2296   SIMP_TAC[MATRIX_EQ; MATRIX_WORKS; LINEAR_ROTATE2D] THEN
2297   SIMP_TAC[matrix_vector_mul; rotate2d; CART_EQ; DIMINDEX_2; FORALL_2;
2298            LAMBDA_BETA; VECTOR_2; ARITH; SUM_2] THEN
2299   REAL_ARITH_TAC);;
2300
2301 let DET_MATRIX_ROTATE2D = prove
2302  (`!t. det(matrix(rotate2d t)) = &1`,
2303   GEN_TAC THEN REWRITE_TAC[MATRIX_ROTATE2D; DET_2; VECTOR_2] THEN
2304   MP_TAC(SPEC `t:real` SIN_CIRCLE) THEN REAL_ARITH_TAC);;
2305
2306 let ROTATION_ROTATE2D = prove
2307  (`!f. orthogonal_transformation f /\ det(matrix f) = &1
2308        ==> ?t. &0 <= t /\ t < &2 * pi /\ f = rotate2d t`,
2309   REWRITE_TAC[ORTHOGONAL_TRANSFORMATION_MATRIX] THEN
2310   REWRITE_TAC[matrix_mul; orthogonal_matrix; transp] THEN
2311   SIMP_TAC[DIMINDEX_2; SUM_2; FORALL_2; LAMBDA_BETA; ARITH;
2312            CART_EQ; mat; DET_2] THEN REPEAT STRIP_TAC THEN
2313   SUBGOAL_THEN `(matrix f)$1$1 pow 2 + (matrix f)$2$1 pow 2 = &1 /\
2314                 (matrix f)$1$2 = --((matrix f)$2$1) /\
2315                 (matrix f:real^2^2)$2$2 = (matrix f)$1$1`
2316   STRIP_ASSUME_TAC THENL
2317    [REPEAT(FIRST_X_ASSUM(MP_TAC o SYM)) THEN CONV_TAC REAL_RING;
2318     FIRST_X_ASSUM(MP_TAC o MATCH_MP SINCOS_TOTAL_2PI) THEN
2319     MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
2320     MATCH_MP_TAC LINEAR_EQ_MATRIX THEN
2321     ASM_REWRITE_TAC[LINEAR_ROTATE2D; MATRIX_ROTATE2D] THEN
2322     ASM_SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; VECTOR_2]]);;
2323
2324 let ROTATE2D_ADD = prove
2325  (`!s t x. rotate2d (s + t) x = rotate2d s (rotate2d t x)`,
2326   SIMP_TAC[CART_EQ; rotate2d; LAMBDA_BETA; DIMINDEX_2; ARITH;
2327            FORALL_2; VECTOR_2] THEN
2328   REWRITE_TAC[SIN_ADD; COS_ADD] THEN REAL_ARITH_TAC);;
2329
2330 let ROTATE2D_COMPLEX = prove
2331  (`!t z. rotate2d t z = cexp(ii * Cx t) * z`,
2332   REPEAT GEN_TAC THEN GEN_REWRITE_TAC RAND_CONV [complex_mul] THEN
2333   REWRITE_TAC[CEXP_EULER; rotate2d; GSYM CX_SIN; GSYM CX_COS;
2334               RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II; IM_CX; RE_CX] THEN
2335   REWRITE_TAC[CART_EQ; FORALL_2; VECTOR_2; DIMINDEX_2] THEN
2336   REWRITE_TAC[GSYM RE_DEF; GSYM IM_DEF; RE; IM] THEN
2337   REAL_ARITH_TAC);;
2338
2339 let ROTATE2D_PI2 = prove
2340  (`!z. rotate2d (pi / &2) z = ii * z`,
2341   REWRITE_TAC[ROTATE2D_COMPLEX; CEXP_EULER; SIN_PI2; COS_PI2; GSYM CX_SIN;
2342               GSYM CX_COS] THEN
2343   CONV_TAC COMPLEX_RING);;
2344
2345 let ROTATE2D_PI = prove
2346  (`!z. rotate2d pi z = --z`,
2347   REWRITE_TAC[ROTATE2D_COMPLEX; CEXP_EULER; SIN_PI; COS_PI; GSYM CX_SIN;
2348               GSYM CX_COS] THEN
2349   CONV_TAC COMPLEX_RING);;
2350
2351 let ROTATE2D_NPI = prove
2352  (`!n z. rotate2d (&n * pi) z = --Cx(&1) pow n * z`,
2353   REWRITE_TAC[ROTATE2D_COMPLEX; CEXP_EULER; SIN_NPI; COS_NPI; GSYM CX_SIN;
2354               GSYM CX_COS; CX_NEG; CX_POW] THEN
2355   CONV_TAC COMPLEX_RING);;
2356
2357 let ROTATE2D_2PI = prove
2358  (`!z. rotate2d (&2 * pi) z = z`,
2359   REWRITE_TAC[ROTATE2D_NPI] THEN CONV_TAC COMPLEX_RING);;
2360
2361 let ARG_ROTATE2D = prove
2362  (`!t z. ~(z = Cx(&0)) /\ &0 <= t + Arg z /\ t + Arg z < &2 * pi
2363          ==> Arg(rotate2d t z) = t + Arg z`,
2364   REPEAT STRIP_TAC THEN MATCH_MP_TAC ARG_UNIQUE THEN
2365   EXISTS_TAC `norm(z:complex)` THEN
2366   ASM_SIMP_TAC[ARG; ROTATE2D_COMPLEX; REAL_LE_ADD; COMPLEX_NORM_NZ] THEN
2367   GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [ARG] THEN
2368   REWRITE_TAC[CX_ADD; COMPLEX_ADD_LDISTRIB; CEXP_ADD] THEN
2369   REWRITE_TAC[COMPLEX_MUL_AC]);;
2370
2371 let ARG_ROTATE2D_UNIQUE = prove
2372  (`!t a z. ~(z = Cx(&0)) /\ Arg(rotate2d t z) = a
2373            ==> ?n. integer n /\ t = &2 * n * pi + (a - Arg z)`,
2374   REPEAT STRIP_TAC THEN
2375   MP_TAC(last(CONJUNCTS(ISPEC `rotate2d t z` ARG))) THEN
2376   ASM_REWRITE_TAC[NORM_ROTATE2D] THEN
2377   REWRITE_TAC[ROTATE2D_COMPLEX] THEN
2378   GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o RAND_CONV) [ARG] THEN
2379   ASM_REWRITE_TAC[COMPLEX_RING `a * z * b = z * c <=> z = Cx(&0) \/ a * b = c`;
2380                   CX_INJ; COMPLEX_NORM_ZERO; GSYM CEXP_ADD; CEXP_EQ] THEN
2381   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN MATCH_MP_TAC MONO_AND THEN
2382   REWRITE_TAC[GSYM CX_ADD; GSYM CX_SUB; CX_INJ; COMPLEX_RING
2383    `ii * t + ii * z = ii * a + n * ii <=> t = n + (a - z)`]);;
2384
2385 let ARG_ROTATE2D_UNIQUE_2PI = prove
2386  (`!s t z. ~(z = Cx(&0)) /\
2387            &0 <= s /\ s < &2 * pi /\ &0 <= t /\ t < &2 * pi /\
2388            Arg(rotate2d s z) = Arg(rotate2d t z)
2389            ==> s = t`,
2390   REPEAT STRIP_TAC THEN ABBREV_TAC `a = Arg(rotate2d t z)` THEN
2391   MP_TAC(ISPECL [`s:real`; `a:real`; `z:complex`] ARG_ROTATE2D_UNIQUE) THEN
2392   MP_TAC(ISPECL [`t:real`; `a:real`; `z:complex`] ARG_ROTATE2D_UNIQUE) THEN
2393   ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC SIN_COS_INJ THEN
2394   REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL
2395    [ASM_REWRITE_TAC[SIN_COS_EQ; REAL_RING
2396      `x + az:real = (y + az) + z <=> x - y = z`] THEN
2397     REWRITE_TAC[GSYM REAL_SUB_LDISTRIB; GSYM REAL_SUB_RDISTRIB] THEN
2398     ASM_MESON_TAC[INTEGER_CLOSED];
2399     ASM_REAL_ARITH_TAC]);;
2400
2401 let COMPLEX_DIV_ROTATION = prove
2402  (`!f w z. orthogonal_transformation f /\ det(matrix f) = &1
2403            ==> f w / f z = w / z`,
2404   REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP ROTATION_ROTATE2D) THEN
2405   DISCH_THEN(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THEN
2406   ASM_REWRITE_TAC[ROTATE2D_COMPLEX] THEN
2407   SIMP_TAC[complex_div; COMPLEX_INV_MUL; CEXP_NZ; COMPLEX_FIELD
2408    `~(a = Cx(&0)) ==> (a * w) * (inv a * z) = w * z`]);;
2409
2410 let th = prove
2411  (`!f w z. linear f /\ (!x. norm(f x) = norm x) /\
2412            (2 <= dimindex(:2) ==> det(matrix f) = &1)
2413            ==> f w / f z = w / z`,
2414   REWRITE_TAC[CONJ_ASSOC; GSYM ORTHOGONAL_TRANSFORMATION;
2415               DIMINDEX_2; LE_REFL; COMPLEX_DIV_ROTATION]) in
2416 add_linear_invariants [th];;
2417
2418 let th = prove
2419  (`!f t z. linear f /\ (!x. norm(f x) = norm x) /\
2420            (2 <= dimindex(:2) ==> det(matrix f) = &1)
2421            ==> rotate2d t (f z) = f(rotate2d t z)`,
2422   REWRITE_TAC[DIMINDEX_2; LE_REFL] THEN REPEAT STRIP_TAC THEN
2423   MP_TAC(SPEC `f:complex->complex` ROTATION_ROTATE2D) THEN
2424   ASM_REWRITE_TAC[ORTHOGONAL_TRANSFORMATION] THEN
2425   DISCH_THEN(X_CHOOSE_THEN `s:real` STRIP_ASSUME_TAC) THEN
2426   ASM_REWRITE_TAC[GSYM ROTATE2D_ADD] THEN REWRITE_TAC[REAL_ADD_SYM]) in
2427 add_linear_invariants [th];;
2428
2429 let ROTATION_ROTATE2D_EXISTS_GEN = prove
2430  (`!x y. ?t. &0 <= t /\ t < &2 * pi /\ norm(y) % rotate2d t x = norm(x) % y`,
2431   REPEAT STRIP_TAC THEN
2432   MP_TAC(ISPECL [`norm(y:real^2) % x:real^2`; `norm(x:real^2) % y:real^2`]
2433                ROTATION_EXISTS) THEN
2434   ASM_REWRITE_TAC[DIMINDEX_2; NORM_MUL; ARITH; REAL_ABS_NORM;
2435                   EQT_INTRO(SPEC_ALL REAL_MUL_SYM); CONJ_ASSOC] THEN
2436   DISCH_THEN(X_CHOOSE_THEN `f:real^2->real^2` (CONJUNCTS_THEN ASSUME_TAC)) THEN
2437   FIRST_ASSUM(MP_TAC o MATCH_MP ROTATION_ROTATE2D) THEN
2438   MATCH_MP_TAC MONO_EXISTS THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
2439   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[LINEAR_CMUL; LINEAR_ROTATE2D]);;
2440
2441 let ROTATION_ROTATE2D_EXISTS = prove
2442  (`!x y. norm x = norm y ==> ?t. &0 <= t /\ t < &2 * pi /\ rotate2d t x = y`,
2443   REPEAT GEN_TAC THEN
2444   ASM_CASES_TAC `norm(y:complex) = &0` THENL
2445    [ASM_REWRITE_TAC[] THEN DISCH_TAC THEN EXISTS_TAC `&0` THEN
2446     SIMP_TAC[REAL_LT_MUL; PI_POS; REAL_OF_NUM_LT; ARITH; REAL_LE_REFL] THEN
2447     ASM_MESON_TAC[COMPLEX_NORM_ZERO; ROTATE2D_0];
2448     DISCH_TAC THEN
2449     MP_TAC(ISPECL [`x:complex`; `y:complex`] ROTATION_ROTATE2D_EXISTS_GEN) THEN
2450     ASM_REWRITE_TAC[VECTOR_MUL_LCANCEL]]);;
2451
2452 let ROTATION_ROTATE2D_EXISTS_ORTHOGONAL = prove
2453  (`!e1 e2. norm(e1) = &1 /\ norm(e2) = &1 /\ orthogonal e1 e2
2454            ==> e1 = rotate2d (pi / &2) e2 \/ e2 = rotate2d (pi / &2) e1`,
2455   REWRITE_TAC[NORM_EQ_1; orthogonal] THEN
2456   SIMP_TAC[DOT_2; CART_EQ; FORALL_2; DIMINDEX_2; rotate2d; VECTOR_2] THEN
2457   REWRITE_TAC[COS_PI2; SIN_PI2; REAL_MUL_RZERO; REAL_ADD_RID;
2458               REAL_SUB_LZERO; REAL_SUB_RZERO; REAL_MUL_RID] THEN
2459   CONV_TAC REAL_RING);;
2460
2461 let ROTATION_ROTATE2D_EXISTS_ORTHOGONAL_ORIENTED = prove
2462  (`!e1 e2. norm(e1) = &1 /\ norm(e2) = &1 /\ orthogonal e1 e2 /\
2463            &0 < e1$1 * e2$2 - e1$2 * e2$1
2464            ==> e2 = rotate2d (pi / &2) e1`,
2465   REPEAT GEN_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN
2466   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
2467   REWRITE_TAC[GSYM CONJ_ASSOC] THEN DISCH_TAC THEN
2468   FIRST_ASSUM(DISJ_CASES_THEN SUBST_ALL_TAC o MATCH_MP
2469     ROTATION_ROTATE2D_EXISTS_ORTHOGONAL) THEN
2470   REWRITE_TAC[] THEN
2471   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_NOT_LE]) THEN
2472   ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_THEN(K ALL_TAC) THEN
2473   SIMP_TAC[DOT_2; CART_EQ; FORALL_2; DIMINDEX_2; rotate2d; VECTOR_2] THEN
2474   REWRITE_TAC[COS_PI2; SIN_PI2; REAL_MUL_RZERO; REAL_ADD_RID;
2475               REAL_SUB_LZERO; REAL_SUB_RZERO; REAL_MUL_RID] THEN
2476   REWRITE_TAC[REAL_ARITH `--x * x - y * y <= &0 <=> &0 <= x * x + y * y`] THEN
2477   MATCH_MP_TAC REAL_LE_ADD THEN REWRITE_TAC[REAL_LE_SQUARE]);;
2478
2479 let ROTATE2D_EQ = prove
2480  (`!t x y. rotate2d t x = rotate2d t y <=> x = y`,
2481   MESON_TAC[ORTHOGONAL_TRANSFORMATION_INJECTIVE;
2482             ORTHOGONAL_TRANSFORMATION_ROTATE2D]);;
2483
2484 let ROTATE2D_SUB_ARG = prove
2485  (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0))
2486          ==> rotate2d(Arg w - Arg z) = rotate2d(Arg(w / z))`,
2487   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[REAL_SUB_ARG] THEN
2488   COND_CASES_TAC THEN REWRITE_TAC[real_sub; ROTATE2D_ADD; FUN_EQ_THM] THEN
2489   GEN_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[ROTATE2D_COMPLEX] THEN
2490   REWRITE_TAC[EULER; RE_MUL_II; IM_MUL_II; RE_CX; IM_CX; COS_NEG; SIN_NEG] THEN
2491   REWRITE_TAC[SIN_NPI; COS_NPI; REAL_EXP_NEG; REAL_EXP_0; CX_NEG] THEN
2492   REWRITE_TAC[COMPLEX_NEG_0; COMPLEX_MUL_RZERO; COMPLEX_ADD_RID] THEN
2493   CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[COMPLEX_MUL_LID]);;
2494
2495 let ROTATION_MATRIX_ROTATE2D = prove
2496  (`!t. rotation_matrix(matrix(rotate2d t))`,
2497   SIMP_TAC[ROTATION_MATRIX_2; MATRIX_ROTATE2D; VECTOR_2] THEN
2498   MESON_TAC[SIN_CIRCLE; REAL_ADD_SYM]);;
2499
2500 let ROTATION_MATRIX_ROTATE2D_EQ = prove
2501  (`!A:real^2^2. rotation_matrix A <=> ?t. A = matrix(rotate2d t)`,
2502   GEN_TAC THEN EQ_TAC THEN
2503   SIMP_TAC[LEFT_IMP_EXISTS_THM; ROTATION_MATRIX_ROTATE2D] THEN
2504   REWRITE_TAC[ROTATION_MATRIX_2; MATRIX_ROTATE2D] THEN STRIP_TAC THEN
2505   FIRST_X_ASSUM(MP_TAC o MATCH_MP SINCOS_TOTAL_2PI) THEN
2506   MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN
2507   REWRITE_TAC[CART_EQ; DIMINDEX_2; FORALL_2; VECTOR_2] THEN
2508   ASM_REAL_ARITH_TAC);;
2509
2510 (* ------------------------------------------------------------------------- *)
2511 (* Homotopy staying within the set of orthogonal transformations             *)
2512 (* ------------------------------------------------------------------------- *)
2513
2514 let NULLHOMOTOPIC_ORTHOGONAL_TRANSFORMATION = prove
2515  (`!f:real^N->real^N.
2516        orthogonal_transformation f /\ det(matrix f) = &1
2517        ==> homotopic_with orthogonal_transformation ((:real^N),(:real^N)) f I`,
2518   let lemma0 = prove
2519    (`!a x:real^N.
2520           2 <= dimindex(:N) /\ a IN span {basis 1,basis 2}
2521           ==> reflect_along (vector[a$1; a$2]:real^2) (lambda i. x$i) =
2522               (lambda i. reflect_along a x$i)`,
2523     REPEAT STRIP_TAC THEN
2524     SIMP_TAC[CART_EQ; LAMBDA_BETA; reflect_along; VECTOR_SUB_COMPONENT;
2525              VECTOR_MUL_COMPONENT; DIMINDEX_2; FORALL_2; VECTOR_2; ARITH] THEN
2526     CONJ_TAC THEN AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
2527     AP_TERM_TAC THEN BINOP_TAC THEN REWRITE_TAC[dot] THEN
2528     CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_EQ_SUPERSET THEN
2529     ASM_SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; FORALL_2; DIMINDEX_2; LAMBDA_BETA;
2530                  ARITH; VECTOR_2; SUBSET_NUMSEG] THEN
2531     REWRITE_TAC[ARITH_RULE
2532      `(1 <= i /\ i <= n) /\ ~(1 <= i /\ i <= 2) <=>
2533       1 <= i /\ 3 <= i /\ i <= n`] THEN
2534     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [SPAN_2]) THEN
2535     REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN
2536     STRIP_TAC THEN
2537     ASM_REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
2538     SIMP_TAC[BASIS_COMPONENT] THEN
2539     REPEAT STRIP_TAC THEN
2540     REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_MUL_RZERO]) THEN
2541     ASM_ARITH_TAC) in
2542   let lemma1 = prove
2543    (`!a b:real^2 r.
2544           ~(a = vec 0) /\ ~(b = vec 0)
2545           ==> homotopic_with orthogonal_transformation ((:real^2),(:real^2))
2546                              (reflect_along a o reflect_along b) I`,
2547     REPEAT STRIP_TAC THEN
2548     MP_TAC(SPEC `reflect_along (a:real^2) o reflect_along b`
2549           ROTATION_ROTATE2D) THEN
2550     ANTS_TAC THENL
2551      [REPEAT(FIRST_X_ASSUM(MP_TAC o
2552         MATCH_MP ROTOINVERSION_MATRIX_REFLECT_ALONG)) THEN
2553       REWRITE_TAC[rotoinversion_matrix] THEN
2554       SIMP_TAC[ORTHOGONAL_MATRIX_MATRIX;
2555                ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG;
2556                ORTHOGONAL_TRANSFORMATION_COMPOSE; MATRIX_COMPOSE;
2557                LINEAR_REFLECT_ALONG; DET_MUL] THEN
2558       CONV_TAC REAL_RAT_REDUCE_CONV;
2559       DISCH_THEN(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THEN
2560       ONCE_REWRITE_TAC[HOMOTOPIC_WITH_SYM] THEN
2561       ASM_REWRITE_TAC[homotopic_with] THEN
2562       EXISTS_TAC `\z. rotate2d (drop(fstcart z) * t) (sndcart z)` THEN
2563       SIMP_TAC[ORTHOGONAL_TRANSFORMATION_ROTATE2D; SNDCART_PASTECART;
2564                ETA_AX; FSTCART_PASTECART; DROP_VEC; I_THM; NORM_ROTATE2D;
2565                REAL_MUL_LZERO; REAL_MUL_LID; SUBSET; FORALL_IN_IMAGE; IN_UNIV;
2566                FORALL_IN_PCROSS; IN_SPHERE_0; ROTATE2D_ZERO] THEN
2567       REWRITE_TAC[ROTATE2D_COMPLEX] THEN
2568       MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN
2569       SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN
2570       GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
2571       MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
2572       REWRITE_TAC[CONTINUOUS_ON_CEXP; CX_MUL] THEN
2573       ONCE_REWRITE_TAC[COMPLEX_RING `ii * x * t = (ii * t) * x`] THEN
2574       MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_LMUL THEN
2575       MATCH_MP_TAC CONTINUOUS_ON_CX_DROP THEN
2576       SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART]]) in
2577   let lemma2 = prove
2578    (`!a b:real^N r.
2579           2 <= dimindex(:N) /\
2580           ~(a = vec 0) /\ ~(b = vec 0) /\
2581           {a,b} SUBSET span {basis 1,basis 2}
2582           ==> homotopic_with orthogonal_transformation ((:real^N),(:real^N))
2583                              (reflect_along a o reflect_along b) I`,
2584     REPEAT STRIP_TAC THEN
2585     SUBGOAL_THEN
2586       `homotopic_with orthogonal_transformation
2587         ((:real^N),(:real^N))
2588         ((\z. (lambda i. if i <= 2 then (fstcart z)$i
2589                          else (sndcart z)$i):real^N) o
2590          (\z. pastecart
2591                (((reflect_along (vector [(a:real^N)$1; a$2]) o
2592                  reflect_along (vector [(b:real^N)$1; b$2]))
2593                   :real^2->real^2)(fstcart z))
2594                (sndcart z)) o
2595          (\z:real^N. pastecart ((lambda i. z$i) :real^2) z))
2596         ((\z. (lambda i. if i <= 2 then (fstcart z)$i
2597                          else (sndcart z)$i):real^N) o
2598          I o
2599          (\z:real^N. pastecart ((lambda i. z$i) :real^2) z))`
2600     MP_TAC THENL
2601      [MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN
2602       EXISTS_TAC `(:real^2) PCROSS (:real^N)` THEN
2603       REWRITE_TAC[SUBSET_UNIV] THEN CONJ_TAC THENL
2604        [ALL_TAC;
2605         MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN
2606         ONCE_REWRITE_TAC[LINEAR_COMPONENTWISE] THEN
2607         SIMP_TAC[LAMBDA_BETA] THEN X_GEN_TAC `i:num` THEN
2608         STRIP_TAC THEN ASM_CASES_TAC `i <= 2` THEN ASM_REWRITE_TAC[] THEN
2609         REWRITE_TAC[linear; FSTCART_ADD; FSTCART_CMUL;
2610                             SNDCART_ADD; SNDCART_CMUL] THEN
2611         REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
2612         REWRITE_TAC[LIFT_ADD; LIFT_CMUL]] THEN
2613       MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN
2614       EXISTS_TAC `(:real^2) PCROSS (:real^N)` THEN
2615       REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_UNIV; PASTECART_IN_PCROSS] THEN
2616       CONJ_TAC THENL
2617        [ALL_TAC;
2618         MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN
2619         MATCH_MP_TAC LINEAR_PASTECART THEN REWRITE_TAC[LINEAR_ID] THEN
2620         SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
2621                  VECTOR_MUL_COMPONENT]] THEN
2622       SUBGOAL_THEN
2623        `I = \z:real^(2,N)finite_sum. pastecart (fstcart z) (sndcart z)`
2624       SUBST1_TAC THENL
2625        [REWRITE_TAC[PASTECART_FST_SND; I_DEF]; ALL_TAC] THEN
2626       MATCH_MP_TAC HOMOTOPIC_WITH_PCROSS THEN
2627       EXISTS_TAC `orthogonal_transformation:(real^2->real^2)->bool` THEN
2628       EXISTS_TAC `\f:real^N->real^N. f = I` THEN REPEAT CONJ_TAC THENL
2629        [REWRITE_TAC[GSYM I_DEF; ETA_AX] THEN MATCH_MP_TAC lemma1 THEN
2630         FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INSERT_SUBSET]) THEN
2631         REWRITE_TAC[SING_SUBSET; SPAN_2; IN_ELIM_THM; IN_UNIV] THEN
2632         DISCH_THEN(REPEAT_TCL STRIP_THM_THEN SUBST_ALL_TAC) THEN
2633         POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN
2634         REWRITE_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
2635                     DIMINDEX_2; FORALL_2; VECTOR_2] THEN
2636         SIMP_TAC[BASIS_COMPONENT; ARITH; DIMINDEX_2; VEC_COMPONENT;
2637                  DIMINDEX_GE_1; LE_REFL] THEN
2638         MATCH_MP_TAC(TAUT
2639          `(r ==> q) /\ (s ==> p) ==> a /\ ~p /\ ~q ==> ~s /\ ~r`) THEN
2640         SIMP_TAC[REAL_MUL_RZERO; REAL_MUL_LZERO; REAL_MUL_RID;
2641                  REAL_ADD_LID; REAL_ADD_RID];
2642         REWRITE_TAC[HOMOTOPIC_WITH_REFL; SUBSET_UNIV; I_DEF] THEN
2643         REWRITE_TAC[CONTINUOUS_ON_ID];
2644         SIMP_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART;
2645                  LAMBDA_BETA; DIMINDEX_2; ARITH; I_THM] THEN
2646         REWRITE_TAC[ORTHOGONAL_TRANSFORMATION; NORM_EQ] THEN
2647         X_GEN_TAC `f:real^2->real^2` THEN GEN_TAC THEN STRIP_TAC THEN
2648         CONJ_TAC THENL
2649          [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [linear]) THEN
2650           SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
2651                    VECTOR_MUL_COMPONENT; DIMINDEX_2; ARITH] THEN
2652           MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN
2653           DISCH_THEN(ASSUME_TAC o GSYM) THEN GEN_TAC THEN
2654           GEN_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
2655           COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN
2656           AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
2657           SIMP_TAC[CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
2658                    VECTOR_MUL_COMPONENT];
2659           X_GEN_TAC `v:real^N` THEN REWRITE_TAC[dot; GSYM REAL_POW_2] THEN
2660           SUBGOAL_THEN `dimindex(:N) = 2 + (dimindex(:N) - 2)` SUBST1_TAC THENL
2661            [ASM_ARITH_TAC; ALL_TAC] THEN
2662           ASM_SIMP_TAC[SUM_ADD_SPLIT; ARITH_RULE `1 <= n + 1`] THEN
2663           BINOP_TAC THENL
2664            [RULE_ASSUM_TAC(REWRITE_RULE[dot; DIMINDEX_2; GSYM REAL_POW_2]) THEN
2665             FIRST_X_ASSUM(MP_TAC o SPEC `(lambda i. (v:real^N)$i):real^2`) THEN
2666             MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THEN
2667             MATCH_MP_TAC SUM_EQ_NUMSEG THEN
2668             FIRST_ASSUM(MP_TAC o MATCH_MP (ARITH_RULE
2669              `2 <= n ==> !i. i <= 2 ==> i <= n`)) THEN
2670             SIMP_TAC[LAMBDA_BETA; DIMINDEX_2];
2671             ASM_SIMP_TAC[ARITH_RULE `2 <= n ==> 2 + n - 2 = n`] THEN
2672             MATCH_MP_TAC SUM_EQ_NUMSEG THEN
2673             SIMP_TAC[ARITH_RULE `2 + 1 <= i ==> 1 <= i`;
2674                      LAMBDA_BETA; DIMINDEX_2] THEN
2675             REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
2676             ASM_ARITH_TAC]]];
2677       MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_EQ) THEN
2678       REWRITE_TAC[IN_UNIV; GSYM FUN_EQ_THM] THEN
2679       SIMP_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART;
2680                LAMBDA_BETA; DIMINDEX_2; ARITH; I_THM] THEN
2681       RULE_ASSUM_TAC(REWRITE_RULE[INSERT_SUBSET; EMPTY_SUBSET]) THEN
2682       ASM_SIMP_TAC[lemma0] THEN
2683       SIMP_TAC[CART_EQ; LAMBDA_BETA; DIMINDEX_2; ARITH; COND_ID] THEN
2684       MAP_EVERY X_GEN_TAC [`x:real^N`; `i:num`] THEN STRIP_TAC THEN
2685       COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
2686       SUBGOAL_THEN `(a:real^N)$i = &0 /\ (b:real^N)$i = &0` ASSUME_TAC THENL
2687        [FIRST_X_ASSUM(CONJUNCTS_THEN MP_TAC) THEN
2688         REWRITE_TAC[SPAN_2; IN_ELIM_THM; IN_UNIV] THEN REPEAT STRIP_TAC THEN
2689         ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
2690                      BASIS_COMPONENT] THEN
2691         REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN
2692         (REAL_ARITH_TAC ORELSE ASM_ARITH_TAC);
2693         ASM_REWRITE_TAC[reflect_along; VECTOR_SUB_COMPONENT; REAL_MUL_RZERO;
2694                         VECTOR_MUL_COMPONENT; REAL_SUB_RZERO]]]) in
2695   let lemma3 = prove
2696    (`!a b:real^N r.
2697           ~(a = vec 0) /\ ~(b = vec 0)
2698           ==> homotopic_with orthogonal_transformation ((:real^N),(:real^N))
2699                              (reflect_along a o reflect_along b) I`,
2700     REPEAT STRIP_TAC THEN ASM_CASES_TAC `dimindex(:N) = 1` THENL
2701      [ASM_SIMP_TAC[o_DEF; I_DEF; REFLECT_ALONG_1D; VECTOR_NEG_NEG] THEN
2702       REWRITE_TAC[HOMOTOPIC_WITH_REFL; SUBSET_UNIV; CONTINUOUS_ON_ID] THEN
2703       REWRITE_TAC[ORTHOGONAL_TRANSFORMATION_ID];
2704       FIRST_X_ASSUM(MP_TAC o MATCH_MP(ARITH_RULE
2705        `~(n = 1) ==> 1 <= n ==> 2 <= n`)) THEN
2706       REWRITE_TAC[DIMINDEX_GE_1] THEN DISCH_TAC] THEN
2707     MP_TAC(ISPECL [`span{a:real^N,b}`; `span{basis 1:real^N,basis 2}`]
2708           ORTHOGONAL_TRANSFORMATION_INTO_SUBSPACE) THEN
2709     REWRITE_TAC[SUBSPACE_SPAN; DIM_SPAN] THEN ANTS_TAC THENL
2710      [ASM_REWRITE_TAC[DIM_INSERT; SPAN_SING; SPAN_EMPTY;
2711                       IN_SING; DIM_EMPTY] THEN
2712       MATCH_MP_TAC(ARITH_RULE `m <= 2 /\ n = 2 ==> m <= n`) THEN
2713       CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
2714       ASM_SIMP_TAC[BASIS_NONZERO; ARITH] THEN
2715       REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN
2716       COND_CASES_TAC THEN REWRITE_TAC[] THEN
2717       FIRST_X_ASSUM(CHOOSE_THEN (MP_TAC o AP_TERM `(\x:real^N. x$1)`)) THEN
2718       ASM_SIMP_TAC[BASIS_COMPONENT; VECTOR_MUL_COMPONENT;
2719                    ARITH; DIMINDEX_GE_1] THEN
2720       REAL_ARITH_TAC;
2721       DISCH_THEN(X_CHOOSE_THEN `f:real^N->real^N` STRIP_ASSUME_TAC) THEN
2722       MP_TAC(ISPEC `f:real^N->real^N` ORTHOGONAL_TRANSFORMATION_INVERSE_o) THEN
2723       ASM_REWRITE_TAC[] THEN
2724       DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^N` STRIP_ASSUME_TAC)] THEN
2725     SUBGOAL_THEN
2726      `homotopic_with orthogonal_transformation ((:real^N),(:real^N))
2727        (g o (f o (reflect_along a o reflect_along b) o (g:real^N->real^N)) o f)
2728        (g o (f o I o (g:real^N->real^N)) o f)`
2729     MP_TAC THENL
2730      [ALL_TAC;
2731       ASM_REWRITE_TAC[o_ASSOC] THEN ASM_REWRITE_TAC[GSYM o_ASSOC; I_O_ID]] THEN
2732     MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN
2733     EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[SUBSET_UNIV] THEN
2734     ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_LINEAR; LINEAR_CONTINUOUS_ON] THEN
2735     MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN
2736     EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[SUBSET_UNIV] THEN
2737     ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_LINEAR; LINEAR_CONTINUOUS_ON] THEN
2738     ASM_REWRITE_TAC[I_O_ID] THEN
2739     MP_TAC(ISPEC `f:real^N->real^N` REFLECT_ALONG_LINEAR_IMAGE) THEN
2740     ASM_REWRITE_TAC[GSYM ORTHOGONAL_TRANSFORMATION] THEN
2741     DISCH_THEN(ASSUME_TAC o GSYM) THEN
2742     SUBGOAL_THEN
2743      `!h:real^N->real^N.
2744           orthogonal_transformation (g o h o (f:real^N->real^N)) <=>
2745           orthogonal_transformation h`
2746      (fun th -> REWRITE_TAC[th; ETA_AX])
2747     THENL
2748      [GEN_TAC THEN EQ_TAC THEN
2749       ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_COMPOSE] THEN
2750       DISCH_TAC THEN
2751       SUBGOAL_THEN `h:real^N->real^N = f o (g o h o f) o (g:real^N->real^N)`
2752       SUBST1_TAC THENL
2753        [ALL_TAC; ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_COMPOSE]] THEN
2754       ASM_REWRITE_TAC[o_ASSOC] THEN ASM_REWRITE_TAC[GSYM o_ASSOC; I_O_ID];
2755       ALL_TAC] THEN
2756     SUBGOAL_THEN
2757      `(f:real^N->real^N) o (reflect_along a o reflect_along b) o g =
2758       reflect_along (f a) o reflect_along (f b)`
2759     SUBST1_TAC THENL
2760      [RULE_ASSUM_TAC(REWRITE_RULE[FUN_EQ_THM; o_THM; I_THM]) THEN
2761       ASM_REWRITE_TAC[o_DEF];
2762       MATCH_MP_TAC lemma2 THEN RULE_ASSUM_TAC
2763        (REWRITE_RULE[GSYM NORM_EQ_0; ORTHOGONAL_TRANSFORMATION]) THEN
2764       ASM_REWRITE_TAC[GSYM NORM_EQ_0] THEN
2765       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
2766          SUBSET_TRANS)) THEN
2767       ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE; IMAGE_CLAUSES] THEN
2768       REWRITE_TAC[SPAN_INC]]) in
2769   GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2770   MP_TAC(ISPECL [`f:real^N->real^N`; `dimindex(:N)`]
2771         ORTHOGONAL_TRANSFORMATION_GENERATED_BY_REFLECTIONS) THEN
2772   ASM_REWRITE_TAC[ARITH_RULE `n:num <= a + n`] THEN
2773   DISCH_THEN(X_CHOOSE_THEN `l:(real^N)list` STRIP_ASSUME_TAC) THEN
2774   UNDISCH_TAC `ALL (\v:real^N. ~(v = vec 0)) l` THEN
2775   UNDISCH_TAC `orthogonal_transformation(f:real^N->real^N)` THEN
2776   MATCH_MP_TAC(TAUT `r /\ (p /\ q ==> s) ==> r ==> p ==> q ==> s`) THEN
2777   ASM_REWRITE_TAC[IMP_IMP] THEN
2778   SPEC_TAC(`l:(real^N)list`,`l:(real^N)list`) THEN
2779   POP_ASSUM_LIST(K ALL_TAC) THEN GEN_TAC THEN
2780   WF_INDUCT_TAC `LENGTH(l:(real^N)list)` THEN POP_ASSUM MP_TAC THEN
2781   SPEC_TAC(`l:(real^N)list`,`l:(real^N)list`) THEN
2782   MATCH_MP_TAC list_INDUCT THEN
2783   REWRITE_TAC[ALL; ITLIST; HOMOTOPIC_WITH_REFL] THEN
2784   REWRITE_TAC[REWRITE_RULE[GSYM I_DEF] CONTINUOUS_ON_ID;
2785               ORTHOGONAL_TRANSFORMATION_I; SUBSET_UNIV] THEN
2786   X_GEN_TAC `a:real^N` THEN MATCH_MP_TAC list_INDUCT THEN
2787   REWRITE_TAC[ALL; ITLIST; I_O_ID; DET_MATRIX_REFLECT_ALONG] THEN
2788   REWRITE_TAC[ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG] THEN
2789   CONJ_TAC THENL [MESON_TAC[REAL_ARITH `~(-- &1 = &1)`]; ALL_TAC] THEN
2790   MAP_EVERY X_GEN_TAC [`b:real^N`; `l:(real^N)list`] THEN
2791   REPLICATE_TAC 2 (DISCH_THEN(K ALL_TAC)) THEN
2792   DISCH_THEN(MP_TAC o SPEC `l:(real^N)list`) THEN
2793   REWRITE_TAC[LENGTH; ARITH_RULE `n < SUC(SUC n)`] THEN
2794   SIMP_TAC[LINEAR_COMPOSE; LINEAR_REFLECT_ALONG; MATRIX_COMPOSE;
2795      ORTHGOONAL_TRANSFORMATION_REFLECT_ALONG;
2796      ORTHOGONAL_TRANSFORMATION_COMPOSE; ORTHOGONAL_TRANSFORMATION_LINEAR] THEN
2797   DISCH_THEN(fun th ->
2798     DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN MP_TAC th) THEN
2799   ASM_SIMP_TAC[DET_MUL; DET_MATRIX_REFLECT_ALONG; REAL_ARITH
2800    `-- &1 * -- &1 * x = x`] THEN
2801   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2802   DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
2803   ASM_REWRITE_TAC[] THEN
2804   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOMOTOPIC_WITH_TRANS) THEN
2805   GEN_REWRITE_TAC RAND_CONV [MESON[I_O_ID] `f = I o f`] THEN
2806   REWRITE_TAC[o_ASSOC] THEN
2807   MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN
2808   EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[SUBSET_UNIV] THEN
2809   ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON; ORTHOGONAL_TRANSFORMATION_LINEAR] THEN
2810   ABBREV_TAC `g = ITLIST (\v:real^N h. reflect_along v o h) l I` THEN
2811   SUBGOAL_THEN
2812    `(\f:real^N->real^N.
2813         orthogonal_transformation (f o g)) = orthogonal_transformation`
2814   SUBST1_TAC THENL [ALL_TAC; MATCH_MP_TAC lemma3 THEN ASM_REWRITE_TAC[]] THEN
2815   REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `f:real^N->real^N` THEN
2816   EQ_TAC THEN ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_COMPOSE] THEN
2817   DISCH_TAC THEN
2818   MP_TAC(ISPEC `g:real^N->real^N` ORTHOGONAL_TRANSFORMATION_INVERSE_o) THEN
2819   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `h:real^N->real^N` THEN
2820   STRIP_TAC THEN
2821   SUBGOAL_THEN `f = ((f:real^N->real^N) o (g:real^N->real^N)) o h`
2822   SUBST1_TAC THENL
2823    [ASM_REWRITE_TAC[GSYM o_ASSOC; I_O_ID];
2824     ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_COMPOSE]]);;
2825
2826 let HOMOTOPIC_SPECIAL_ORTHOGONAL_TRANSFORMATIONS,
2827     HOMOTOPIC_ORTHOGONAL_TRANSFORMATIONS = (CONJ_PAIR o prove)
2828  (`(!f g. homotopic_with
2829             (\h. orthogonal_transformation h /\ det(matrix h) = det(matrix f))
2830             ((:real^N),(:real^N)) f g <=>
2831           homotopic_with
2832             orthogonal_transformation ((:real^N),(:real^N)) f g) /\
2833    !f g. homotopic_with orthogonal_transformation ((:real^N),(:real^N)) f g <=>
2834          orthogonal_transformation f /\ orthogonal_transformation g /\
2835          det(matrix f) = det(matrix g)`,
2836   REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
2837    `(u ==> s) /\ (s ==> t) /\ (t ==> u)
2838     ==> (u <=> t) /\ (t <=> s)`) THEN
2839   REPEAT CONJ_TAC THENL
2840    [DISCH_THEN(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_PROPERTY) THEN MESON_TAC[];
2841     STRIP_TAC THEN
2842     MP_TAC(ISPEC `g:real^N->real^N` ORTHOGONAL_TRANSFORMATION_INVERSE_o) THEN
2843     ASM_REWRITE_TAC[] THEN
2844     DISCH_THEN(X_CHOOSE_THEN `h:real^N->real^N` STRIP_ASSUME_TAC) THEN
2845     SUBGOAL_THEN
2846      `(f:real^N->real^N) = g o (h:real^N->real^N) o f /\ g = g o I`
2847      (fun th -> ONCE_REWRITE_TAC[th])
2848     THENL [ASM_REWRITE_TAC[o_ASSOC; I_O_ID]; ALL_TAC] THEN
2849     MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_LEFT THEN
2850     EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[SUBSET_UNIV] THEN
2851     ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_LINEAR; LINEAR_CONTINUOUS_ON] THEN
2852     SUBGOAL_THEN
2853       `!k:real^N->real^N.
2854           orthogonal_transformation (g o k) <=> orthogonal_transformation k`
2855       (fun th -> REWRITE_TAC[th; ETA_AX])
2856     THENL
2857      [GEN_TAC THEN EQ_TAC THEN
2858       ASM_SIMP_TAC[ORTHOGONAL_TRANSFORMATION_COMPOSE] THEN DISCH_THEN
2859        (MP_TAC o SPEC `h:real^N->real^N` o MATCH_MP (ONCE_REWRITE_RULE
2860          [IMP_CONJ_ALT] ORTHOGONAL_TRANSFORMATION_COMPOSE)) THEN
2861       ASM_SIMP_TAC[o_ASSOC; I_O_ID];
2862       MATCH_MP_TAC NULLHOMOTOPIC_ORTHOGONAL_TRANSFORMATION THEN
2863       REPEAT(FIRST_X_ASSUM(MP_TAC o AP_TERM
2864        `\f:real^N->real^N. det(matrix f)`)) THEN
2865       ASM_SIMP_TAC[MATRIX_COMPOSE; ORTHOGONAL_TRANSFORMATION_LINEAR;
2866                    ORTHOGONAL_TRANSFORMATION_COMPOSE; DET_MUL;
2867                    MATRIX_I; DET_I]];
2868     REWRITE_TAC[homotopic_with] THEN MATCH_MP_TAC MONO_EXISTS THEN
2869     X_GEN_TAC `k:real^(1,N)finite_sum->real^N` THEN
2870     STRIP_TAC THEN ASM_SIMP_TAC[] THEN MP_TAC(ISPECL
2871      [`\t. lift(
2872        det(matrix((k:real^(1,N)finite_sum->real^N) o pastecart t)))`;
2873       `interval[vec 0:real^1,vec 1]`]
2874      CONTINUOUS_DISCRETE_RANGE_CONSTANT) THEN
2875     REWRITE_TAC[CONNECTED_INTERVAL] THEN ANTS_TAC THENL
2876      [CONJ_TAC THENL
2877        [MATCH_MP_TAC CONTINUOUS_ON_LIFT_DET THEN
2878         SIMP_TAC[matrix; LAMBDA_BETA; o_DEF] THEN
2879         MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN STRIP_TAC THEN
2880         MATCH_MP_TAC CONTINUOUS_ON_LIFT_COMPONENT_COMPOSE THEN
2881         ASM_REWRITE_TAC[] THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
2882         MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
2883         SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_CONST;
2884                  CONTINUOUS_ON_ID] THEN
2885         FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
2886           CONTINUOUS_ON_SUBSET)) THEN
2887         SIMP_TAC[SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS; IN_UNIV];
2888         X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN
2889         REWRITE_TAC[REAL_LT_01] THEN X_GEN_TAC `u:real^1` THEN
2890         DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2891         REWRITE_TAC[GSYM LIFT_SUB; NORM_LIFT; LIFT_EQ] THEN
2892         SUBGOAL_THEN
2893          `orthogonal_transformation
2894            ((k:real^(1,N)finite_sum->real^N) o pastecart t) /\
2895           orthogonal_transformation (k o pastecart u)`
2896         MP_TAC THENL [ASM_SIMP_TAC[o_DEF]; ALL_TAC] THEN
2897         DISCH_THEN(CONJUNCTS_THEN
2898           (STRIP_ASSUME_TAC o MATCH_MP DET_ORTHOGONAL_MATRIX o
2899                     MATCH_MP ORTHOGONAL_MATRIX_MATRIX)) THEN
2900         ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV];
2901       REWRITE_TAC[o_DEF; LEFT_IMP_EXISTS_THM] THEN
2902       X_GEN_TAC `a:real^1` THEN DISCH_TAC THEN
2903       REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM FUN_EQ_THM])) THEN
2904       REPEAT(DISCH_THEN(SUBST1_TAC o SYM)) THEN
2905       ASM_SIMP_TAC[ENDS_IN_UNIT_INTERVAL; GSYM LIFT_EQ]]]);;
2906
2907 (* ------------------------------------------------------------------------- *)
2908 (* Complex tangent function.                                                 *)
2909 (* ------------------------------------------------------------------------- *)
2910
2911 let ctan = new_definition
2912  `ctan z = csin z / ccos z`;;
2913
2914 let CTAN_0 = prove
2915  (`ctan(Cx(&0)) = Cx(&0)`,
2916   REWRITE_TAC[ctan; CSIN_0; CCOS_0; COMPLEX_DIV_1]);;
2917
2918 let CTAN_NEG = prove
2919  (`!z. ctan(--z) = --(ctan z)`,
2920   REWRITE_TAC[ctan; CSIN_NEG; CCOS_NEG; complex_div; COMPLEX_MUL_LNEG]);;
2921
2922 let CTAN_ADD = prove
2923  (`!w z. ~(ccos(w) = Cx(&0)) /\
2924          ~(ccos(z) = Cx(&0)) /\
2925          ~(ccos(w + z) = Cx(&0))
2926          ==> ctan(w + z) = (ctan w + ctan z) / (Cx(&1) - ctan(w) * ctan(z))`,
2927   REPEAT GEN_TAC THEN REWRITE_TAC[ctan; CSIN_ADD; CCOS_ADD] THEN
2928   CONV_TAC COMPLEX_FIELD);;
2929
2930 let CTAN_DOUBLE = prove
2931  (`!z. ~(ccos(z) = Cx(&0)) /\ ~(ccos(Cx(&2) * z) = Cx(&0))
2932        ==> ctan(Cx(&2) * z) =
2933            (Cx(&2) * ctan z) / (Cx(&1) - ctan(z) pow 2)`,
2934   SIMP_TAC[COMPLEX_MUL_2; CTAN_ADD; COMPLEX_POW_2]);;
2935
2936 let CTAN_SUB = prove
2937  (`!w z. ~(ccos(w) = Cx(&0)) /\
2938          ~(ccos(z) = Cx(&0)) /\
2939          ~(ccos(w - z) = Cx(&0))
2940          ==> ctan(w - z) = (ctan w - ctan z) / (Cx(&1) + ctan(w) * ctan(z))`,
2941   SIMP_TAC[complex_sub; CTAN_ADD; CCOS_NEG; CTAN_NEG] THEN
2942   REWRITE_TAC[COMPLEX_MUL_RNEG; COMPLEX_NEG_NEG]);;
2943
2944 let COMPLEX_ADD_CTAN = prove
2945  (`!w z. ~(ccos(w) = Cx(&0)) /\
2946          ~(ccos(z) = Cx(&0))
2947          ==> ctan(w) + ctan(z) = csin(w + z) / (ccos(w) * ccos(z))`,
2948   REWRITE_TAC[ctan; CSIN_ADD] THEN CONV_TAC COMPLEX_FIELD);;
2949
2950 let COMPLEX_SUB_CTAN = prove
2951  (`!w z. ~(ccos(w) = Cx(&0)) /\
2952          ~(ccos(z) = Cx(&0))
2953          ==> ctan(w) - ctan(z) = csin(w - z) / (ccos(w) * ccos(z))`,
2954   REWRITE_TAC[ctan; CSIN_SUB] THEN CONV_TAC COMPLEX_FIELD);;
2955
2956 (* ------------------------------------------------------------------------- *)
2957 (* Analytic properties of tangent function.                                  *)
2958 (* ------------------------------------------------------------------------- *)
2959
2960 let HAS_COMPLEX_DERIVATIVE_CTAN = prove
2961  (`!z. ~(ccos z = Cx(&0))
2962        ==> (ctan has_complex_derivative (inv(ccos(z) pow 2))) (at z)`,
2963   REPEAT STRIP_TAC THEN
2964   GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
2965   REWRITE_TAC[ctan] THEN COMPLEX_DIFF_TAC THEN
2966   MP_TAC(SPEC `z:complex` CSIN_CIRCLE) THEN
2967   POP_ASSUM MP_TAC THEN CONV_TAC COMPLEX_FIELD);;
2968
2969 let COMPLEX_DIFFERENTIABLE_AT_CTAN = prove
2970  (`!z. ~(ccos z = Cx(&0)) ==> ctan complex_differentiable at z`,
2971   REWRITE_TAC[complex_differentiable] THEN
2972   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CTAN]);;
2973
2974 let COMPLEX_DIFFERENTIABLE_WITHIN_CTAN = prove
2975  (`!s z. ~(ccos z = Cx(&0))
2976          ==> ctan complex_differentiable (at z within s)`,
2977   MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN;
2978             COMPLEX_DIFFERENTIABLE_AT_CTAN]);;
2979
2980 add_complex_differentiation_theorems
2981  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
2982    (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN
2983              HAS_COMPLEX_DERIVATIVE_CTAN)));;
2984
2985 let CONTINUOUS_AT_CTAN = prove
2986  (`!z. ~(ccos z = Cx(&0)) ==> ctan continuous at z`,
2987   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CTAN;
2988             HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);;
2989
2990 let CONTINUOUS_WITHIN_CTAN = prove
2991  (`!s z. ~(ccos z = Cx(&0)) ==> ctan continuous (at z within s)`,
2992   MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CTAN]);;
2993
2994 let CONTINUOUS_ON_CTAN = prove
2995  (`!s. (!z. z IN s ==> ~(ccos z = Cx(&0))) ==> ctan continuous_on s`,
2996   MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CTAN]);;
2997
2998 let HOLOMORPHIC_ON_CTAN = prove
2999  (`!s. (!z. z IN s ==> ~(ccos z = Cx(&0))) ==> ctan holomorphic_on s`,
3000   REWRITE_TAC [holomorphic_on] THEN
3001   MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CTAN]);;
3002
3003 (* ------------------------------------------------------------------------- *)
3004 (* Real tangent function.                                                    *)
3005 (* ------------------------------------------------------------------------- *)
3006
3007 let tan_def = new_definition
3008  `tan(x) = Re(ctan(Cx x))`;;
3009
3010 let CNJ_CTAN = prove
3011  (`!z. cnj(ctan z) = ctan(cnj z)`,
3012   REWRITE_TAC[ctan; CNJ_DIV; CNJ_CSIN; CNJ_CCOS]);;
3013
3014 let REAL_TAN = prove
3015  (`!z. real z ==> real(ctan z)`,
3016   SIMP_TAC[REAL_CNJ; CNJ_CTAN]);;
3017
3018 let CX_TAN = prove
3019  (`!x. Cx(tan x) = ctan(Cx x)`,
3020   REWRITE_TAC[tan_def] THEN MESON_TAC[REAL; REAL_CX; REAL_TAN]);;
3021
3022 let tan = prove
3023  (`!x. tan x = sin x / cos x`,
3024   REWRITE_TAC[GSYM CX_INJ; CX_DIV; CX_TAN; CX_SIN; CX_COS; ctan]);;
3025
3026 let TAN_0 = prove
3027  (`tan(&0) = &0`,
3028   REWRITE_TAC[GSYM CX_INJ; CX_TAN; CTAN_0]);;
3029
3030 let TAN_PI = prove
3031  (`tan(pi) = &0`,
3032   REWRITE_TAC[tan; SIN_PI; real_div; REAL_MUL_LZERO]);;
3033
3034 let TAN_NPI = prove
3035  (`!n. tan(&n * pi) = &0`,
3036   REWRITE_TAC[tan; SIN_NPI; real_div; REAL_MUL_LZERO]);;
3037
3038 let TAN_NEG = prove
3039  (`!x. tan(--x) = --(tan x)`,
3040   REWRITE_TAC[GSYM CX_INJ; CX_TAN; CX_NEG; CTAN_NEG]);;
3041
3042 let TAN_PERIODIC_PI = prove
3043  (`!x. tan(x + pi) = tan(x)`,
3044   REWRITE_TAC[tan; SIN_PERIODIC_PI; COS_PERIODIC_PI; real_div] THEN
3045   REWRITE_TAC[REAL_MUL_LNEG; REAL_INV_NEG; REAL_MUL_RNEG; REAL_NEG_NEG]);;
3046
3047 let TAN_PERIODIC_NPI = prove
3048  (`!x n. tan(x + &n * pi) = tan(x)`,
3049   GEN_TAC THEN INDUCT_TAC THEN REWRITE_TAC[REAL_MUL_LZERO; REAL_ADD_RID] THEN
3050   REWRITE_TAC[GSYM REAL_OF_NUM_SUC; REAL_ADD_RDISTRIB; REAL_MUL_LID] THEN
3051   ASM_REWRITE_TAC[REAL_ADD_ASSOC; TAN_PERIODIC_PI]);;
3052
3053 let TAN_ADD = prove
3054  (`!x y. ~(cos(x) = &0) /\ ~(cos(y) = &0) /\ ~(cos(x + y) = &0)
3055          ==> tan(x + y) = (tan(x) + tan(y)) / (&1 - tan(x) * tan(y))`,
3056   REWRITE_TAC[GSYM CX_INJ; CX_TAN; CX_SIN; CX_COS; CTAN_ADD;
3057               CX_DIV; CX_ADD; CX_SUB; CX_MUL]);;
3058
3059 let TAN_SUB = prove
3060  (`!x y. ~(cos(x) = &0) /\ ~(cos(y) = &0) /\ ~(cos(x - y) = &0)
3061          ==> tan(x - y) = (tan(x) - tan(y)) / (&1 + tan(x) * tan(y))`,
3062   REWRITE_TAC[GSYM CX_INJ; CX_TAN; CX_SIN; CX_COS; CX_ADD; CTAN_SUB;
3063               CX_DIV; CX_ADD; CX_SUB; CX_MUL]);;
3064
3065 let TAN_DOUBLE = prove
3066  (`!x. ~(cos(x) = &0) /\ ~(cos(&2 * x) = &0)
3067        ==> tan(&2 * x) = (&2 * tan(x)) / (&1 - (tan(x) pow 2))`,
3068   SIMP_TAC[REAL_MUL_2; TAN_ADD; REAL_POW_2]);;
3069
3070 let REAL_ADD_TAN = prove
3071  (`!x y. ~(cos(x) = &0) /\ ~(cos(y) = &0)
3072          ==> tan(x) + tan(y) = sin(x + y) / (cos(x) * cos(y))`,
3073   REWRITE_TAC[GSYM CX_INJ; CX_TAN; CX_SIN; CX_COS; CX_MUL; CX_ADD; CX_DIV] THEN
3074   REWRITE_TAC[COMPLEX_ADD_CTAN]);;
3075
3076 let REAL_SUB_TAN = prove
3077  (`!x y. ~(cos(x) = &0) /\ ~(cos(y) = &0)
3078          ==> tan(x) - tan(y) = sin(x - y) / (cos(x) * cos(y))`,
3079   REWRITE_TAC[GSYM CX_INJ; CX_TAN; CX_SIN; CX_COS; CX_MUL; CX_SUB; CX_DIV] THEN
3080   REWRITE_TAC[COMPLEX_SUB_CTAN]);;
3081
3082 let TAN_PI4 = prove
3083  (`tan(pi / &4) = &1`,
3084   REWRITE_TAC[tan; SIN_COS; REAL_ARITH `p / &2 - p / &4 = p / &4`] THEN
3085   MATCH_MP_TAC REAL_DIV_REFL THEN REWRITE_TAC[COS_EQ_0; PI_NZ; REAL_FIELD
3086    `p / &4 = (n + &1 / &2) * p <=> p = &0 \/ n = -- &1 / &4`] THEN
3087   ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[UNWIND_THM2] THEN
3088   DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
3089    REAL_ABS_INTEGER_LEMMA)) THEN
3090   REAL_ARITH_TAC);;
3091
3092 let TAN_POS_PI2 = prove
3093  (`!x. &0 < x /\ x < pi / &2 ==> &0 < tan x`,
3094   REPEAT STRIP_TAC THEN REWRITE_TAC[tan] THEN
3095   MATCH_MP_TAC REAL_LT_DIV THEN CONJ_TAC THENL
3096    [MATCH_MP_TAC SIN_POS_PI; MATCH_MP_TAC COS_POS_PI] THEN
3097   ASM_REAL_ARITH_TAC);;
3098
3099 let TAN_POS_PI2_LE = prove
3100  (`!x. &0 <= x /\ x < pi / &2 ==> &0 <= tan x`,
3101   REWRITE_TAC[REAL_LE_LT] THEN MESON_TAC[TAN_0; TAN_POS_PI2]);;
3102
3103 let COS_TAN = prove
3104  (`!x. abs(x) < pi / &2 ==> cos(x) = &1 / sqrt(&1 + tan(x) pow 2)`,
3105   REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_FIELD
3106    `sqrt(s) pow 2 = s /\ c pow 2 * s = &1 /\ ~(&1 + c * sqrt s = &0)
3107     ==> c = &1 / sqrt s`) THEN
3108   SUBGOAL_THEN `&0 < &1 + tan x pow 2` ASSUME_TAC THENL
3109    [MP_TAC(SPEC `tan x` REAL_LE_SQUARE) THEN REAL_ARITH_TAC; ALL_TAC] THEN
3110   ASM_SIMP_TAC[SQRT_POW_2; REAL_LT_IMP_LE] THEN CONJ_TAC THENL
3111    [REWRITE_TAC[tan] THEN
3112     MATCH_MP_TAC(REAL_FIELD
3113      `s pow 2 + c pow 2 = &1 /\ &0 < c
3114       ==> c pow 2 * (&1 + (s / c) pow 2) = &1`) THEN
3115     ASM_SIMP_TAC[SIN_CIRCLE; COS_POS_PI; REAL_BOUNDS_LT];
3116     MATCH_MP_TAC(REAL_ARITH `&0 < x ==> ~(&1 + x = &0)`) THEN
3117     ASM_SIMP_TAC[SIN_CIRCLE; COS_POS_PI; REAL_BOUNDS_LT; SQRT_POS_LT;
3118                  REAL_LT_MUL]]);;
3119
3120 let SIN_TAN = prove
3121  (`!x. abs(x) < pi / &2 ==> sin(x) = tan(x) / sqrt(&1 + tan(x) pow 2)`,
3122   REPEAT STRIP_TAC THEN
3123   ONCE_REWRITE_TAC[REAL_ARITH `a / b = a * &1 / b`] THEN
3124   ASM_SIMP_TAC[GSYM COS_TAN] THEN
3125   ASM_SIMP_TAC[tan; REAL_DIV_RMUL; REAL_LT_IMP_NZ; COS_POS_PI;
3126                REAL_BOUNDS_LT]);;
3127
3128 (* ------------------------------------------------------------------------- *)
3129 (* Monotonicity theorems for the basic trig functions.                       *)
3130 (* ------------------------------------------------------------------------- *)
3131
3132 let SIN_MONO_LT = prove
3133  (`!x y. --(pi / &2) <= x /\ x < y /\ y <= pi / &2 ==> sin(x) < sin(y)`,
3134   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN
3135   REWRITE_TAC[REAL_SUB_SIN; REAL_ARITH `&0 < &2 * x <=> &0 < x`] THEN
3136   MATCH_MP_TAC REAL_LT_MUL THEN CONJ_TAC THENL
3137    [MATCH_MP_TAC SIN_POS_PI; MATCH_MP_TAC COS_POS_PI] THEN
3138   ASM_REAL_ARITH_TAC);;
3139
3140 let SIN_MONO_LE = prove
3141  (`!x y. --(pi / &2) <= x /\ x <= y /\ y <= pi / &2 ==> sin(x) <= sin(y)`,
3142   MESON_TAC[SIN_MONO_LT; REAL_LE_LT]);;
3143
3144 let SIN_MONO_LT_EQ = prove
3145  (`!x y. --(pi / &2) <= x /\ x <= pi / &2 /\ --(pi / &2) <= y /\ y <= pi / &2
3146          ==> (sin(x) < sin(y) <=> x < y)`,
3147   MESON_TAC[REAL_NOT_LE; SIN_MONO_LT; SIN_MONO_LE]);;
3148
3149 let SIN_MONO_LE_EQ = prove
3150  (`!x y. --(pi / &2) <= x /\ x <= pi / &2 /\ --(pi / &2) <= y /\ y <= pi / &2
3151          ==> (sin(x) <= sin(y) <=> x <= y)`,
3152   MESON_TAC[REAL_NOT_LE; SIN_MONO_LT; SIN_MONO_LE]);;
3153
3154 let SIN_INJ_PI = prove
3155  (`!x y. --(pi / &2) <= x /\ x <= pi / &2 /\
3156          --(pi / &2) <= y /\ y <= pi / &2 /\
3157          sin(x) = sin(y)
3158          ==> x = y`,
3159   REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN MESON_TAC[SIN_MONO_LE_EQ]);;
3160
3161 let COS_MONO_LT = prove
3162  (`!x y. &0 <= x /\ x < y /\ y <= pi ==> cos(y) < cos(x)`,
3163   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN
3164   REWRITE_TAC[REAL_SUB_COS; REAL_ARITH `&0 < &2 * x <=> &0 < x`] THEN
3165   MATCH_MP_TAC REAL_LT_MUL THEN CONJ_TAC THEN MATCH_MP_TAC SIN_POS_PI THEN
3166   ASM_REAL_ARITH_TAC);;
3167
3168 let COS_MONO_LE = prove
3169  (`!x y. &0 <= x /\ x <= y /\ y <= pi ==> cos(y) <= cos(x)`,
3170   MESON_TAC[COS_MONO_LT; REAL_LE_LT]);;
3171
3172 let COS_MONO_LT_EQ = prove
3173  (`!x y. &0 <= x /\ x <= pi /\ &0 <= y /\ y <= pi
3174          ==> (cos(x) < cos(y) <=> y < x)`,
3175   MESON_TAC[REAL_NOT_LE; COS_MONO_LT; COS_MONO_LE]);;
3176
3177 let COS_MONO_LE_EQ = prove
3178  (`!x y. &0 <= x /\ x <= pi /\ &0 <= y /\ y <= pi
3179          ==> (cos(x) <= cos(y) <=> y <= x)`,
3180   MESON_TAC[REAL_NOT_LE; COS_MONO_LT; COS_MONO_LE]);;
3181
3182 let COS_INJ_PI = prove
3183  (`!x y. &0 <= x /\ x <= pi /\ &0 <= y /\ y <= pi /\ cos(x) = cos(y)
3184          ==> x = y`,
3185   REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN MESON_TAC[COS_MONO_LE_EQ]);;
3186
3187 let TAN_MONO_LT = prove
3188  (`!x y. --(pi / &2) < x /\ x < y /\ y < pi / &2 ==> tan(x) < tan(y)`,
3189   REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [GSYM REAL_SUB_LT] THEN
3190   SUBGOAL_THEN `&0 < cos(x) /\ &0 < cos(y)` STRIP_ASSUME_TAC THENL
3191    [CONJ_TAC THEN MATCH_MP_TAC COS_POS_PI;
3192     ASM_SIMP_TAC[REAL_LT_IMP_NZ; REAL_SUB_TAN] THEN
3193     MATCH_MP_TAC REAL_LT_DIV THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN
3194     MATCH_MP_TAC SIN_POS_PI] THEN
3195   ASM_REAL_ARITH_TAC);;
3196
3197 let TAN_MONO_LE = prove
3198  (`!x y. --(pi / &2) < x /\ x <= y /\ y < pi / &2 ==> tan(x) <= tan(y)`,
3199   REWRITE_TAC[REAL_LE_LT] THEN MESON_TAC[TAN_MONO_LT]);;
3200
3201 let TAN_MONO_LT_EQ = prove
3202  (`!x y. --(pi / &2) < x /\ x < pi / &2 /\ --(pi / &2) < y /\ y < pi / &2
3203          ==> (tan(x) < tan(y) <=> x < y)`,
3204   MESON_TAC[REAL_NOT_LE; TAN_MONO_LT; TAN_MONO_LE]);;
3205
3206 let TAN_MONO_LE_EQ = prove
3207  (`!x y. --(pi / &2) < x /\ x < pi / &2 /\ --(pi / &2) < y /\ y < pi / &2
3208          ==> (tan(x) <= tan(y) <=> x <= y)`,
3209   MESON_TAC[REAL_NOT_LE; TAN_MONO_LT; TAN_MONO_LE]);;
3210
3211 let TAN_BOUND_PI2 = prove
3212  (`!x. abs(x) < pi / &4 ==> abs(tan x) < &1`,
3213   REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM TAN_PI4] THEN
3214   REWRITE_TAC[GSYM TAN_NEG; REAL_ARITH `abs(x) < a <=> --a < x /\ x < a`] THEN
3215   CONJ_TAC THEN MATCH_MP_TAC TAN_MONO_LT THEN
3216   POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);;
3217
3218 let TAN_COT = prove
3219  (`!x. tan(pi / &2 - x) = inv(tan x)`,
3220   REWRITE_TAC[tan; SIN_SUB; COS_SUB; SIN_PI2; COS_PI2; REAL_INV_DIV] THEN
3221   GEN_TAC THEN BINOP_TAC THEN REAL_ARITH_TAC);;
3222
3223 (* ------------------------------------------------------------------------- *)
3224 (* Approximation to pi.                                                      *)
3225 (* ------------------------------------------------------------------------- *)
3226
3227 let SIN_PI6_STRADDLE = prove
3228  (`!a b. &0 <= a /\ a <= b /\ b <= &4 /\
3229          sin(a / &6) <= &1 / &2 /\ &1 / &2 <= sin(b / &6)
3230          ==> a <= pi /\ pi <= b`,
3231   REPEAT GEN_TAC THEN STRIP_TAC THEN
3232   MP_TAC(SPECL [`pi / &6`; `b / &6`] SIN_MONO_LE_EQ) THEN
3233   MP_TAC(SPECL [`a / &6`; `pi / &6`] SIN_MONO_LE_EQ) THEN
3234   ASM_REWRITE_TAC[SIN_PI6] THEN
3235   SUBGOAL_THEN `!x. &0 < x /\ x < &7 / &5 ==> &0 < sin x`
3236   MP_TAC THENL
3237    [REPEAT STRIP_TAC THEN MP_TAC(ISPECL [`0`; `Cx(x)`] TAYLOR_CSIN) THEN
3238     REWRITE_TAC[VSUM_SING_NUMSEG] THEN CONV_TAC NUM_REDUCE_CONV THEN
3239     REWRITE_TAC[COMPLEX_DIV_1; COMPLEX_POW_1; complex_pow] THEN
3240     REWRITE_TAC[COMPLEX_MUL_LID; GSYM CX_SIN; GSYM CX_SUB] THEN
3241     REWRITE_TAC[IM_CX; COMPLEX_NORM_CX; REAL_ABS_NUM; REAL_EXP_0] THEN
3242     MATCH_MP_TAC(REAL_ARITH
3243      `e + d < a ==> abs(s - a) <= d ==> e < s`) THEN
3244     ASM_SIMP_TAC[real_abs; real_pow; REAL_MUL_LID; REAL_LT_IMP_LE] THEN
3245     SIMP_TAC[REAL_ARITH `&0 + x pow 3 / &2 < x <=> x * x pow 2 < x * &2`] THEN
3246     ASM_SIMP_TAC[REAL_LT_LMUL_EQ] THEN
3247     MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `(&7 / &5) pow 2` THEN
3248     ASM_SIMP_TAC[REAL_POW_LT2; ARITH_EQ; REAL_LT_IMP_LE] THEN
3249     CONV_TAC REAL_RAT_REDUCE_CONV;
3250     DISCH_THEN(MP_TAC o SPEC `pi`) THEN
3251     SIMP_TAC[SIN_PI; REAL_LT_REFL; PI_POS; REAL_NOT_LT] THEN
3252     ASM_REAL_ARITH_TAC]);;
3253
3254 let PI_APPROX_32 = prove
3255  (`abs(pi - &13493037705 / &4294967296) <= inv(&2 pow 32)`,
3256   REWRITE_TAC[REAL_ARITH `abs(x - a) <= e <=> a - e <= x /\ x <= a + e`] THEN
3257   MATCH_MP_TAC SIN_PI6_STRADDLE THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
3258   CONJ_TAC THENL
3259    [MP_TAC(SPECL [`5`; `Cx(&1686629713 / &3221225472)`] TAYLOR_CSIN);
3260     MP_TAC(SPECL [`5`; `Cx(&6746518853 / &12884901888)`] TAYLOR_CSIN)] THEN
3261   CONV_TAC(ONCE_DEPTH_CONV EXPAND_VSUM_CONV) THEN CONV_TAC NUM_REDUCE_CONV THEN
3262   REWRITE_TAC[GSYM CX_POW; GSYM CX_DIV; GSYM CX_ADD; GSYM CX_SUB;
3263               GSYM CX_NEG; GSYM CX_MUL; GSYM CX_SIN; COMPLEX_NORM_CX] THEN
3264   REWRITE_TAC[IM_CX; REAL_ABS_NUM; REAL_EXP_0] THEN REAL_ARITH_TAC);;
3265
3266 let PI2_BOUNDS = prove
3267  (`&0 < pi / &2 /\ pi / &2 < &2`,
3268   MP_TAC PI_APPROX_32 THEN REAL_ARITH_TAC);;
3269
3270 (* ------------------------------------------------------------------------- *)
3271 (* Complex logarithms (the conventional principal value).                    *)
3272 (* ------------------------------------------------------------------------- *)
3273
3274 let clog = new_definition
3275  `clog z = @w. cexp(w) = z /\ --pi < Im(w) /\ Im(w) <= pi`;;
3276
3277 let EXISTS_COMPLEX' = prove
3278  (`!P. (?z. P (Re z) (Im z)) <=> ?x y. P x y`,
3279   MESON_TAC[RE; IM; COMPLEX]);;
3280
3281 let CLOG_WORKS = prove
3282  (`!z. ~(z = Cx(&0))
3283        ==> cexp(clog z) = z /\ --pi < Im(clog z) /\ Im(clog z) <= pi`,
3284   GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[clog] THEN CONV_TAC SELECT_CONV THEN
3285   MP_TAC(SPEC `z / Cx(norm z)` COMPLEX_UNIMODULAR_POLAR) THEN ANTS_TAC THENL
3286    [ASM_SIMP_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX] THEN
3287     ASM_SIMP_TAC[REAL_ABS_NORM; REAL_DIV_REFL; COMPLEX_NORM_ZERO];
3288     ALL_TAC] THEN
3289   DISCH_THEN(X_CHOOSE_THEN `x:real` STRIP_ASSUME_TAC) THEN
3290   MP_TAC(SPEC `x:real` SINCOS_PRINCIPAL_VALUE) THEN
3291   DISCH_THEN(X_CHOOSE_THEN `y:real` STRIP_ASSUME_TAC) THEN
3292   EXISTS_TAC `complex(log(norm(z:complex)),y)` THEN
3293   ASM_REWRITE_TAC[RE; IM; CEXP_COMPLEX] THEN
3294   REPEAT(FIRST_X_ASSUM(SUBST_ALL_TAC o SYM)) THEN
3295   ASM_SIMP_TAC[EXP_LOG; COMPLEX_NORM_NZ; COMPLEX_DIV_LMUL;
3296                COMPLEX_NORM_ZERO; CX_INJ]);;
3297
3298 let CEXP_CLOG = prove
3299  (`!z. ~(z = Cx(&0)) ==> cexp(clog z) = z`,
3300   SIMP_TAC[CLOG_WORKS]);;
3301
3302 let CLOG_CEXP = prove
3303  (`!z. --pi < Im(z) /\ Im(z) <= pi ==> clog(cexp z) = z`,
3304   REPEAT STRIP_TAC THEN REWRITE_TAC[clog] THEN
3305   MATCH_MP_TAC SELECT_UNIQUE THEN X_GEN_TAC `w:complex` THEN
3306   EQ_TAC THEN ASM_SIMP_TAC[] THEN REWRITE_TAC[CEXP_EQ] THEN
3307   REWRITE_TAC[IMP_CONJ] THEN DISCH_THEN(X_CHOOSE_THEN `n:real`
3308     (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN
3309   REWRITE_TAC[IM_ADD; IM_MUL_II; RE_CX] THEN REPEAT STRIP_TAC THEN
3310   ASM_CASES_TAC `n = &0` THEN ASM_REWRITE_TAC[REAL_MUL_LZERO] THEN
3311   REWRITE_TAC[REAL_MUL_RZERO; COMPLEX_ADD_RID; COMPLEX_MUL_LZERO] THEN
3312   SUBGOAL_THEN `abs(n * pi) < &1 * pi` MP_TAC THENL
3313    [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
3314   ASM_SIMP_TAC[REAL_ABS_MUL; REAL_LT_RMUL_EQ; PI_POS; REAL_ABS_PI] THEN
3315   ASM_MESON_TAC[REAL_ABS_INTEGER_LEMMA; REAL_NOT_LT]);;
3316
3317 let CLOG_EQ = prove
3318  (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) ==> (clog w = clog z <=> w = z)`,
3319   MESON_TAC[CEXP_CLOG]);;
3320
3321 let CLOG_UNIQUE = prove
3322  (`!w z. --pi < Im(z) /\ Im(z) <= pi /\ cexp(z) = w ==> clog w = z`,
3323   MESON_TAC[CLOG_CEXP]);;
3324
3325 let RE_CLOG = prove
3326  (`!z. ~(z = Cx(&0)) ==> Re(clog z) = log(norm z)`,
3327   REPEAT STRIP_TAC THEN FIRST_X_ASSUM
3328    (MP_TAC o AP_TERM `norm:complex->real` o MATCH_MP CEXP_CLOG) THEN
3329   REWRITE_TAC[NORM_CEXP] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
3330   REWRITE_TAC[LOG_EXP]);;
3331
3332 let EXISTS_COMPLEX_ROOT = prove
3333  (`!a n. ~(n = 0) ==> ?z. z pow n = a`,
3334   REPEAT STRIP_TAC THEN ASM_CASES_TAC `a = Cx(&0)` THENL
3335    [EXISTS_TAC `Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_POW_ZERO];
3336     EXISTS_TAC `cexp(clog(a) / Cx(&n))` THEN REWRITE_TAC[GSYM CEXP_N] THEN
3337     ASM_SIMP_TAC[COMPLEX_DIV_LMUL; CX_INJ; REAL_OF_NUM_EQ; CEXP_CLOG]]);;
3338
3339 (* ------------------------------------------------------------------------- *)
3340 (* Derivative of clog away from the branch cut.                              *)
3341 (* ------------------------------------------------------------------------- *)
3342
3343 let HAS_COMPLEX_DERIVATIVE_CLOG = prove
3344  (`!z. (Im(z) = &0 ==> &0 < Re(z))
3345        ==> (clog has_complex_derivative inv(z)) (at z)`,
3346   REPEAT STRIP_TAC THEN
3347   MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_INVERSE_STRONG_X THEN
3348   EXISTS_TAC `cexp` THEN
3349   EXISTS_TAC `{w | --pi < Im(w) /\ Im(w) < pi}` THEN
3350   REWRITE_TAC[IN_ELIM_THM] THEN
3351   ASM_CASES_TAC `z = Cx(&0)` THENL
3352    [FIRST_X_ASSUM SUBST_ALL_TAC THEN POP_ASSUM MP_TAC THEN
3353      ASM_REWRITE_TAC[RE_CX; IM_CX; REAL_LT_REFL];
3354      ALL_TAC] THEN
3355   ASM_SIMP_TAC[CONTINUOUS_ON_CEXP; CEXP_CLOG; CLOG_CEXP; REAL_LT_IMP_LE] THEN
3356   REPEAT CONJ_TAC THENL
3357    [REWRITE_TAC[SET_RULE `{x | p x /\ q x} = {x | p x} INTER {x | q x}`] THEN
3358     MATCH_MP_TAC OPEN_INTER THEN
3359     REWRITE_TAC[REAL_ARITH `--x < w <=> w > --x`] THEN
3360     REWRITE_TAC[OPEN_HALFSPACE_IM_LT; OPEN_HALFSPACE_IM_GT];
3361     ASM_SIMP_TAC[CLOG_WORKS];
3362     ASM_SIMP_TAC[CLOG_WORKS; REAL_LT_LE] THEN
3363     DISCH_THEN(fun th ->
3364       FIRST_X_ASSUM(SUBST_ALL_TAC o SYM o MATCH_MP CEXP_CLOG) THEN
3365       POP_ASSUM MP_TAC THEN ASSUME_TAC th) THEN
3366     ASM_REWRITE_TAC[EULER; COS_PI; SIN_PI; COMPLEX_MUL_RZERO] THEN
3367     REWRITE_TAC[COMPLEX_ADD_RID; CX_NEG; COMPLEX_MUL_RNEG] THEN
3368     REWRITE_TAC[COMPLEX_MUL_RID; IM_NEG; IM_CX; RE_NEG; RE_CX] THEN
3369     MP_TAC(SPEC `Re(clog z)` REAL_EXP_POS_LT) THEN REAL_ARITH_TAC;
3370     ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_CEXP; CEXP_CLOG]]);;
3371
3372 let COMPLEX_DIFFERENTIABLE_AT_CLOG = prove
3373  (`!z. (Im(z) = &0 ==> &0 < Re(z)) ==> clog complex_differentiable at z`,
3374   REWRITE_TAC[complex_differentiable] THEN
3375   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CLOG]);;
3376
3377 let COMPLEX_DIFFERENTIABLE_WITHIN_CLOG = prove
3378  (`!s z. (Im(z) = &0 ==> &0 < Re(z))
3379          ==> clog complex_differentiable (at z within s)`,
3380   MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN;
3381             COMPLEX_DIFFERENTIABLE_AT_CLOG]);;
3382
3383 add_complex_differentiation_theorems
3384  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
3385    (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN
3386              HAS_COMPLEX_DERIVATIVE_CLOG)));;
3387
3388 let CONTINUOUS_AT_CLOG = prove
3389  (`!z. (Im(z) = &0 ==> &0 < Re(z)) ==> clog continuous at z`,
3390   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CLOG;
3391             HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);;
3392
3393 let CONTINUOUS_WITHIN_CLOG = prove
3394  (`!s z. (Im(z) = &0 ==> &0 < Re(z)) ==> clog continuous (at z within s)`,
3395   MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CLOG]);;
3396
3397 let CONTINUOUS_ON_CLOG = prove
3398  (`!s. (!z. z IN s /\ Im(z) = &0 ==> &0 < Re(z)) ==> clog continuous_on s`,
3399   MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CLOG]);;
3400
3401 let HOLOMORPHIC_ON_CLOG = prove
3402  (`!s. (!z. z IN s /\ Im(z) = &0 ==> &0 < Re(z)) ==> clog holomorphic_on s`,
3403   REWRITE_TAC [holomorphic_on] THEN
3404   MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CLOG]);;
3405
3406 (* ------------------------------------------------------------------------- *)
3407 (* Relation to real log.                                                     *)
3408 (* ------------------------------------------------------------------------- *)
3409
3410 let CX_LOG = prove
3411  (`!z. &0 < z ==> Cx(log z) = clog(Cx z)`,
3412   REPEAT STRIP_TAC THEN FIRST_ASSUM(fun th ->
3413    GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV)
3414      [SYM(MATCH_MP EXP_LOG th)]) THEN
3415   REWRITE_TAC[CX_EXP] THEN CONV_TAC SYM_CONV THEN
3416   MATCH_MP_TAC CLOG_CEXP THEN REWRITE_TAC[IM_CX] THEN
3417   MP_TAC PI_POS THEN REAL_ARITH_TAC);;
3418
3419 (* ------------------------------------------------------------------------- *)
3420 (* Quadrant-type results for clog.                                           *)
3421 (* ------------------------------------------------------------------------- *)
3422
3423 let RE_CLOG_POS_LT = prove
3424  (`!z. ~(z = Cx(&0)) ==> (abs(Im(clog z)) < pi / &2 <=> &0 < Re(z))`,
3425   GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CLOG_WORKS) THEN
3426   DISCH_THEN(CONJUNCTS_THEN2
3427     (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SYM th])
3428     MP_TAC) THEN
3429   SIMP_TAC[RE_CEXP; REAL_LT_MUL_EQ; REAL_EXP_POS_LT] THEN
3430   SPEC_TAC(`clog z`,`z:complex`) THEN GEN_TAC THEN
3431   DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH
3432    `--p < x /\ x <= p
3433     ==> --(p / &2) < x /\ x < p / &2 \/
3434         --(p / &2) <= p + x /\ p + x <= p / &2 \/
3435         --(p / &2) <= x - p /\ x - p <= p / &2`)) THEN
3436   DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THEN
3437   (FIRST_ASSUM(MP_TAC o MATCH_MP COS_POS_PI) ORELSE
3438    FIRST_ASSUM(MP_TAC o MATCH_MP COS_POS_PI_LE)) THEN
3439   REPEAT(POP_ASSUM MP_TAC) THEN
3440   REWRITE_TAC[COS_ADD; COS_SUB; COS_PI; SIN_PI] THEN
3441   REAL_ARITH_TAC);;
3442
3443 let RE_CLOG_POS_LE = prove
3444  (`!z. ~(z = Cx(&0)) ==> (abs(Im(clog z)) <= pi / &2 <=> &0 <= Re(z))`,
3445   GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CLOG_WORKS) THEN
3446   DISCH_THEN(CONJUNCTS_THEN2
3447     (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SYM th])
3448     MP_TAC) THEN
3449   SIMP_TAC[RE_CEXP; REAL_LE_MUL_EQ; REAL_EXP_POS_LT] THEN
3450   SPEC_TAC(`clog z`,`z:complex`) THEN GEN_TAC THEN
3451   DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH
3452    `--p < x /\ x <= p
3453     ==> --(p / &2) <= x /\ x <= p / &2 \/
3454         --(p / &2) < p + x /\ p + x < p / &2 \/
3455         --(p / &2) < x - p /\ x - p < p / &2`)) THEN
3456   DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THEN
3457   (FIRST_ASSUM(MP_TAC o MATCH_MP COS_POS_PI) ORELSE
3458    FIRST_ASSUM(MP_TAC o MATCH_MP COS_POS_PI_LE)) THEN
3459   REPEAT(POP_ASSUM MP_TAC) THEN
3460   REWRITE_TAC[COS_ADD; COS_SUB; COS_PI; SIN_PI] THEN
3461   REAL_ARITH_TAC);;
3462
3463 let IM_CLOG_POS_LT = prove
3464  (`!z. ~(z = Cx(&0)) ==> (&0 < Im(clog z) /\ Im(clog z) < pi <=> &0 < Im(z))`,
3465   GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CLOG_WORKS) THEN
3466   DISCH_THEN(CONJUNCTS_THEN2
3467     (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SYM th])
3468     MP_TAC) THEN
3469   SIMP_TAC[IM_CEXP; REAL_LT_MUL_EQ; REAL_EXP_POS_LT] THEN
3470   SPEC_TAC(`clog z`,`z:complex`) THEN GEN_TAC THEN
3471   DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH
3472    `--p < x /\ x <= p
3473     ==> &0 < x /\ x < p \/
3474         &0 <= x + p /\ x + p <= p \/
3475         &0 <= x - p /\ x - p <= p`)) THEN
3476   DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THEN
3477   (FIRST_ASSUM(MP_TAC o MATCH_MP SIN_POS_PI) ORELSE
3478    FIRST_ASSUM(MP_TAC o MATCH_MP SIN_POS_PI_LE)) THEN
3479   REPEAT(POP_ASSUM MP_TAC) THEN
3480   REWRITE_TAC[SIN_ADD; SIN_SUB; COS_PI; SIN_PI] THEN
3481   REAL_ARITH_TAC);;
3482
3483 let IM_CLOG_POS_LE = prove
3484  (`!z. ~(z = Cx(&0)) ==> (&0 <= Im(clog z) <=> &0 <= Im(z))`,
3485   GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CLOG_WORKS) THEN
3486   DISCH_THEN(CONJUNCTS_THEN2
3487     (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SYM th])
3488     MP_TAC) THEN
3489   SIMP_TAC[IM_CEXP; REAL_LE_MUL_EQ; REAL_EXP_POS_LT] THEN
3490   SPEC_TAC(`clog z`,`z:complex`) THEN GEN_TAC THEN
3491   DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH
3492    `--p < x /\ x <= p
3493     ==> &0 <= x /\ x <= p \/
3494         &0 < x + p /\ x + p < p \/
3495         &0 < p - x /\ p - x < p`)) THEN
3496   DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THEN
3497   (FIRST_ASSUM(MP_TAC o MATCH_MP SIN_POS_PI) ORELSE
3498    FIRST_ASSUM(MP_TAC o MATCH_MP SIN_POS_PI_LE)) THEN
3499   REPEAT(POP_ASSUM MP_TAC) THEN
3500   REWRITE_TAC[SIN_ADD; SIN_SUB; COS_PI; SIN_PI] THEN
3501   REAL_ARITH_TAC);;
3502
3503 let RE_CLOG_POS_LT_IMP = prove
3504  (`!z. &0 < Re(z) ==> abs(Im(clog z)) < pi / &2`,
3505   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN
3506   ASM_SIMP_TAC[RE_CLOG_POS_LT; RE_CX; REAL_LT_REFL]);;
3507
3508 let IM_CLOG_POS_LT_IMP = prove
3509  (`!z. &0 < Im(z) ==> &0 < Im(clog z) /\ Im(clog z) < pi`,
3510   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN
3511   ASM_SIMP_TAC[IM_CLOG_POS_LT; IM_CX; REAL_LT_REFL]);;
3512
3513 let IM_CLOG_EQ_0 = prove
3514  (`!z. ~(z = Cx(&0)) ==> (Im(clog z) = &0 <=> &0 < Re(z) /\ Im(z) = &0)`,
3515   REPEAT STRIP_TAC THEN
3516   GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV)
3517    [REAL_ARITH `z = &0 <=> &0 <= z /\ ~(&0 < z)`] THEN
3518   ASM_SIMP_TAC[GSYM RE_CLOG_POS_LT; GSYM IM_CLOG_POS_LE;
3519                GSYM IM_CLOG_POS_LT] THEN
3520   MP_TAC PI_POS THEN REAL_ARITH_TAC);;
3521
3522 let IM_CLOG_EQ_PI = prove
3523  (`!z. ~(z = Cx(&0)) ==> (Im(clog z) = pi <=> Re(z) < &0 /\ Im(z) = &0)`,
3524   SIMP_TAC[PI_POS; RE_CLOG_POS_LE; IM_CLOG_POS_LE; IM_CLOG_POS_LT; CLOG_WORKS;
3525            REAL_ARITH `&0 < pi ==> (x = pi <=> (&0 <= x /\ x <= pi) /\
3526                             ~(abs x <= pi / &2) /\ ~(&0 < x /\ x < pi))`] THEN
3527   REAL_ARITH_TAC);;
3528
3529 (* ------------------------------------------------------------------------- *)
3530 (* Various properties.                                                       *)
3531 (* ------------------------------------------------------------------------- *)
3532
3533 let CNJ_CLOG = prove
3534  (`!z. (Im z = &0 ==> &0 < Re z) ==> cnj(clog z) = clog(cnj z)`,
3535   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN
3536   ASM_REWRITE_TAC[RE_CX; IM_CX; REAL_LT_REFL] THEN
3537   DISCH_TAC THEN MATCH_MP_TAC COMPLEX_EQ_CEXP THEN
3538   REWRITE_TAC[GSYM CNJ_CEXP] THEN
3539   ASM_SIMP_TAC[CEXP_CLOG; CNJ_EQ_CX; IM_CNJ] THEN
3540   MATCH_MP_TAC(REAL_ARITH
3541    `(--p < x /\ x <= p) /\ (--p < y /\ y <= p) /\
3542     ~(x = p /\ y = p)
3543     ==> abs(--x - y) < &2 * p`) THEN
3544   ASM_SIMP_TAC[IM_CLOG_EQ_PI; CNJ_EQ_CX; CLOG_WORKS] THEN
3545   ASM_REAL_ARITH_TAC);;
3546
3547 let CLOG_INV = prove
3548  (`!z. (Im(z) = &0 ==> &0 < Re z) ==> clog(inv z) = --(clog z)`,
3549   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN
3550   ASM_REWRITE_TAC[RE_CX; IM_CX; REAL_LT_REFL] THEN
3551   STRIP_TAC THEN MATCH_MP_TAC COMPLEX_EQ_CEXP THEN
3552   ASM_SIMP_TAC[CEXP_CLOG; CEXP_NEG; COMPLEX_INV_EQ_0] THEN
3553   REWRITE_TAC[IM_NEG; REAL_SUB_RNEG] THEN
3554   MATCH_MP_TAC(REAL_ARITH
3555    `--pi < x /\ x <= pi /\ --pi < y /\ y <= pi /\
3556     ~(x = pi /\ y = pi) ==> abs(x + y) < &2 * pi`) THEN
3557   ASM_SIMP_TAC[CLOG_WORKS; COMPLEX_INV_EQ_0; IM_CLOG_EQ_PI] THEN
3558   UNDISCH_TAC `Im z = &0 ==> &0 < Re z` THEN
3559   ASM_CASES_TAC `Im z = &0` THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
3560
3561 let CLOG_1 = prove
3562  (`clog(Cx(&1)) = Cx(&0)`,
3563   REWRITE_TAC[GSYM CEXP_0] THEN MATCH_MP_TAC CLOG_CEXP THEN
3564   REWRITE_TAC[IM_CX] THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);;
3565
3566 let CLOG_NEG_1 = prove
3567  (`clog(--Cx(&1)) = ii * Cx pi`,
3568   MATCH_MP_TAC COMPLEX_EQ_CEXP THEN REWRITE_TAC[GSYM CX_NEG] THEN
3569   SIMP_TAC[CEXP_EULER; GSYM CX_COS; GSYM CX_SIN; IM_MUL_II; IM_CX; RE_CX] THEN
3570   REWRITE_TAC[COS_PI; SIN_PI; COMPLEX_MUL_RZERO; COMPLEX_ADD_RID] THEN
3571   SIMP_TAC[CLOG_WORKS; COMPLEX_RING `~(Cx(-- &1) = Cx(&0))`;
3572            REAL_ARITH `--pi < x /\ x <= pi ==> abs(x - pi) < &2 * pi`]);;
3573
3574 let CLOG_II = prove
3575  (`clog ii = ii * Cx(pi / &2)`,
3576   MP_TAC(SPEC `ii * Cx(pi / &2)` CLOG_CEXP) THEN
3577   SIMP_TAC[CEXP_EULER; GSYM CX_COS; GSYM CX_SIN; IM_MUL_II; IM_CX; RE_CX] THEN
3578   REWRITE_TAC[COS_PI2; SIN_PI2] THEN ANTS_TAC THENL
3579    [MP_TAC PI_POS THEN REAL_ARITH_TAC;
3580     REWRITE_TAC[COMPLEX_ADD_LID; COMPLEX_MUL_RID]]);;
3581
3582 let CLOG_NEG_II = prove
3583  (`clog(--ii) = --ii * Cx(pi / &2)`,
3584   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [COMPLEX_FIELD `--ii = inv ii`] THEN
3585   SIMP_TAC[CLOG_INV; RE_II; IM_II; REAL_OF_NUM_EQ; ARITH; CLOG_II] THEN
3586   REWRITE_TAC[COMPLEX_MUL_LNEG]);;
3587
3588 (* ------------------------------------------------------------------------- *)
3589 (* Relation between square root and exp/log, and hence its derivative.       *)
3590 (* ------------------------------------------------------------------------- *)
3591
3592 let CSQRT_CEXP_CLOG = prove
3593  (`!z. ~(z = Cx(&0)) ==> csqrt z = cexp(clog(z) / Cx(&2))`,
3594   REPEAT STRIP_TAC THEN MATCH_MP_TAC CSQRT_UNIQUE THEN
3595   REWRITE_TAC[GSYM CEXP_N; RE_CEXP; IM_CEXP] THEN
3596   ASM_SIMP_TAC[COMPLEX_DIV_LMUL; CX_INJ; REAL_OF_NUM_EQ; ARITH; CEXP_CLOG] THEN
3597   SIMP_TAC[REAL_LT_MUL_EQ; REAL_EXP_POS_LT; REAL_LE_MUL_EQ] THEN
3598   REWRITE_TAC[REAL_ENTIRE; REAL_EXP_NZ; IM_DIV_CX] THEN
3599   FIRST_ASSUM(STRIP_ASSUME_TAC o CONJUNCT2 o MATCH_MP CLOG_WORKS) THEN
3600   FIRST_X_ASSUM(DISJ_CASES_TAC o REWRITE_RULE[REAL_LE_LT]) THENL
3601    [DISJ1_TAC THEN MATCH_MP_TAC COS_POS_PI THEN
3602     ASM_REAL_ARITH_TAC;
3603     DISJ2_TAC THEN ASM_REWRITE_TAC[COS_PI2; SIN_PI2; REAL_POS]]);;
3604
3605 let CNJ_CSQRT = prove
3606  (`!z. (Im z = &0 ==> &0 <= Re(z)) ==> cnj(csqrt z) = csqrt(cnj z)`,
3607   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN
3608   ASM_REWRITE_TAC[CSQRT_0; CNJ_CX] THEN DISCH_TAC THEN
3609   SUBGOAL_THEN `Im z = &0 ==> &0 < Re(z)` ASSUME_TAC THENL
3610    [REPEAT(POP_ASSUM MP_TAC) THEN
3611     REWRITE_TAC[COMPLEX_EQ; IM_CX; RE_CX] THEN REAL_ARITH_TAC;
3612     ASM_REWRITE_TAC[RE_CX; IM_CX; REAL_LT_REFL] THEN
3613     ASM_SIMP_TAC[CSQRT_CEXP_CLOG; CNJ_CEXP; CNJ_CLOG;
3614                  CNJ_DIV; CNJ_EQ_CX; CNJ_CX]]);;
3615
3616 let HAS_COMPLEX_DERIVATIVE_CSQRT = prove
3617  (`!z. (Im z = &0 ==> &0 < Re(z))
3618        ==> (csqrt has_complex_derivative inv(Cx(&2) * csqrt z)) (at z)`,
3619   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN
3620   ASM_REWRITE_TAC[IM_CX; RE_CX; REAL_LT_REFL] THEN DISCH_TAC THEN
3621   MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_AT THEN
3622   MAP_EVERY EXISTS_TAC [`\z. cexp(clog(z) / Cx(&2))`; `norm(z:complex)`] THEN
3623   ASM_REWRITE_TAC[COMPLEX_NORM_NZ] THEN CONJ_TAC THENL
3624    [REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
3625     MATCH_MP_TAC CSQRT_CEXP_CLOG THEN REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN
3626     REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC;
3627     COMPLEX_DIFF_TAC THEN ASM_SIMP_TAC[GSYM CSQRT_CEXP_CLOG] THEN
3628     UNDISCH_TAC `~(z = Cx(&0))` THEN MP_TAC(SPEC `z:complex` CSQRT) THEN
3629     CONV_TAC COMPLEX_FIELD]);;
3630
3631 let COMPLEX_DIFFERENTIABLE_AT_CSQRT = prove
3632  (`!z. (Im z = &0 ==> &0 < Re(z)) ==> csqrt complex_differentiable at z`,
3633   REWRITE_TAC[complex_differentiable] THEN
3634   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CSQRT]);;
3635
3636 let COMPLEX_DIFFERENTIABLE_WITHIN_CSQRT = prove
3637  (`!s z. (Im z = &0 ==> &0 < Re(z))
3638          ==> csqrt complex_differentiable (at z within s)`,
3639   MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN;
3640             COMPLEX_DIFFERENTIABLE_AT_CSQRT]);;
3641
3642 add_complex_differentiation_theorems
3643  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
3644    (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN
3645              HAS_COMPLEX_DERIVATIVE_CSQRT)));;
3646
3647 let CONTINUOUS_AT_CSQRT = prove
3648  (`!z. (Im z = &0 ==> &0 < Re(z)) ==> csqrt continuous at z`,
3649   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CSQRT;
3650             HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);;
3651
3652 let CONTINUOUS_WITHIN_CSQRT = prove
3653  (`!s z. (Im z = &0 ==> &0 < Re(z)) ==> csqrt continuous (at z within s)`,
3654   MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CSQRT]);;
3655
3656 let CONTINUOUS_ON_CSQRT = prove
3657  (`!s. (!z. z IN s /\ Im z = &0 ==> &0 < Re(z)) ==> csqrt continuous_on s`,
3658   MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CSQRT]);;
3659
3660 let HOLOMORPHIC_ON_CSQRT = prove
3661  (`!s. (!z. z IN s /\ Im(z) = &0 ==> &0 < Re(z)) ==> csqrt holomorphic_on s`,
3662   REWRITE_TAC [holomorphic_on] THEN
3663   MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CSQRT]);;
3664
3665 let CONTINUOUS_WITHIN_CSQRT_POSREAL = prove
3666  (`!z. csqrt continuous (at z within {w | real w /\ &0 <= Re(w)})`,
3667   REPEAT STRIP_TAC THEN ASM_CASES_TAC `Im z = &0 ==> &0 < Re(z)` THENL
3668    [ASM_SIMP_TAC[CONTINUOUS_WITHIN_CSQRT]; ALL_TAC] THEN
3669   POP_ASSUM MP_TAC THEN REWRITE_TAC[NOT_IMP; REAL_NOT_LT] THEN
3670   REWRITE_TAC[REAL_ARITH `x <= &0 <=> x < &0 \/ x = &0`] THEN STRIP_TAC THENL
3671    [MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN
3672     REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
3673     SIMP_TAC[CLOSED_REAL_SET; CLOSED_INTER; IN_INTER; IN_ELIM_THM;
3674              REWRITE_RULE[real_ge] CLOSED_HALFSPACE_RE_GE] THEN
3675     ASM_REAL_ARITH_TAC;
3676     SUBGOAL_THEN `z = Cx(&0)` SUBST_ALL_TAC THENL
3677      [ASM_REWRITE_TAC[COMPLEX_EQ; RE_CX; IM_CX]; ALL_TAC] THEN
3678     REWRITE_TAC[continuous_within] THEN
3679     REWRITE_TAC[IN_ELIM_THM; IMP_CONJ; FORALL_REAL; RE_CX] THEN
3680     SIMP_TAC[GSYM CX_SQRT; REAL_LE_REFL] THEN
3681     SIMP_TAC[dist; GSYM CX_SUB; COMPLEX_NORM_CX; SQRT_0; REAL_SUB_RZERO] THEN
3682     X_GEN_TAC `e:real` THEN STRIP_TAC THEN EXISTS_TAC `(e:real) pow 2` THEN
3683     ASM_SIMP_TAC[REAL_POW_LT] THEN REPEAT STRIP_TAC THEN
3684     SUBGOAL_THEN `e = sqrt(e pow 2)` SUBST1_TAC THENL
3685      [ASM_SIMP_TAC[POW_2_SQRT; REAL_LT_IMP_LE];
3686       ASM_SIMP_TAC[real_abs; SQRT_POS_LE]] THEN
3687     MATCH_MP_TAC SQRT_MONO_LT THEN ASM_REAL_ARITH_TAC]);;
3688
3689 (* ------------------------------------------------------------------------- *)
3690 (* Complex powers.                                                           *)
3691 (* ------------------------------------------------------------------------- *)
3692
3693 parse_as_infix("cpow",(24,"left"));;
3694
3695 let cpow = new_definition
3696  `w cpow z = if w = Cx(&0) then Cx(&0)
3697              else cexp(z * clog w)`;;
3698
3699 let CPOW_0 = prove
3700  (`!z. Cx(&0) cpow z = Cx(&0)`,
3701   REWRITE_TAC[cpow]);;
3702
3703 let CPOW_N = prove
3704  (`!z. z cpow (Cx(&n)) = if z = Cx(&0) then Cx(&0) else z pow n`,
3705   GEN_TAC THEN REWRITE_TAC[cpow] THEN COND_CASES_TAC THEN
3706   ASM_SIMP_TAC[CEXP_N; CEXP_CLOG]);;
3707
3708 let CPOW_1 = prove
3709  (`!z. Cx(&1) cpow z = Cx(&1)`,
3710   REWRITE_TAC[cpow; CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ; CLOG_1] THEN
3711   REWRITE_TAC[CEXP_0; COMPLEX_MUL_RZERO]);;
3712
3713 let CPOW_ADD = prove
3714  (`!w z1 z2. w cpow (z1 + z2) = w cpow z1 * w cpow z2`,
3715   REPEAT GEN_TAC THEN REWRITE_TAC[cpow] THEN
3716   ASM_CASES_TAC `w = Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_MUL_RZERO] THEN
3717   REWRITE_TAC[COMPLEX_ADD_RDISTRIB; CEXP_ADD]);;
3718
3719 let CPOW_NEG = prove
3720  (`!w z. w cpow (--z) = inv(w cpow z)`,
3721   REPEAT GEN_TAC THEN REWRITE_TAC[cpow] THEN ASM_CASES_TAC `w = Cx(&0)` THEN
3722   ASM_REWRITE_TAC[COMPLEX_MUL_RZERO; COMPLEX_INV_0] THEN
3723   REWRITE_TAC[COMPLEX_MUL_LNEG; CEXP_NEG]);;
3724
3725 let CPOW_SUB = prove
3726  (`!w z1 z2. w cpow (z1 - z2) = w cpow z1 / w cpow z2`,
3727   REWRITE_TAC[complex_sub; complex_div; CPOW_ADD; CPOW_NEG]);;
3728
3729 let CPOW_EQ_0 = prove
3730  (`!w z. w cpow z = Cx(&0) <=> w = Cx(&0)`,
3731   REPEAT GEN_TAC THEN REWRITE_TAC[cpow] THEN
3732   COND_CASES_TAC THEN ASM_REWRITE_TAC[CEXP_NZ]);;
3733
3734 let NORM_CPOW_REAL = prove
3735  (`!w z. real w /\ &0 < Re w ==> norm(w cpow z) = exp(Re z * log(Re w))`,
3736   REPEAT STRIP_TAC THEN
3737   FIRST_X_ASSUM(SUBST_ALL_TAC o SYM o GEN_REWRITE_RULE I [REAL]) THEN
3738   RULE_ASSUM_TAC(REWRITE_RULE[RE_CX]) THEN
3739   ASM_SIMP_TAC[cpow; CX_INJ; REAL_LT_IMP_NZ] THEN
3740   ASM_SIMP_TAC[NORM_CEXP; GSYM CX_LOG; RE_MUL_CX; RE_CX]);;
3741
3742 let CPOW_REAL_REAL = prove
3743  (`!w z. real w /\ real z /\ &0 < Re w
3744          ==> w cpow z = Cx(exp(Re z * log(Re w)))`,
3745   REPEAT STRIP_TAC THEN
3746   REPEAT(FIRST_X_ASSUM(SUBST_ALL_TAC o SYM o GEN_REWRITE_RULE I [REAL])) THEN
3747   RULE_ASSUM_TAC(REWRITE_RULE[RE_CX]) THEN
3748   ASM_SIMP_TAC[cpow; CX_INJ; REAL_LT_IMP_NZ] THEN
3749   ASM_SIMP_TAC[NORM_CEXP; GSYM CX_LOG; RE_MUL_CX; RE_CX; CX_EXP; CX_MUL]);;
3750
3751 let NORM_CPOW_REAL_MONO = prove
3752  (`!w z1 z2. real w /\ &1 < Re w
3753              ==> (norm(w cpow z1) <= norm(w cpow z2) <=> Re(z1) <= Re(z2))`,
3754   SIMP_TAC[NORM_CPOW_REAL; REAL_ARITH `&1 < x ==> &0 < x`] THEN
3755   SIMP_TAC[REAL_EXP_MONO_LE; REAL_LE_RMUL_EQ; LOG_POS_LT]);;
3756
3757 let CPOW_MUL_REAL = prove
3758  (`!x y z. real x /\ real y /\ &0 <= Re x /\ &0 <= Re y
3759            ==> (x * y) cpow z = x cpow z * y cpow z`,
3760   REPEAT STRIP_TAC THEN
3761   REPEAT(FIRST_X_ASSUM(SUBST_ALL_TAC o SYM o GEN_REWRITE_RULE I [REAL])) THEN
3762   REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[RE_CX; IM_CX] THEN
3763   REWRITE_TAC[REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN
3764   REPEAT STRIP_TAC THEN
3765   ASM_REWRITE_TAC[COMPLEX_MUL_LZERO; COMPLEX_MUL_RZERO; CPOW_0] THEN
3766   ASM_SIMP_TAC[cpow; COMPLEX_ENTIRE; CX_INJ; REAL_LT_IMP_NZ] THEN
3767   REWRITE_TAC[GSYM CEXP_ADD; GSYM COMPLEX_ADD_LDISTRIB] THEN
3768   ASM_SIMP_TAC[GSYM CX_LOG; GSYM CX_ADD; GSYM CX_MUL; REAL_LT_MUL] THEN
3769   ASM_SIMP_TAC[LOG_MUL]);;
3770
3771 let HAS_COMPLEX_DERIVATIVE_CPOW = prove
3772  (`!s z. (Im z = &0 ==> &0 < Re z)
3773          ==> ((\z. z cpow s) has_complex_derivative
3774               (s * z cpow (s - Cx(&1)))) (at z)`,
3775   REPEAT GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN
3776   ASM_REWRITE_TAC[IM_CX; RE_CX; REAL_LT_REFL] THEN
3777   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[cpow] THEN
3778   MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_AT THEN
3779   MAP_EVERY EXISTS_TAC [`\z. cexp (s * clog z)`; `norm(z:complex)`] THEN
3780   ASM_REWRITE_TAC[COMPLEX_NORM_NZ] THEN CONJ_TAC THENL
3781    [GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[dist] THEN
3782     REWRITE_TAC[COMPLEX_SUB_LZERO; NORM_NEG; REAL_LT_REFL];
3783     COMPLEX_DIFF_TAC THEN ASM_REWRITE_TAC[CEXP_SUB; COMPLEX_SUB_RDISTRIB] THEN
3784     ASM_SIMP_TAC[CEXP_CLOG; COMPLEX_MUL_LID] THEN
3785     REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC COMPLEX_FIELD]);;
3786
3787 add_complex_differentiation_theorems
3788  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
3789    (GEN `s:complex`
3790      (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN
3791                (SPEC `s:complex` HAS_COMPLEX_DERIVATIVE_CPOW)))));;
3792
3793 let HAS_COMPLEX_DERIVATIVE_CPOW_RIGHT = prove
3794  (`!w z. ~(w = Cx(&0))
3795          ==> ((\z. w cpow z) has_complex_derivative clog(w) * w cpow z) (at z)`,
3796   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[cpow] THEN
3797   COMPLEX_DIFF_TAC THEN REWRITE_TAC[COMPLEX_MUL_LID]);;
3798
3799 add_complex_differentiation_theorems
3800  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
3801    (GEN `s:complex`
3802      (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN
3803                (SPEC `s:complex` HAS_COMPLEX_DERIVATIVE_CPOW_RIGHT)))));;
3804
3805 let COMPLEX_DIFFERENTIABLE_CPOW_RIGHT = prove
3806  (`!w z. ~(w = Cx(&0)) ==> (\z. w cpow z) complex_differentiable (at z)`,
3807   REWRITE_TAC[complex_differentiable] THEN
3808   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CPOW_RIGHT]);;
3809
3810 let HOLOMORPHIC_ON_CPOW_RIGHT = prove
3811  (`!w f s. ~(w = Cx(&0)) /\ f holomorphic_on s
3812            ==> (\z. w cpow (f z)) holomorphic_on s`,
3813   REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
3814   MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN
3815   GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN
3816   REWRITE_TAC[holomorphic_on; GSYM complex_differentiable] THEN
3817   ASM_SIMP_TAC[COMPLEX_DIFFERENTIABLE_CPOW_RIGHT;
3818                COMPLEX_DIFFERENTIABLE_AT_WITHIN]);;
3819
3820 (* ------------------------------------------------------------------------- *)
3821 (* Product rule.                                                             *)
3822 (* ------------------------------------------------------------------------- *)
3823
3824 let CLOG_MUL = prove
3825  (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0))
3826            ==> clog(w * z) =
3827                 if Im(clog w + clog z) <= --pi then
3828                   (clog(w) + clog(z)) + ii * Cx(&2 * pi)
3829                 else if Im(clog w + clog z) > pi then
3830                   (clog(w) + clog(z)) - ii * Cx(&2 * pi)
3831                 else clog(w) + clog(z)`,
3832   REPEAT STRIP_TAC THEN
3833   REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN
3834   MATCH_MP_TAC CLOG_UNIQUE THEN
3835   ASM_SIMP_TAC[CEXP_ADD; CEXP_SUB; CEXP_EULER; CEXP_CLOG; CONJ_ASSOC;
3836                GSYM CX_SIN; GSYM CX_COS; COS_NPI; SIN_NPI] THEN
3837   CONV_TAC REAL_RAT_REDUCE_CONV THEN
3838   TRY(CONJ_TAC THENL [ALL_TAC; CONV_TAC COMPLEX_FIELD]) THEN
3839   REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOG_WORKS)) THEN
3840   REPEAT(POP_ASSUM MP_TAC) THEN
3841   REWRITE_TAC[IM_ADD; IM_SUB; IM_MUL_II; RE_CX] THEN
3842   REAL_ARITH_TAC);;
3843
3844 let CLOG_MUL_SIMPLE = prove
3845  (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0)) /\
3846          --pi < Im(clog(w)) + Im(clog(z)) /\
3847          Im(clog(w)) + Im(clog(z)) <= pi
3848          ==> clog(w * z) = clog(w) + clog(z)`,
3849   SIMP_TAC[CLOG_MUL; IM_ADD] THEN REAL_ARITH_TAC);;
3850
3851 let CLOG_NEG = prove
3852  (`!z. ~(z = Cx(&0))
3853        ==> clog(--z) = if Im(z) <= &0 /\ ~(Re(z) < &0 /\ Im(z) = &0)
3854                        then clog(z) + ii * Cx(pi)
3855                        else clog(z) - ii * Cx(pi)`,
3856   REPEAT STRIP_TAC THEN
3857   SUBST1_TAC(SIMPLE_COMPLEX_ARITH `--z = --Cx(&1) * z`) THEN
3858   ASM_SIMP_TAC[CLOG_MUL; COMPLEX_RING `~(--Cx(&1) = Cx(&0))`] THEN
3859   REWRITE_TAC[CLOG_NEG_1; IM_ADD; IM_MUL_II; RE_CX] THEN
3860   ASM_SIMP_TAC[CLOG_WORKS; REAL_ARITH
3861    `--p < x /\ x <= p ==> ~(p + x <= --p)`] THEN
3862   REWRITE_TAC[REAL_ARITH `p + x > p <=> &0 < x`] THEN
3863   ASM_SIMP_TAC[GSYM IM_CLOG_EQ_PI] THEN
3864   ONCE_REWRITE_TAC[REAL_ARITH `Im z <= &0 <=> ~(&0 < Im z)`] THEN
3865   ASM_SIMP_TAC[GSYM IM_CLOG_POS_LT] THEN
3866   ASM_SIMP_TAC[CLOG_WORKS; REAL_ARITH `x <= p ==> (x < p <=> ~(x = p))`] THEN
3867   REWRITE_TAC[TAUT `~(a /\ ~b) /\ ~b <=> ~a /\ ~b`] THEN
3868   ASM_CASES_TAC `Im(clog z) = pi` THEN ASM_REWRITE_TAC[PI_POS] THEN
3869   ASM_CASES_TAC `&0 < Im(clog z)` THEN ASM_REWRITE_TAC[] THEN
3870   REWRITE_TAC[CX_MUL] THEN CONV_TAC COMPLEX_RING);;
3871
3872 let CLOG_MUL_II = prove
3873  (`!z. ~(z = Cx(&0))
3874        ==> clog(ii * z) = if &0 <= Re(z) \/ Im(z) < &0
3875                           then clog(z) + ii * Cx(pi / &2)
3876                           else clog(z) - ii * Cx(&3 * pi / &2)`,
3877   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[CLOG_MUL; II_NZ; CLOG_II] THEN
3878   REWRITE_TAC[IM_ADD; IM_MUL_II; RE_CX] THEN
3879   ASM_SIMP_TAC[CLOG_WORKS; REAL_ARITH
3880    `--p < x /\ x <= p ==> ~(p / &2 + x <= --p)`] THEN
3881   REWRITE_TAC[REAL_ARITH `p / &2 + x > p <=> p / &2 < x`] THEN
3882   REWRITE_TAC[REAL_ARITH `Im z < &0 <=> ~(&0 <= Im z)`] THEN
3883   ASM_SIMP_TAC[GSYM RE_CLOG_POS_LE; GSYM IM_CLOG_POS_LE] THEN
3884   MATCH_MP_TAC(MESON[]
3885    `(p <=> ~q) /\ x = a /\ y = b
3886     ==> ((if p then x else y) = (if q then b else a))`) THEN
3887   CONJ_TAC THENL
3888    [MP_TAC PI_POS THEN REAL_ARITH_TAC;
3889     REWRITE_TAC[CX_MUL; CX_DIV] THEN CONV_TAC COMPLEX_RING]);;
3890
3891 (* ------------------------------------------------------------------------- *)
3892 (* Unwinding number gives another version of log-product formula.            *)
3893 (* Note that in this special case the unwinding number is -1, 0 or 1.        *)
3894 (* ------------------------------------------------------------------------- *)
3895
3896 let unwinding = new_definition
3897  `unwinding(z) = (z - clog(cexp z)) / (Cx(&2 * pi) * ii)`;;
3898
3899 let UNWINDING_2PI = prove
3900  (`Cx(&2 * pi) * ii * unwinding(z) = z - clog(cexp z)`,
3901   REWRITE_TAC[unwinding; COMPLEX_MUL_ASSOC] THEN
3902   MATCH_MP_TAC COMPLEX_DIV_LMUL THEN
3903   REWRITE_TAC[COMPLEX_ENTIRE; CX_INJ; II_NZ] THEN
3904   MP_TAC PI_POS THEN REAL_ARITH_TAC);;
3905
3906 let CLOG_MUL_UNWINDING = prove
3907  (`!w z. ~(w = Cx(&0)) /\ ~(z = Cx(&0))
3908            ==> clog(w * z) =
3909                clog(w) + clog(z) -
3910                Cx(&2 * pi) * ii * unwinding(clog w + clog z)`,
3911   REWRITE_TAC[UNWINDING_2PI;
3912     COMPLEX_RING `w + z - ((w + z) - c) = c:complex`] THEN
3913   ASM_SIMP_TAC[CEXP_ADD; CEXP_CLOG]);;
3914
3915 (* ------------------------------------------------------------------------- *)
3916 (* Complex arctangent (branch cut gives standard bounds in real case).       *)
3917 (* ------------------------------------------------------------------------- *)
3918
3919 let catn = new_definition
3920  `catn z = (ii / Cx(&2)) * clog((Cx(&1) - ii * z) / (Cx(&1) + ii * z))`;;
3921
3922 let IM_COMPLEX_DIV_LEMMA = prove
3923  (`!z. Im((Cx(&1) - ii * z) / (Cx(&1) + ii * z)) = &0 <=> Re z = &0`,
3924   REWRITE_TAC[IM_COMPLEX_DIV_EQ_0] THEN
3925   REWRITE_TAC[complex_mul;  IM; RE; IM_CNJ; RE_CNJ; RE_CX; IM_CX; RE_II; IM_II;
3926               RE_SUB; RE_ADD; IM_SUB; IM_ADD] THEN
3927   REAL_ARITH_TAC);;
3928
3929 let RE_COMPLEX_DIV_LEMMA = prove
3930  (`!z. &0 < Re((Cx(&1) - ii * z) / (Cx(&1) + ii * z)) <=> norm(z) < &1`,
3931   REWRITE_TAC[RE_COMPLEX_DIV_GT_0; NORM_LT_SQUARE; REAL_LT_01] THEN
3932   REWRITE_TAC[GSYM NORM_POW_2; COMPLEX_SQNORM] THEN
3933   REWRITE_TAC[complex_mul;  IM; RE; IM_CNJ; RE_CNJ; RE_CX; IM_CX; RE_II; IM_II;
3934               RE_SUB; RE_ADD; IM_SUB; IM_ADD] THEN
3935   REAL_ARITH_TAC);;
3936
3937 let CTAN_CATN = prove
3938  (`!z. ~(z pow 2 = --Cx(&1)) ==> ctan(catn z) = z`,
3939   REPEAT STRIP_TAC THEN
3940   REWRITE_TAC[catn; ctan; csin; ccos;
3941               COMPLEX_RING `--i * i / Cx(&2) * z = --(i * i) / Cx(&2) * z`;
3942               COMPLEX_RING `i * i / Cx(&2) * z =  (i * i) / Cx(&2) * z`] THEN
3943   REWRITE_TAC[COMPLEX_POW_II_2; GSYM COMPLEX_POW_2] THEN
3944   REWRITE_TAC[COMPLEX_RING `--Cx(&1) / Cx(&2) * x = --(Cx(&1) / Cx(&2) * x)`;
3945               CEXP_NEG] THEN
3946   SUBGOAL_THEN
3947   `~(cexp(Cx(&1) / Cx(&2) *
3948           (clog((Cx(&1) - ii * z) / (Cx(&1) + ii * z)))) pow 2 = --Cx(&1))`
3949   ASSUME_TAC THENL
3950    [REWRITE_TAC[GSYM CEXP_N; CEXP_SUB; COMPLEX_RING
3951      `Cx(&2) * Cx(&1) / Cx(&2) * z = z`] THEN
3952     ASM_SIMP_TAC[CEXP_CLOG; COMPLEX_POW_II_2;
3953       COMPLEX_FIELD `~(w = Cx(&0)) /\ ~(z = Cx(&0)) ==> ~(w / z = Cx(&0))`;
3954       COMPLEX_FIELD `~(w = Cx(&0)) ==> (x / w = y <=> x = y * w)`;
3955       COMPLEX_FIELD
3956      `ii pow 2 = --Cx(&1) /\ ~(z pow 2 = --Cx(&1))
3957       ==> ~(Cx(&1) - ii * z = Cx(&0)) /\ ~(Cx(&1) + ii * z = Cx(&0))`] THEN
3958     POP_ASSUM MP_TAC THEN CONV_TAC COMPLEX_FIELD;
3959     ALL_TAC] THEN
3960   REWRITE_TAC[COMPLEX_RING `-- --Cx (&1) / Cx (&2) = Cx(&1) / Cx(&2)`] THEN
3961   ASM_SIMP_TAC[CEXP_NZ; COMPLEX_FIELD
3962     `~(z = Cx(&0)) /\ ~(z pow 2 = --Cx(&1))
3963      ==> ((inv(z) - z) / (Cx(&2) * ii)) / ((inv(z) + z) / Cx(&2)) =
3964          inv ii * ((Cx(&1) - z pow 2) / (Cx(&1) + z pow 2))`] THEN
3965   ASM_SIMP_TAC[GSYM CEXP_N; CEXP_SUB;
3966                COMPLEX_RING `Cx(&2) * Cx(&1) / Cx(&2) * z = z`] THEN
3967   ASM_SIMP_TAC[CEXP_CLOG; COMPLEX_FIELD
3968      `~(z pow 2 = --Cx(&1))
3969       ==> ~((Cx(&1) - ii * z) / (Cx(&1) + ii * z) = Cx(&0))`] THEN
3970   UNDISCH_TAC `~(z pow 2 = --Cx(&1))` THEN CONV_TAC COMPLEX_FIELD);;
3971
3972 let CATN_CTAN = prove
3973  (`!z. abs(Re z) < pi / &2 ==> catn(ctan z) = z`,
3974   REPEAT STRIP_TAC THEN REWRITE_TAC[catn; ctan; csin; ccos] THEN
3975   ASM_SIMP_TAC[COMPLEX_FIELD
3976    `ii * (a / (Cx(&2) * ii)) / (b / Cx(&2)) = a / b`] THEN
3977   SIMP_TAC[COMPLEX_FIELD
3978    `ii / Cx(&2) * x = y <=> x = Cx(&2) * --(ii * y)`] THEN
3979   SUBGOAL_THEN `~(cexp(ii * z) pow 2 = --Cx(&1))` ASSUME_TAC THENL
3980    [SUBGOAL_THEN `--Cx(&1) = cexp(ii * Cx pi)` SUBST1_TAC THENL
3981      [REWRITE_TAC[CEXP_EULER; GSYM CX_SIN; GSYM CX_COS; SIN_PI; COS_PI] THEN
3982       CONV_TAC COMPLEX_RING;
3983       ALL_TAC] THEN
3984     REWRITE_TAC[GSYM CEXP_N; CEXP_EQ] THEN
3985     DISCH_THEN(X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC) THEN
3986     FIRST_X_ASSUM(MP_TAC o AP_TERM `Im`) THEN
3987     REWRITE_TAC[IM_MUL_CX; IM_MUL_II; IM_ADD; RE_CX; IM_II; REAL_MUL_RID] THEN
3988     MATCH_MP_TAC(REAL_ARITH
3989      `abs(z) < p / &2 /\ (w = &0 \/ abs(w) >= &2 * p)
3990       ==> ~(&2 * z = p + w)`) THEN
3991     ASM_REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_PI; REAL_ABS_NUM] THEN
3992     SIMP_TAC[real_ge; REAL_MUL_ASSOC; REAL_LE_RMUL_EQ; PI_POS] THEN
3993     REWRITE_TAC[REAL_ENTIRE; PI_NZ] THEN
3994     MP_TAC(SPEC `n:real` REAL_ABS_INTEGER_LEMMA) THEN
3995     ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC;
3996     ASM_SIMP_TAC[CEXP_NEG; CEXP_NZ; COMPLEX_MUL_LNEG; COMPLEX_FIELD
3997      `~(w = Cx(&0)) /\ ~(w pow 2 = --Cx(&1))
3998       ==> (Cx(&1) - (w - inv w) / (w + inv w)) /
3999           (Cx(&1) + (w - inv w) / (w + inv w)) =
4000            inv(w) pow 2`] THEN
4001     REWRITE_TAC[GSYM CEXP_N; GSYM CEXP_NEG] THEN
4002     MATCH_MP_TAC CLOG_CEXP THEN REWRITE_TAC[IM_MUL_CX; IM_NEG; IM_MUL_II] THEN
4003     ASM_REAL_ARITH_TAC]);;
4004
4005 let RE_CATN_BOUNDS = prove
4006  (`!z. (Re z = &0 ==> abs(Im z) < &1) ==> abs(Re(catn z)) < pi / &2`,
4007   REWRITE_TAC[catn; complex_div; GSYM CX_INV; GSYM COMPLEX_MUL_ASSOC] THEN
4008   REPEAT STRIP_TAC THEN REWRITE_TAC[RE_MUL_II; IM_MUL_CX] THEN
4009   MATCH_MP_TAC(REAL_ARITH `abs x < p ==> abs(--(inv(&2) * x)) < p / &2`) THEN
4010   MATCH_MP_TAC(REAL_ARITH `(--p < x /\ x <= p) /\ ~(x = p) ==> abs x < p`) THEN
4011   SUBGOAL_THEN `~(z = ii) /\ ~(z = --ii)` STRIP_ASSUME_TAC THENL
4012    [CONJ_TAC THEN
4013     DISCH_THEN(fun th -> POP_ASSUM MP_TAC THEN SUBST1_TAC th) THEN
4014     REWRITE_TAC[RE_II; IM_II; RE_NEG; IM_NEG] THEN REAL_ARITH_TAC;
4015     ALL_TAC] THEN
4016   REWRITE_TAC[GSYM complex_div] THEN CONJ_TAC THENL
4017    [SUBGOAL_THEN `~((Cx(&1) - ii * z) / (Cx(&1) + ii * z) = Cx(&0))`
4018      (fun th -> MESON_TAC[th; CLOG_WORKS]) THEN
4019     REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC COMPLEX_FIELD;
4020     ALL_TAC] THEN
4021   DISCH_TAC THEN
4022   MP_TAC(ISPEC `clog((Cx(&1) - ii * z) / (Cx(&1) + ii * z))` EULER) THEN
4023   ASM_REWRITE_TAC[SIN_PI; COS_PI; CX_NEG] THEN
4024   REWRITE_TAC[COMPLEX_RING
4025    `x = y * (--Cx(&1) + z * Cx(&0)) <=> x + y = Cx(&0)`] THEN
4026   REWRITE_TAC[CX_EXP] THEN
4027   ASM_SIMP_TAC[CEXP_CLOG; COMPLEX_FIELD
4028      `~(z = ii) /\ ~(z = --ii)
4029       ==> ~((Cx(&1) - ii * z) / (Cx(&1) + ii * z) = Cx(&0))`] THEN
4030   REWRITE_TAC[GSYM CX_EXP] THEN DISCH_THEN(MP_TAC o AP_TERM `Im`) THEN
4031   REWRITE_TAC[IM_ADD; IM_CX; REAL_ADD_RID; IM_COMPLEX_DIV_LEMMA] THEN
4032   DISCH_TAC THEN UNDISCH_TAC `Re z = &0 ==> abs (Im z) < &1` THEN
4033   ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
4034   SUBGOAL_THEN `ii * z = --Cx(Im z)` SUBST_ALL_TAC THENL
4035    [ASM_REWRITE_TAC[COMPLEX_EQ; RE_NEG; IM_NEG; RE_MUL_II; IM_MUL_II;
4036                     RE_CX; IM_CX; REAL_NEG_0];
4037     ALL_TAC] THEN
4038   UNDISCH_TAC
4039    `Im(clog((Cx(&1) - --Cx(Im z)) / (Cx(&1) + --Cx(Im z)))) = pi` THEN
4040   REWRITE_TAC[COMPLEX_SUB_RNEG; GSYM complex_sub] THEN
4041   REWRITE_TAC[GSYM CX_ADD; GSYM CX_SUB; GSYM CX_DIV] THEN
4042   SUBGOAL_THEN `&0 < (&1 + Im z) / (&1 - Im z)` ASSUME_TAC THENL
4043    [MATCH_MP_TAC REAL_LT_DIV THEN ASM_REAL_ARITH_TAC;
4044     ASM_SIMP_TAC[GSYM CX_LOG; IM_CX; PI_NZ]]);;
4045
4046 let HAS_COMPLEX_DERIVATIVE_CATN = prove
4047  (`!z. (Re z = &0 ==> abs(Im z) < &1)
4048        ==> (catn has_complex_derivative inv(Cx(&1) + z pow 2)) (at z)`,
4049   REPEAT STRIP_TAC THEN
4050   SUBGOAL_THEN `~(z = ii) /\ ~(z = --ii)` STRIP_ASSUME_TAC THENL
4051    [CONJ_TAC THEN
4052     DISCH_THEN(fun th -> POP_ASSUM MP_TAC THEN SUBST1_TAC th) THEN
4053     REWRITE_TAC[RE_II; IM_II; RE_NEG; IM_NEG] THEN REAL_ARITH_TAC;
4054     ALL_TAC] THEN
4055   GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
4056   REWRITE_TAC[catn] THEN COMPLEX_DIFF_TAC THEN
4057   REWRITE_TAC[RE_SUB; RE_ADD; IM_SUB; IM_ADD;
4058               RE_CX; RE_MUL_II; IM_CX; IM_MUL_II] THEN
4059   REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL
4060    [ASM_REWRITE_TAC[IM_COMPLEX_DIV_LEMMA; RE_COMPLEX_DIV_LEMMA] THEN
4061     SIMP_TAC[complex_norm] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
4062     ASM_REWRITE_TAC[REAL_ADD_LID; POW_2_SQRT_ABS];
4063     REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC COMPLEX_FIELD]);;
4064
4065 let COMPLEX_DIFFERENTIABLE_AT_CATN = prove
4066  (`!z. (Re z = &0 ==> abs(Im z) < &1) ==> catn complex_differentiable at z`,
4067   REWRITE_TAC[complex_differentiable] THEN
4068   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CATN]);;
4069
4070 let COMPLEX_DIFFERENTIABLE_WITHIN_CATN = prove
4071  (`!s z. (Re z = &0 ==> abs(Im z) < &1)
4072          ==> catn complex_differentiable (at z within s)`,
4073   MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN;
4074             COMPLEX_DIFFERENTIABLE_AT_CATN]);;
4075
4076 add_complex_differentiation_theorems
4077  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4078    (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN
4079              HAS_COMPLEX_DERIVATIVE_CATN)));;
4080
4081 let CONTINUOUS_AT_CATN = prove
4082  (`!z. (Re z = &0 ==> abs(Im z) < &1) ==> catn continuous at z`,
4083   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CATN;
4084             HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);;
4085
4086 let CONTINUOUS_WITHIN_CATN = prove
4087  (`!s z. (Re z = &0 ==> abs(Im z) < &1) ==> catn continuous (at z within s)`,
4088   MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CATN]);;
4089
4090 let CONTINUOUS_ON_CATN = prove
4091  (`!s. (!z. z IN s /\ Re z = &0 ==> abs(Im z) < &1) ==> catn continuous_on s`,
4092   MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CATN]);;
4093
4094 let HOLOMORPHIC_ON_CATN = prove
4095  (`!s. (!z. z IN s /\ Re z = &0 ==> abs(Im z) < &1) ==> catn holomorphic_on s`,
4096   REWRITE_TAC [holomorphic_on] THEN
4097   MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CATN]);;
4098
4099 (* ------------------------------------------------------------------------- *)
4100 (* Real arctangent.                                                          *)
4101 (* ------------------------------------------------------------------------- *)
4102
4103 let atn = new_definition
4104  `atn(x) = Re(catn(Cx x))`;;
4105
4106 let CX_ATN = prove
4107  (`!x. Cx(atn x) = catn(Cx x)`,
4108   GEN_TAC THEN REWRITE_TAC[atn; catn; GSYM REAL; real] THEN
4109   REWRITE_TAC[complex_div; IM_MUL_II; GSYM CX_INV; GSYM COMPLEX_MUL_ASSOC] THEN
4110   REWRITE_TAC[RE_MUL_CX; REAL_ARITH `inv(&2) * x = &0 <=> x = &0`] THEN
4111   MATCH_MP_TAC NORM_CEXP_IMAGINARY THEN
4112   SUBGOAL_THEN `~(Cx(&1) - ii * Cx(x) = Cx(&0)) /\
4113                 ~(Cx(&1) + ii * Cx(x) = Cx(&0))`
4114   STRIP_ASSUME_TAC THENL
4115    [CONJ_TAC THEN DISCH_THEN(MP_TAC o AP_TERM `Re`) THEN
4116     REWRITE_TAC[RE_ADD; RE_SUB; RE_MUL_II; IM_CX; RE_CX] THEN
4117     CONV_TAC REAL_RAT_REDUCE_CONV;
4118     ALL_TAC] THEN
4119   ASM_SIMP_TAC[CEXP_SUB; CEXP_CLOG; COMPLEX_FIELD
4120    `~(a = Cx(&0)) /\ ~(b = Cx(&0)) ==> ~(a * inv b = Cx(&0))`] THEN
4121   REWRITE_TAC[GSYM complex_div; COMPLEX_NORM_DIV] THEN
4122   MATCH_MP_TAC(REAL_FIELD `~(b = &0) /\ a = b ==> a / b = &1`) THEN
4123   ASM_REWRITE_TAC[COMPLEX_NORM_ZERO] THEN
4124   MATCH_MP_TAC(MESON[COMPLEX_NORM_CNJ] `cnj a = b ==> norm a = norm b`) THEN
4125   REWRITE_TAC[CNJ_SUB; CNJ_MUL; CNJ_MUL; CNJ_II; CNJ_CX] THEN
4126   CONV_TAC COMPLEX_RING);;
4127
4128 let ATN_TAN = prove
4129  (`!y. tan(atn y) = y`,
4130   GEN_TAC THEN REWRITE_TAC[tan_def; atn] THEN
4131   MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `Re(ctan(catn(Cx y)))` THEN
4132   CONJ_TAC THENL [REWRITE_TAC[GSYM CX_ATN; RE_CX]; ALL_TAC] THEN
4133   GEN_REWRITE_TAC RAND_CONV [GSYM RE_CX] THEN AP_TERM_TAC THEN
4134   MATCH_MP_TAC CTAN_CATN THEN MATCH_MP_TAC(COMPLEX_RING
4135    `~(z = ii) /\ ~(z = --ii) ==> ~(z pow 2 = --Cx(&1))`) THEN
4136   CONJ_TAC THEN DISCH_THEN(MP_TAC o AP_TERM `Im`) THEN
4137   REWRITE_TAC[IM_II; IM_CX; IM_NEG] THEN REAL_ARITH_TAC);;
4138
4139 let ATN_BOUND = prove
4140  (`!y. abs(atn y) < pi / &2`,
4141   GEN_TAC THEN REWRITE_TAC[atn] THEN MATCH_MP_TAC RE_CATN_BOUNDS THEN
4142   REWRITE_TAC[IM_CX] THEN CONV_TAC REAL_RAT_REDUCE_CONV);;
4143
4144 let ATN_BOUNDS = prove
4145  (`!y. --(pi / &2) < atn(y) /\ atn(y) < (pi / &2)`,
4146   MP_TAC ATN_BOUND THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);;
4147
4148 let TAN_ATN = prove
4149  (`!x. --(pi / &2) < x /\ x < pi / &2 ==> atn(tan(x)) = x`,
4150   REPEAT STRIP_TAC THEN REWRITE_TAC[tan_def; atn] THEN
4151   MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `Re(catn(ctan(Cx x)))` THEN
4152   CONJ_TAC THENL [REWRITE_TAC[GSYM CX_TAN; RE_CX]; ALL_TAC] THEN
4153   GEN_REWRITE_TAC RAND_CONV [GSYM RE_CX] THEN AP_TERM_TAC THEN
4154   MATCH_MP_TAC CATN_CTAN THEN REWRITE_TAC[RE_CX] THEN
4155   ASM_REAL_ARITH_TAC);;
4156
4157 let ATN_0 = prove
4158  (`atn(&0) = &0`,
4159   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [SYM TAN_0] THEN
4160   MATCH_MP_TAC TAN_ATN THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);;
4161
4162 let ATN_1 = prove
4163  (`atn(&1) = pi / &4`,
4164   MP_TAC(AP_TERM `atn` TAN_PI4) THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
4165   MATCH_MP_TAC TAN_ATN THEN MP_TAC PI_POS THEN REAL_ARITH_TAC);;
4166
4167 let ATN_NEG = prove
4168  (`!x. atn(--x) = --(atn x)`,
4169   GEN_TAC THEN MP_TAC(SPEC `atn(x)` TAN_NEG) THEN REWRITE_TAC[ATN_TAN] THEN
4170   DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC TAN_ATN THEN
4171   MP_TAC(SPEC `x:real` ATN_BOUNDS) THEN REAL_ARITH_TAC);;
4172
4173 let ATN_MONO_LT = prove
4174  (`!x y. x < y ==> atn(x) < atn(y)`,
4175   REPEAT GEN_TAC THEN
4176   GEN_REWRITE_TAC (LAND_CONV o BINOP_CONV) [GSYM ATN_TAN] THEN
4177   ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[REAL_NOT_LT] THEN
4178   SIMP_TAC[TAN_MONO_LE; ATN_BOUNDS]);;
4179
4180 let ATN_MONO_LT_EQ = prove
4181  (`!x y. atn(x) < atn(y) <=> x < y`,
4182   MESON_TAC[REAL_NOT_LE; REAL_LE_LT; ATN_MONO_LT]);;
4183
4184 let ATN_MONO_LE_EQ = prove
4185  (`!x y. atn(x) <= atn(y) <=> x <= y`,
4186   REWRITE_TAC[GSYM REAL_NOT_LT; ATN_MONO_LT_EQ]);;
4187
4188 let ATN_INJ = prove
4189  (`!x y. (atn x = atn y) <=> (x = y)`,
4190   REWRITE_TAC[GSYM REAL_LE_ANTISYM; ATN_MONO_LE_EQ]);;
4191
4192 let ATN_POS_LT = prove
4193  (`&0 < atn(x) <=> &0 < x`,
4194   MESON_TAC[ATN_0; ATN_MONO_LT_EQ]);;
4195
4196 let ATN_POS_LE = prove
4197  (`&0 <= atn(x) <=> &0 <= x`,
4198   MESON_TAC[ATN_0; ATN_MONO_LE_EQ]);;
4199
4200 let ATN_LT_PI4_POS = prove
4201  (`!x. x < &1 ==> atn(x) < pi / &4`,
4202   SIMP_TAC[GSYM ATN_1; ATN_MONO_LT]);;
4203
4204 let ATN_LT_PI4_NEG = prove
4205  (`!x. --(&1) < x ==> --(pi / &4) < atn(x)`,
4206   SIMP_TAC[GSYM ATN_1; GSYM ATN_NEG; ATN_MONO_LT]);;
4207
4208 let ATN_LT_PI4 = prove
4209  (`!x. abs(x) < &1 ==> abs(atn x) < pi / &4`,
4210   GEN_TAC THEN
4211   MATCH_MP_TAC(REAL_ARITH
4212    `(&0 < x ==> &0 < y) /\
4213     (x < &0 ==> y < &0) /\
4214     ((x = &0) ==> (y = &0)) /\
4215     (x < a ==> y < b) /\
4216     (--a < x ==> --b < y)
4217     ==> abs(x) < a ==> abs(y) < b`) THEN
4218   SIMP_TAC[ATN_LT_PI4_POS; ATN_LT_PI4_NEG; ATN_0] THEN CONJ_TAC THEN
4219   GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [GSYM ATN_0] THEN
4220   SIMP_TAC[ATN_MONO_LT]);;
4221
4222 let ATN_LE_PI4 = prove
4223  (`!x. abs(x) <= &1 ==> abs(atn x) <= pi / &4`,
4224   REWRITE_TAC[REAL_LE_LT] THEN REPEAT STRIP_TAC THEN
4225   ASM_SIMP_TAC[ATN_LT_PI4] THEN DISJ2_TAC THEN
4226   FIRST_ASSUM(DISJ_CASES_THEN SUBST1_TAC o MATCH_MP
4227     (REAL_ARITH `(abs(x) = a) ==> (x = a) \/ (x = --a)`)) THEN
4228   ASM_REWRITE_TAC[ATN_1; ATN_NEG] THEN
4229   REWRITE_TAC[REAL_ABS_DIV; REAL_ABS_NUM; REAL_ABS_NEG] THEN
4230   SIMP_TAC[real_abs; REAL_LT_IMP_LE; PI_POS]);;
4231
4232 let COS_ATN_NZ = prove
4233  (`!x. ~(cos(atn(x)) = &0)`,
4234   GEN_TAC THEN MATCH_MP_TAC REAL_LT_IMP_NZ THEN
4235   MATCH_MP_TAC COS_POS_PI THEN REWRITE_TAC[ATN_BOUNDS]);;
4236
4237 let TAN_SEC = prove
4238  (`!x. ~(cos(x) = &0) ==> (&1 + (tan(x) pow 2) = inv(cos x) pow 2)`,
4239   MP_TAC SIN_CIRCLE THEN MATCH_MP_TAC MONO_FORALL THEN REWRITE_TAC[tan] THEN
4240   CONV_TAC REAL_FIELD);;
4241
4242 let COS_ATN = prove
4243  (`!x. cos(atn x) = &1 / sqrt(&1 + x pow 2)`,
4244   SIMP_TAC[COS_TAN; ATN_BOUND; ATN_TAN]);;
4245
4246 let SIN_ATN = prove
4247  (`!x. sin(atn x) = x / sqrt(&1 + x pow 2)`,
4248   SIMP_TAC[SIN_TAN; ATN_BOUND; ATN_TAN]);;
4249
4250 (* ------------------------------------------------------------------------- *)
4251 (* Some bound theorems where a bit of simple calculus is handy.              *)
4252 (* ------------------------------------------------------------------------- *)
4253
4254 let ATN_ABS_LE_X = prove
4255  (`!x. abs(atn x) <= abs x`,
4256   REPEAT STRIP_TAC THEN
4257   MP_TAC(ISPECL [`catn`; `\z. inv(Cx(&1) + z pow 2)`; `real`; `&1`]
4258       COMPLEX_MVT) THEN
4259   REWRITE_TAC[CONVEX_REAL; IN] THEN ANTS_TAC THENL
4260    [CONJ_TAC THENL
4261      [REWRITE_TAC[real] THEN REPEAT STRIP_TAC THEN
4262       MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN
4263       MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_CATN THEN
4264       ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC;
4265       GEN_TAC THEN REWRITE_TAC[REAL] THEN
4266       DISCH_THEN(SUBST1_TAC o SYM) THEN
4267       REWRITE_TAC[GSYM CX_POW; GSYM CX_ADD; GSYM CX_INV; COMPLEX_NORM_CX] THEN
4268       REWRITE_TAC[REAL_ABS_INV] THEN MATCH_MP_TAC REAL_INV_LE_1 THEN
4269       MP_TAC(SPEC `Re z` REAL_LE_SQUARE) THEN REAL_ARITH_TAC];
4270     DISCH_THEN(MP_TAC o SPECL [`Cx(&0)`; `Cx(x)`]) THEN
4271     REWRITE_TAC[GSYM CX_ATN; COMPLEX_SUB_RZERO; REAL_CX; ATN_0] THEN
4272     REWRITE_TAC[COMPLEX_NORM_CX; REAL_MUL_LID]]);;
4273
4274 let ATN_LE_X = prove
4275  (`!x. &0 <= x ==> atn(x) <= x`,
4276   MP_TAC ATN_ABS_LE_X THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);;
4277
4278 let TAN_ABS_GE_X = prove
4279  (`!x. abs(x) < pi / &2 ==> abs(x) <= abs(tan x)`,
4280   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
4281   EXISTS_TAC `abs(atn(tan x))` THEN REWRITE_TAC[ATN_ABS_LE_X] THEN
4282   MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
4283   CONV_TAC SYM_CONV THEN MATCH_MP_TAC TAN_ATN THEN
4284   POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);;
4285
4286 (* ------------------------------------------------------------------------- *)
4287 (* Probably not very useful, but for compatibility with old analysis theory. *)
4288 (* ------------------------------------------------------------------------- *)
4289
4290 let TAN_TOTAL = prove
4291  (`!y. ?!x. --(pi / &2) < x /\ x < (pi / &2) /\ tan(x) = y`,
4292   MESON_TAC[TAN_ATN; ATN_TAN; ATN_BOUNDS]);;
4293
4294 let TAN_TOTAL_POS = prove
4295  (`!y. &0 <= y ==> ?x. &0 <= x /\ x < pi / &2 /\ tan(x) = y`,
4296   MESON_TAC[ATN_TAN; ATN_BOUNDS; ATN_POS_LE]);;
4297
4298 let TAN_TOTAL_LEMMA = prove
4299  (`!y. &0 < y ==> ?x. &0 < x /\ x < pi / &2 /\ y < tan(x)`,
4300   REPEAT STRIP_TAC THEN EXISTS_TAC `atn(y + &1)` THEN
4301   REWRITE_TAC[ATN_TAN; ATN_BOUNDS; ATN_POS_LT] THEN
4302   POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);;
4303
4304 (* ------------------------------------------------------------------------- *)
4305 (* Some slightly ad hoc lemmas useful here.                                  *)
4306 (* ------------------------------------------------------------------------- *)
4307
4308 let RE_POW_2 = prove
4309  (`Re(z pow 2) = Re(z) pow 2 - Im(z) pow 2`,
4310   REWRITE_TAC[COMPLEX_POW_2; complex_mul; RE] THEN REAL_ARITH_TAC);;
4311
4312 let IM_POW_2 = prove
4313  (`Im(z pow 2) = &2 * Re(z) * Im(z)`,
4314   REWRITE_TAC[COMPLEX_POW_2; complex_mul; IM] THEN REAL_ARITH_TAC);;
4315
4316 let ABS_SQUARE_LT_1 = prove
4317  (`!x. x pow 2 < &1 <=> abs(x) < &1`,
4318   ONCE_REWRITE_TAC[GSYM REAL_ABS_NUM] THEN
4319   REWRITE_TAC[REAL_LT_SQUARE_ABS] THEN REAL_ARITH_TAC);;
4320
4321 let ABS_SQUARE_LE_1 = prove
4322  (`!x. x pow 2 <= &1 <=> abs(x) <= &1`,
4323   ONCE_REWRITE_TAC[GSYM REAL_ABS_NUM] THEN
4324   REWRITE_TAC[REAL_LT_SQUARE_ABS; GSYM REAL_NOT_LT] THEN REAL_ARITH_TAC);;
4325
4326 let ABS_SQUARE_EQ_1 = prove
4327  (`!x. x pow 2 = &1 <=> abs(x) = &1`,
4328   REWRITE_TAC[REAL_RING `x pow 2 = &1 <=> x = &1 \/ x = -- &1`] THEN
4329   REAL_ARITH_TAC);;
4330
4331 (* ------------------------------------------------------------------------- *)
4332 (* Inverse sine.                                                             *)
4333 (* ------------------------------------------------------------------------- *)
4334
4335 let casn = new_definition
4336  `casn z = --ii * clog(ii * z + csqrt(Cx(&1) - z pow 2))`;;
4337
4338 let CASN_BODY_LEMMA = prove
4339  (`!z. ~(ii * z + csqrt(Cx(&1) - z pow 2) = Cx(&0))`,
4340   GEN_TAC THEN MP_TAC(SPEC `Cx(&1) - z pow 2` CSQRT) THEN
4341   CONV_TAC COMPLEX_FIELD);;
4342
4343 let CSIN_CASN = prove
4344  (`!z. csin(casn z) = z`,
4345   GEN_TAC THEN REWRITE_TAC[csin; casn; COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG] THEN
4346   REWRITE_TAC[COMPLEX_MUL_ASSOC; COMPLEX_NEG_NEG] THEN
4347   REWRITE_TAC[COMPLEX_POW_II_2; GSYM COMPLEX_POW_2] THEN
4348   REWRITE_TAC[COMPLEX_NEG_NEG; COMPLEX_MUL_LNEG; COMPLEX_MUL_LID] THEN
4349   REWRITE_TAC[CEXP_NEG] THEN
4350   ASM_SIMP_TAC[CASN_BODY_LEMMA; CEXP_CLOG; COMPLEX_FIELD
4351      `~(z = Cx(&0))
4352       ==> ((z - inv z) / (Cx(&2) * ii) = c <=>
4353            z pow 2 - Cx(&1) = Cx(&2) * ii * c * z)`] THEN
4354   MP_TAC(SPEC `Cx(&1) - z pow 2` CSQRT) THEN CONV_TAC COMPLEX_FIELD);;
4355
4356 let CASN_CSIN = prove
4357  (`!z. abs(Re z) < pi / &2 \/ (abs(Re z) = pi / &2 /\ Im z = &0)
4358        ==> casn(csin z) = z`,
4359   GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
4360   REWRITE_TAC[csin; casn; COMPLEX_MUL_LNEG; CEXP_NEG] THEN
4361   SIMP_TAC[CEXP_NZ; COMPLEX_FIELD
4362     `~(z = Cx(&0))
4363      ==> Cx(&1) - ((z - inv z) / (Cx(&2) * ii)) pow 2 =
4364          ((z + inv z) / Cx(&2)) pow 2`] THEN
4365   SUBGOAL_THEN
4366    `csqrt(((cexp(ii * z) + inv(cexp(ii * z))) / Cx(&2)) pow 2) =
4367     (cexp(ii * z) + inv(cexp(ii * z))) / Cx(&2)`
4368   SUBST1_TAC THENL
4369    [MATCH_MP_TAC POW_2_CSQRT THEN REWRITE_TAC[GSYM CEXP_NEG] THEN
4370     REWRITE_TAC[complex_div; GSYM CX_INV; RE_MUL_CX; IM_MUL_CX] THEN
4371     REWRITE_TAC[REAL_ARITH
4372      `&0 < r * inv(&2) \/ r * inv(&2) = &0 /\ &0 <= i * inv(&2) <=>
4373       &0 < r \/ r = &0 /\ &0 <= i`] THEN
4374     REWRITE_TAC[RE_ADD; IM_ADD; RE_CEXP; IM_CEXP] THEN
4375     REWRITE_TAC[RE_MUL_II; RE_NEG; IM_MUL_II; IM_NEG] THEN
4376     REWRITE_TAC[SIN_NEG; COS_NEG; REAL_NEG_NEG] THEN
4377     REWRITE_TAC[REAL_MUL_RNEG; GSYM real_sub] THEN
4378     REWRITE_TAC[GSYM REAL_ADD_RDISTRIB; GSYM REAL_SUB_RDISTRIB] THEN
4379     FIRST_X_ASSUM(DISJ_CASES_THEN STRIP_ASSUME_TAC) THENL
4380      [DISJ1_TAC THEN MATCH_MP_TAC REAL_LT_MUL THEN
4381       ASM_SIMP_TAC[REAL_LT_ADD; REAL_EXP_POS_LT] THEN
4382       MATCH_MP_TAC COS_POS_PI THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
4383       DISJ2_TAC THEN ASM_REWRITE_TAC[SIN_PI2; COS_PI2] THEN
4384       REWRITE_TAC[REAL_EXP_NEG; REAL_EXP_0; REAL_INV_1; REAL_SUB_REFL] THEN
4385       REWRITE_TAC[REAL_MUL_LZERO; REAL_LE_REFL; REAL_ENTIRE] THEN
4386       FIRST_X_ASSUM(DISJ_CASES_THEN SUBST1_TAC o MATCH_MP (REAL_ARITH
4387        `abs(x) = p ==> x = p \/ x = --p`)) THEN
4388       REWRITE_TAC[COS_PI2; COS_NEG] THEN REAL_ARITH_TAC];
4389     ALL_TAC] THEN
4390   SIMP_TAC[COMPLEX_FIELD
4391    `ii * (a - b) / (Cx(&2) * ii) + (a + b) / Cx(&2) = a`] THEN
4392   SIMP_TAC[COMPLEX_FIELD `--(ii * w) = z <=> w = ii * z`] THEN
4393   MATCH_MP_TAC CLOG_CEXP THEN REWRITE_TAC[IM_MUL_II] THEN
4394   MP_TAC PI_POS THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);;
4395
4396 let CASN_UNIQUE = prove
4397  (`!w z. csin(z) = w /\
4398          (abs(Re z) < pi / &2 \/ (abs(Re z) = pi / &2 /\ Im z = &0))
4399          ==> casn w = z`,
4400   MESON_TAC[CASN_CSIN]);;
4401
4402 let CASN_0 = prove
4403  (`casn(Cx(&0)) = Cx(&0)`,
4404   REWRITE_TAC[casn; COMPLEX_MUL_RZERO; COMPLEX_ADD_LID; COMPLEX_POW_2;
4405               COMPLEX_SUB_RZERO; CSQRT_1; CLOG_1; COMPLEX_MUL_RZERO]);;
4406
4407 let CASN_1 = prove
4408  (`casn(Cx(&1)) = Cx(pi / &2)`,
4409   REWRITE_TAC[casn; GSYM CX_POW; GSYM CX_SUB] THEN
4410   CONV_TAC REAL_RAT_REDUCE_CONV THEN
4411   REWRITE_TAC[CSQRT_0; COMPLEX_MUL_RID; COMPLEX_ADD_RID] THEN
4412   REWRITE_TAC[CLOG_II] THEN CONV_TAC COMPLEX_RING);;
4413
4414 let CASN_NEG_1 = prove
4415  (`casn(--Cx(&1)) = --Cx(pi / &2)`,
4416   REWRITE_TAC[casn; GSYM CX_NEG; GSYM CX_POW; GSYM CX_SUB] THEN
4417   CONV_TAC REAL_RAT_REDUCE_CONV THEN
4418   REWRITE_TAC[CSQRT_0; COMPLEX_MUL_RID; COMPLEX_ADD_RID] THEN
4419   REWRITE_TAC[CX_NEG; COMPLEX_MUL_RID; COMPLEX_MUL_RNEG] THEN
4420   REWRITE_TAC[CLOG_NEG_II] THEN CONV_TAC COMPLEX_RING);;
4421
4422 let HAS_COMPLEX_DERIVATIVE_CASN = prove
4423  (`!z. (Im z = &0 ==> abs(Re z) < &1)
4424        ==> (casn has_complex_derivative inv(ccos(casn z))) (at z)`,
4425   REPEAT STRIP_TAC THEN
4426   MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_INVERSE_BASIC THEN
4427   EXISTS_TAC `csin` THEN
4428   REWRITE_TAC[CSIN_CASN; HAS_COMPLEX_DERIVATIVE_CSIN; CONTINUOUS_AT_CSIN] THEN
4429   EXISTS_TAC `ball(z:complex,&1)` THEN
4430   REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL; REAL_LT_01] THEN CONJ_TAC THENL
4431    [DISCH_THEN(MP_TAC o MATCH_MP (COMPLEX_RING
4432      `ccos z = Cx(&0) ==> csin(z) pow 2 + ccos(z) pow 2 = Cx(&1)
4433                           ==> csin(z) pow 2 = Cx(&1)`)) THEN
4434     REWRITE_TAC[CSIN_CASN; CSIN_CIRCLE] THEN
4435     REWRITE_TAC[COMPLEX_RING
4436      `z pow 2 = Cx(&1) <=> z = Cx(&1) \/ z = --Cx(&1)`] THEN
4437     DISCH_THEN(DISJ_CASES_THEN SUBST_ALL_TAC) THEN
4438     POP_ASSUM MP_TAC THEN REWRITE_TAC[RE_CX; IM_CX; RE_NEG; IM_NEG] THEN
4439     REAL_ARITH_TAC;
4440     ALL_TAC] THEN
4441   GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN REWRITE_TAC[casn] THEN
4442   MATCH_MP_TAC CONTINUOUS_COMPLEX_MUL THEN REWRITE_TAC[CONTINUOUS_CONST] THEN
4443   ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN
4444   CONJ_TAC THENL
4445    [MATCH_MP_TAC CONTINUOUS_ADD THEN
4446     SIMP_TAC[CONTINUOUS_COMPLEX_MUL; CONTINUOUS_CONST; CONTINUOUS_AT_ID] THEN
4447     ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN
4448     SIMP_TAC[CONTINUOUS_COMPLEX_POW; CONTINUOUS_SUB;
4449              CONTINUOUS_CONST; CONTINUOUS_AT_ID] THEN
4450     MATCH_MP_TAC CONTINUOUS_AT_CSQRT THEN
4451     REWRITE_TAC[RE_SUB; IM_SUB; RE_CX; IM_CX; RE_POW_2; IM_POW_2] THEN
4452     REWRITE_TAC[REAL_RING `&0 - &2 * x * y = &0 <=> x = &0 \/ y = &0`] THEN
4453     STRIP_TAC THEN
4454     ASM_REWRITE_TAC[REAL_POW_2; REAL_MUL_LZERO; REAL_SUB_RZERO;
4455                     REAL_ARITH `&1 - (&0 - x) = &1 + x`] THEN
4456     ASM_SIMP_TAC[REAL_LE_SQUARE; REAL_ARITH `&0 <= x ==> &0 < &1 + x`] THEN
4457     REWRITE_TAC[REAL_ARITH `&0 < &1 - x * x <=> x pow 2 < &1 pow 2`] THEN
4458     ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN MATCH_MP_TAC REAL_POW_LT2 THEN
4459     ASM_SIMP_TAC[REAL_ABS_POS; REAL_ABS_NUM; ARITH];
4460     ALL_TAC] THEN
4461   MATCH_MP_TAC CONTINUOUS_AT_CLOG THEN
4462   REWRITE_TAC[IM_ADD; IM_MUL_II; RE_ADD; RE_MUL_II] THEN
4463   ASM_CASES_TAC `Im z = &0` THENL
4464    [DISCH_THEN(K ALL_TAC) THEN ASM_REWRITE_TAC[csqrt] THEN
4465     ASM_REWRITE_TAC[IM_SUB; RE_SUB; IM_CX; RE_CX; IM_POW_2; RE_POW_2;
4466                     REAL_MUL_RZERO; REAL_SUB_REFL] THEN
4467     CONV_TAC REAL_RAT_REDUCE_CONV THEN
4468     REWRITE_TAC[REAL_ARITH `&0 <= &1 - (z pow 2 - &0) <=> z pow 2 <= &1 pow 2`;
4469                 GSYM REAL_LE_SQUARE_ABS] THEN
4470     ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_ABS_NUM; RE; REAL_ADD_LID] THEN
4471     MATCH_MP_TAC SQRT_POS_LT THEN
4472     REWRITE_TAC[REAL_ARITH `&0 < &1 - (z pow 2 - &0) <=> z pow 2 < &1 pow 2`;
4473                 GSYM REAL_LT_SQUARE_ABS] THEN
4474     ASM_REAL_ARITH_TAC;
4475     ALL_TAC] THEN
4476   REWRITE_TAC[csqrt; IM_SUB; RE_SUB; IM_CX; RE_CX; IM_POW_2; RE_POW_2] THEN
4477   REWRITE_TAC[REAL_RING `&0 - &2 * x * y = &0 <=> x = &0 \/ y = &0`] THEN
4478   ASM_CASES_TAC `Re z = &0` THEN ASM_REWRITE_TAC[RE; IM] THENL
4479    [CONV_TAC REAL_RAT_REDUCE_CONV THEN
4480     REWRITE_TAC[REAL_ARITH `&1 - (&0 - x) = &1 + x`] THEN
4481     SIMP_TAC[REAL_POW_2; REAL_LE_ADD; REAL_LE_SQUARE; REAL_POS] THEN
4482     REWRITE_TAC[RE; IM; REAL_ADD_LID; REAL_ARITH `&0 < --x + y <=> x < y`] THEN
4483     MATCH_MP_TAC REAL_LT_RSQRT THEN REAL_ARITH_TAC;
4484     ALL_TAC] THEN
4485   DISCH_TAC THEN REWRITE_TAC[REAL_ARITH `&0 < --x + y <=> x < y`] THEN
4486   MATCH_MP_TAC REAL_LT_RSQRT THEN
4487   REWRITE_TAC[REAL_POW_2; REAL_ARITH
4488    `a < (n + &1 - (b - a)) / &2 <=> (a + b) - &1 < n`] THEN
4489   REWRITE_TAC[complex_norm] THEN MATCH_MP_TAC REAL_LT_RSQRT THEN
4490   REWRITE_TAC[RE_SUB; IM_SUB; RE_CX; IM_CX; RE_POW_2; IM_POW_2] THEN
4491   REPEAT(FIRST_X_ASSUM(MP_TAC o
4492     GEN_REWRITE_RULE I [GSYM REAL_LT_SQUARE])) THEN
4493   REAL_ARITH_TAC);;
4494
4495 let COMPLEX_DIFFERENTIABLE_AT_CASN = prove
4496  (`!z. (Im z = &0 ==> abs(Re z) < &1) ==> casn complex_differentiable at z`,
4497   REWRITE_TAC[complex_differentiable] THEN
4498   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CASN]);;
4499
4500 let COMPLEX_DIFFERENTIABLE_WITHIN_CASN = prove
4501  (`!s z. (Im z = &0 ==> abs(Re z) < &1)
4502          ==> casn complex_differentiable (at z within s)`,
4503   MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN;
4504             COMPLEX_DIFFERENTIABLE_AT_CASN]);;
4505
4506 add_complex_differentiation_theorems
4507  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4508    (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN
4509              HAS_COMPLEX_DERIVATIVE_CASN)));;
4510
4511 let CONTINUOUS_AT_CASN = prove
4512  (`!z. (Im z = &0 ==> abs(Re z) < &1) ==> casn continuous at z`,
4513   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CASN;
4514             HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);;
4515
4516 let CONTINUOUS_WITHIN_CASN = prove
4517  (`!s z. (Im z = &0 ==> abs(Re z) < &1) ==> casn continuous (at z within s)`,
4518   MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CASN]);;
4519
4520 let CONTINUOUS_ON_CASN = prove
4521  (`!s. (!z. z IN s /\ Im z = &0 ==> abs(Re z) < &1) ==> casn continuous_on s`,
4522   MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CASN]);;
4523
4524 let HOLOMORPHIC_ON_CASN = prove
4525  (`!s. (!z. z IN s /\ Im z = &0 ==> abs(Re z) < &1) ==> casn holomorphic_on s`,
4526   REWRITE_TAC [holomorphic_on] THEN
4527   MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CASN]);;
4528
4529 (* ------------------------------------------------------------------------- *)
4530 (* Inverse cosine.                                                           *)
4531 (* ------------------------------------------------------------------------- *)
4532
4533 let cacs = new_definition
4534  `cacs z = --ii * clog(z + ii * csqrt(Cx(&1) - z pow 2))`;;
4535
4536 let CACS_BODY_LEMMA = prove
4537  (`!z. ~(z + ii * csqrt(Cx(&1) - z pow 2) = Cx(&0))`,
4538   GEN_TAC THEN MP_TAC(SPEC `Cx(&1) - z pow 2` CSQRT) THEN
4539   CONV_TAC COMPLEX_FIELD);;
4540
4541 let CCOS_CACS = prove
4542  (`!z. ccos(cacs z) = z`,
4543   GEN_TAC THEN REWRITE_TAC[ccos; cacs; COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG] THEN
4544   REWRITE_TAC[COMPLEX_MUL_ASSOC; COMPLEX_NEG_NEG] THEN
4545   REWRITE_TAC[COMPLEX_POW_II_2; GSYM COMPLEX_POW_2] THEN
4546   REWRITE_TAC[COMPLEX_NEG_NEG; COMPLEX_MUL_LNEG; COMPLEX_MUL_LID] THEN
4547   REWRITE_TAC[CEXP_NEG] THEN
4548   ASM_SIMP_TAC[CACS_BODY_LEMMA; CEXP_CLOG; COMPLEX_POW_II_2; COMPLEX_FIELD
4549      `~(z = Cx(&0))
4550       ==> ((z + inv z) / Cx(&2) = c <=>
4551            z pow 2 + Cx(&1) = Cx(&2) * c * z)`] THEN
4552   MP_TAC(SPEC `Cx(&1) - z pow 2` CSQRT) THEN CONV_TAC COMPLEX_FIELD);;
4553
4554 let CACS_CCOS = prove
4555  (`!z. &0 < Re z /\ Re z < pi \/
4556        Re(z) = &0 /\ &0 <= Im(z) \/
4557        Re(z) = pi /\ Im(z) <= &0
4558        ==> cacs(ccos z) = z`,
4559   GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
4560   REWRITE_TAC[ccos; cacs; COMPLEX_MUL_LNEG; CEXP_NEG] THEN
4561   SIMP_TAC[CEXP_NZ; COMPLEX_FIELD
4562     `~(z = Cx(&0))
4563      ==> Cx(&1) - ((z + inv z) / Cx(&2)) pow 2 =
4564          --(((z - inv z) / Cx(&2)) pow 2)`] THEN
4565   SUBGOAL_THEN
4566    `csqrt(--(((cexp(ii * z) - inv(cexp(ii * z))) / Cx(&2)) pow 2)) =
4567     --ii * (cexp(ii * z) - inv(cexp(ii * z))) / Cx(&2)`
4568   SUBST1_TAC THENL
4569    [SIMP_TAC[COMPLEX_FIELD `--(x pow 2) = (--ii * x) pow 2`] THEN
4570     MATCH_MP_TAC POW_2_CSQRT THEN REWRITE_TAC[GSYM CEXP_NEG] THEN
4571     REWRITE_TAC[complex_div; GSYM CX_INV; RE_MUL_CX; IM_MUL_CX; RE_NEG; IM_NEG;
4572                 COMPLEX_MUL_LNEG; RE_MUL_II; IM_MUL_II; RE_SUB; IM_SUB] THEN
4573     REWRITE_TAC[REAL_NEG_NEG; REAL_NEG_EQ_0] THEN
4574     REWRITE_TAC[REAL_ARITH
4575      `&0 < r * inv(&2) \/ r * inv(&2) = &0 /\ &0 <= --(i * inv(&2)) <=>
4576       &0 < r \/ r = &0 /\ &0 <= --i`] THEN
4577     REWRITE_TAC[RE_ADD; IM_ADD; RE_CEXP; IM_CEXP] THEN
4578     REWRITE_TAC[RE_MUL_II; RE_NEG; IM_MUL_II; IM_NEG] THEN
4579     REWRITE_TAC[SIN_NEG; COS_NEG; REAL_NEG_NEG] THEN
4580     REWRITE_TAC[REAL_MUL_RNEG; GSYM real_sub; REAL_SUB_RNEG; REAL_NEG_SUB] THEN
4581     REWRITE_TAC[GSYM REAL_ADD_RDISTRIB; GSYM REAL_SUB_RDISTRIB] THEN
4582     ASM_SIMP_TAC[REAL_LT_ADD; REAL_EXP_POS_LT; REAL_LT_MUL_EQ] THEN
4583     POP_ASSUM(REPEAT_TCL DISJ_CASES_THEN STRIP_ASSUME_TAC) THEN
4584     ASM_SIMP_TAC[SIN_POS_PI] THEN DISJ2_TAC THEN
4585     REWRITE_TAC[SIN_PI; REAL_MUL_RZERO; COS_PI; SIN_0; COS_0] THEN
4586     REWRITE_TAC[REAL_MUL_RID; REAL_MUL_RNEG] THEN
4587     REWRITE_TAC[REAL_NEG_SUB; REAL_SUB_LE; REAL_EXP_MONO_LE] THEN
4588     ASM_REAL_ARITH_TAC;
4589     ALL_TAC] THEN
4590   SIMP_TAC[COMPLEX_FIELD
4591    `(e + e') / Cx(&2) + ii * --ii * (e - e') / Cx(&2) = e`] THEN
4592   SIMP_TAC[COMPLEX_FIELD `--(ii * w) = z <=> w = ii * z`] THEN
4593   MATCH_MP_TAC CLOG_CEXP THEN REWRITE_TAC[IM_MUL_II] THEN
4594   MP_TAC PI_POS THEN ASM_REAL_ARITH_TAC);;
4595
4596 let CACS_UNIQUE = prove
4597  (`!w z.
4598        ccos z = w /\
4599        (&0 < Re z /\ Re z < pi \/
4600         Re(z) = &0 /\ &0 <= Im(z) \/
4601         Re(z) = pi /\ Im(z) <= &0)
4602        ==> cacs(w) = z`,
4603   MESON_TAC[CACS_CCOS]);;
4604
4605 let CACS_0 = prove
4606  (`cacs(Cx(&0)) = Cx(pi / &2)`,
4607   MATCH_MP_TAC CACS_UNIQUE THEN
4608   REWRITE_TAC[RE_CX; IM_CX; GSYM CX_COS; COS_PI2] THEN
4609   MP_TAC PI_POS THEN REAL_ARITH_TAC);;
4610
4611 let CACS_1 = prove
4612  (`cacs(Cx(&1)) = Cx(&0)`,
4613   MATCH_MP_TAC CACS_UNIQUE THEN
4614   REWRITE_TAC[RE_CX; IM_CX; GSYM CX_COS; COS_0; REAL_LE_REFL]);;
4615
4616 let CACS_NEG_1 = prove
4617  (`cacs(--Cx(&1)) = Cx pi`,
4618   MATCH_MP_TAC CACS_UNIQUE THEN
4619   REWRITE_TAC[RE_CX; IM_CX; GSYM CX_COS; COS_PI; CX_NEG; REAL_LE_REFL]);;
4620
4621 let HAS_COMPLEX_DERIVATIVE_CACS = prove
4622  (`!z. (Im z = &0 ==> abs(Re z) < &1)
4623        ==> (cacs has_complex_derivative --inv(csin(cacs z))) (at z)`,
4624   REPEAT STRIP_TAC THEN REWRITE_TAC[COMPLEX_NEG_INV] THEN
4625   MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_INVERSE_BASIC THEN
4626   EXISTS_TAC `ccos` THEN
4627   REWRITE_TAC[CCOS_CACS; HAS_COMPLEX_DERIVATIVE_CCOS; CONTINUOUS_AT_CCOS] THEN
4628   EXISTS_TAC `ball(z:complex,&1)` THEN
4629   REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL; REAL_LT_01] THEN CONJ_TAC THENL
4630    [DISCH_THEN(MP_TAC o MATCH_MP (COMPLEX_RING
4631      `--(csin z) = Cx(&0) ==> csin(z) pow 2 + ccos(z) pow 2 = Cx(&1)
4632                               ==> ccos(z) pow 2 = Cx(&1)`)) THEN
4633     REWRITE_TAC[CCOS_CACS; CSIN_CIRCLE] THEN
4634     REWRITE_TAC[COMPLEX_RING
4635      `z pow 2 = Cx(&1) <=> z = Cx(&1) \/ z = --Cx(&1)`] THEN
4636     DISCH_THEN(DISJ_CASES_THEN SUBST_ALL_TAC) THEN
4637     POP_ASSUM MP_TAC THEN REWRITE_TAC[RE_CX; IM_CX; RE_NEG; IM_NEG] THEN
4638     REAL_ARITH_TAC;
4639     ALL_TAC] THEN
4640   GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN REWRITE_TAC[cacs] THEN
4641   MATCH_MP_TAC CONTINUOUS_COMPLEX_MUL THEN REWRITE_TAC[CONTINUOUS_CONST] THEN
4642   ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN
4643   CONJ_TAC THENL
4644    [MATCH_MP_TAC CONTINUOUS_ADD THEN REWRITE_TAC[CONTINUOUS_AT_ID] THEN
4645     MATCH_MP_TAC CONTINUOUS_COMPLEX_MUL THEN REWRITE_TAC[CONTINUOUS_CONST] THEN
4646     ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN
4647     SIMP_TAC[CONTINUOUS_COMPLEX_POW; CONTINUOUS_SUB;
4648              CONTINUOUS_CONST; CONTINUOUS_AT_ID] THEN
4649     MATCH_MP_TAC CONTINUOUS_AT_CSQRT THEN
4650     REWRITE_TAC[RE_SUB; IM_SUB; RE_CX; IM_CX; RE_POW_2; IM_POW_2] THEN
4651     REWRITE_TAC[REAL_RING `&0 - &2 * x * y = &0 <=> x = &0 \/ y = &0`] THEN
4652     STRIP_TAC THEN
4653     ASM_REWRITE_TAC[REAL_POW_2; REAL_MUL_LZERO; REAL_SUB_RZERO;
4654                     REAL_ARITH `&1 - (&0 - x) = &1 + x`] THEN
4655     ASM_SIMP_TAC[REAL_LE_SQUARE; REAL_ARITH `&0 <= x ==> &0 < &1 + x`] THEN
4656     REWRITE_TAC[REAL_ARITH `&0 < &1 - x * x <=> x pow 2 < &1 pow 2`] THEN
4657     ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN MATCH_MP_TAC REAL_POW_LT2 THEN
4658     ASM_SIMP_TAC[REAL_ABS_POS; REAL_ABS_NUM; ARITH];
4659     ALL_TAC] THEN
4660   MATCH_MP_TAC CONTINUOUS_AT_CLOG THEN
4661   REWRITE_TAC[IM_ADD; IM_MUL_II; RE_ADD; RE_MUL_II] THEN
4662   ASM_CASES_TAC `Im z = &0` THENL
4663    [ASM_REWRITE_TAC[csqrt] THEN
4664     ASM_REWRITE_TAC[IM_SUB; RE_SUB; IM_CX; RE_CX; IM_POW_2; RE_POW_2;
4665                     REAL_MUL_RZERO; REAL_SUB_REFL] THEN
4666     CONV_TAC REAL_RAT_REDUCE_CONV THEN
4667     REWRITE_TAC[REAL_ARITH `&0 <= &1 - (z pow 2 - &0) <=> z pow 2 <= &1 pow 2`;
4668                 GSYM REAL_LE_SQUARE_ABS] THEN
4669     ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_ABS_NUM; RE; REAL_ADD_LID] THEN
4670     REWRITE_TAC[GSYM real_sub; IM; REAL_SUB_LT; REAL_SUB_RZERO] THEN
4671     MATCH_MP_TAC(REAL_ARITH `&0 < x ==> x = &0 ==> &0 < y`) THEN
4672     MATCH_MP_TAC SQRT_POS_LT THEN
4673     ASM_SIMP_TAC[REAL_SUB_LT; ABS_SQUARE_LT_1];
4674     ALL_TAC] THEN
4675   REWRITE_TAC[csqrt; IM_SUB; RE_SUB; IM_CX; RE_CX; IM_POW_2; RE_POW_2] THEN
4676   REWRITE_TAC[REAL_RING `&0 - &2 * x * y = &0 <=> x = &0 \/ y = &0`] THEN
4677   ASM_CASES_TAC `Re z = &0` THEN ASM_REWRITE_TAC[RE; IM] THENL
4678    [CONV_TAC REAL_RAT_REDUCE_CONV THEN
4679     REWRITE_TAC[REAL_ARITH `&1 - (&0 - x) = &1 + x`] THEN
4680     SIMP_TAC[REAL_POW_2; REAL_LE_ADD; REAL_LE_SQUARE; REAL_POS] THEN
4681     REWRITE_TAC[RE; IM; REAL_ADD_LID] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
4682     DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH `a + b = &0 ==> a = --b`)) THEN
4683     DISCH_THEN(MP_TAC o AP_TERM `\x:real. x pow 2`) THEN
4684     SIMP_TAC[SQRT_POW_2; REAL_POW_NEG; ARITH; REAL_LE_SQUARE; REAL_LE_ADD;
4685              REAL_POS] THEN
4686     REAL_ARITH_TAC;
4687     ALL_TAC] THEN
4688   DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH `a + b = &0 ==> a = --b`)) THEN
4689   DISCH_THEN(MP_TAC o AP_TERM `\x:real. x pow 2`) THEN
4690   SUBGOAL_THEN `&0 < (norm(Cx (&1) - z pow 2) +
4691                       &1 - (Re z pow 2 - Im z pow 2)) / &2`
4692   ASSUME_TAC THENL
4693    [REWRITE_TAC[REAL_ARITH `&0 < (x + y - z) / &2 <=> z - y < x`] THEN
4694     REWRITE_TAC[complex_norm] THEN MATCH_MP_TAC REAL_LT_RSQRT THEN
4695     REWRITE_TAC[RE_SUB; IM_SUB; RE_CX; IM_CX; RE_POW_2; IM_POW_2] THEN
4696     REPEAT(FIRST_X_ASSUM(MP_TAC o
4697      GEN_REWRITE_RULE I [GSYM REAL_LT_SQUARE])) THEN
4698     REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP REAL_LT_MUL) THEN
4699     REAL_ARITH_TAC;
4700     ALL_TAC] THEN
4701   ASM_SIMP_TAC[SQRT_POW_2; REAL_POW_NEG; ARITH; REAL_LT_IMP_LE] THEN
4702   REWRITE_TAC[REAL_POW_2; REAL_ARITH
4703    `a = (n + &1 - (b - a)) / &2 <=> (a + b) - &1 = n`] THEN
4704   REWRITE_TAC[complex_norm] THEN
4705   DISCH_THEN(MP_TAC o AP_TERM `\x:real. x pow 2`) THEN
4706   SIMP_TAC[SQRT_POW_2; REWRITE_RULE[GSYM REAL_POW_2] REAL_LE_SQUARE;
4707            REAL_LE_ADD] THEN
4708   REWRITE_TAC[RE_SUB; RE_CX; RE_POW_2; IM_SUB; IM_CX; IM_POW_2] THEN
4709   REPEAT(FIRST_X_ASSUM(MP_TAC o
4710    GEN_REWRITE_RULE I [GSYM REAL_LT_SQUARE])) THEN
4711   REAL_ARITH_TAC);;
4712
4713 let COMPLEX_DIFFERENTIABLE_AT_CACS = prove
4714  (`!z. (Im z = &0 ==> abs(Re z) < &1) ==> cacs complex_differentiable at z`,
4715   REWRITE_TAC[complex_differentiable] THEN
4716   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CACS]);;
4717
4718 let COMPLEX_DIFFERENTIABLE_WITHIN_CACS = prove
4719  (`!s z. (Im z = &0 ==> abs(Re z) < &1)
4720          ==> cacs complex_differentiable (at z within s)`,
4721   MESON_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN;
4722             COMPLEX_DIFFERENTIABLE_AT_CACS]);;
4723
4724 add_complex_differentiation_theorems
4725  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4726    (MATCH_MP HAS_COMPLEX_DERIVATIVE_CHAIN
4727              HAS_COMPLEX_DERIVATIVE_CACS)));;
4728
4729 let CONTINUOUS_AT_CACS = prove
4730  (`!z. (Im z = &0 ==> abs(Re z) < &1) ==> cacs continuous at z`,
4731   MESON_TAC[HAS_COMPLEX_DERIVATIVE_CACS;
4732             HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_AT]);;
4733
4734 let CONTINUOUS_WITHIN_CACS = prove
4735  (`!s z. (Im z = &0 ==> abs(Re z) < &1) ==> cacs continuous (at z within s)`,
4736   MESON_TAC[CONTINUOUS_AT_WITHIN; CONTINUOUS_AT_CACS]);;
4737
4738 let CONTINUOUS_ON_CACS = prove
4739  (`!s. (!z. z IN s /\ Im z = &0 ==> abs(Re z) < &1) ==> cacs continuous_on s`,
4740   MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_CACS]);;
4741
4742 let HOLOMORPHIC_ON_CACS = prove
4743  (`!s. (!z. z IN s /\ Im z = &0 ==> abs(Re z) < &1) ==> cacs holomorphic_on s`,
4744   REWRITE_TAC [holomorphic_on] THEN
4745   MESON_TAC [HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CACS]);;
4746
4747 (* ------------------------------------------------------------------------- *)
4748 (* Some crude range theorems (could be sharpened).                           *)
4749 (* ------------------------------------------------------------------------- *)
4750
4751 let CASN_RANGE_LEMMA = prove
4752  (`!z. abs (Re z) < &1 ==> &0 < Re(ii * z + csqrt(Cx(&1) - z pow 2))`,
4753   REPEAT STRIP_TAC THEN REWRITE_TAC[RE_ADD; RE_MUL_II] THEN
4754   REWRITE_TAC[REAL_ARITH `&0 < --i + r <=> i < r`] THEN
4755   REWRITE_TAC[csqrt; IM_SUB; RE_SUB; COMPLEX_POW_2; RE_CX; IM_CX] THEN
4756   REWRITE_TAC[complex_mul; RE; IM] THEN REWRITE_TAC[GSYM complex_mul] THEN
4757   REWRITE_TAC[REAL_ARITH `r * i + i * r = &2 * r * i`] THEN
4758   REWRITE_TAC[REAL_SUB_LZERO; REAL_NEG_EQ_0; REAL_ABS_NEG] THEN
4759   REWRITE_TAC[REAL_NEG_SUB; REAL_ENTIRE; REAL_OF_NUM_EQ; ARITH] THEN
4760   MAP_EVERY ASM_CASES_TAC [`Re z = &0`; `Im z = &0`] THEN
4761   ASM_REWRITE_TAC[REAL_SUB_LZERO; REAL_SUB_RZERO] THEN
4762   CONV_TAC REAL_RAT_REDUCE_CONV THEN
4763   REWRITE_TAC[RE; SQRT_1] THEN CONV_TAC REAL_RAT_REDUCE_CONV THENL
4764    [REWRITE_TAC[REAL_ARITH `&1 - (&0 - z) = &1 + z`] THEN
4765     SIMP_TAC[REAL_LE_ADD; REAL_POS; REAL_LE_SQUARE; RE] THEN
4766     MATCH_MP_TAC REAL_LT_RSQRT THEN REAL_ARITH_TAC;
4767     SUBGOAL_THEN `Re(z) pow 2 < &1 pow 2` MP_TAC THENL
4768      [ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN MATCH_MP_TAC REAL_POW_LT2 THEN
4769       ASM_REWRITE_TAC[REAL_ABS_POS; REAL_ABS_NUM; ARITH];
4770       REWRITE_TAC[REAL_POW_ONE] THEN STRIP_TAC] THEN
4771     COND_CASES_TAC THEN ASM_REWRITE_TAC[RE] THEN
4772     TRY(MATCH_MP_TAC SQRT_POS_LT) THEN ASM_REAL_ARITH_TAC;
4773     MATCH_MP_TAC REAL_LT_RSQRT THEN
4774     REWRITE_TAC[REAL_POW_2; REAL_ARITH
4775      `a < (n + &1 - (b - a)) / &2 <=> (a + b) - &1 < n`] THEN
4776     REWRITE_TAC[complex_norm] THEN MATCH_MP_TAC REAL_LT_RSQRT THEN
4777     REWRITE_TAC[RE_SUB; IM_SUB; RE_CX; IM_CX] THEN
4778     REWRITE_TAC[complex_mul; RE; IM] THEN
4779     REPEAT(FIRST_X_ASSUM(MP_TAC o
4780       GEN_REWRITE_RULE I [GSYM REAL_LT_SQUARE])) THEN
4781     REAL_ARITH_TAC]);;
4782
4783 let CACS_RANGE_LEMMA = prove
4784  (`!z. abs(Re z) < &1 ==> &0 < Im(z + ii * csqrt(Cx(&1) - z pow 2))`,
4785   REPEAT STRIP_TAC THEN MP_TAC(SPEC `--z:complex` CASN_RANGE_LEMMA) THEN
4786   ASM_SIMP_TAC[IM_NEG; RE_NEG; IM_ADD; RE_ADD; IM_MUL_II; RE_MUL_II;
4787                COMPLEX_POW_NEG; ARITH; REAL_ABS_NEG] THEN
4788   REAL_ARITH_TAC);;
4789
4790 let RE_CASN = prove
4791  (`!z. Re(casn z) = Im(clog(ii * z + csqrt(Cx(&1) - z pow 2)))`,
4792   REWRITE_TAC[casn; COMPLEX_MUL_LNEG; RE_NEG; RE_MUL_II; REAL_NEGNEG]);;
4793
4794 let RE_CACS = prove
4795  (`!z. Re(cacs z) = Im(clog(z + ii * csqrt(Cx(&1) - z pow 2)))`,
4796   REWRITE_TAC[cacs; COMPLEX_MUL_LNEG; RE_NEG; RE_MUL_II; REAL_NEGNEG]);;
4797
4798 let CASN_BOUNDS = prove
4799  (`!z. abs(Re z) < &1 ==> abs(Re(casn z)) < pi / &2`,
4800   GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[RE_CASN] THEN
4801   MATCH_MP_TAC RE_CLOG_POS_LT_IMP THEN ASM_SIMP_TAC[CASN_RANGE_LEMMA]);;
4802
4803 let CACS_BOUNDS = prove
4804  (`!z. abs(Re z) < &1 ==> &0 < Re(cacs z) /\ Re(cacs z) < pi`,
4805   GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[RE_CACS] THEN
4806   MATCH_MP_TAC IM_CLOG_POS_LT_IMP THEN ASM_SIMP_TAC[CACS_RANGE_LEMMA]);;
4807
4808 let RE_CACS_BOUNDS = prove
4809  (`!z. --pi < Re(cacs z) /\ Re(cacs z) <= pi`,
4810   REWRITE_TAC[RE_CACS] THEN SIMP_TAC[CLOG_WORKS; CACS_BODY_LEMMA]);;
4811
4812 let RE_CACS_BOUND = prove
4813  (`!z. abs(Re(cacs z)) <= pi`,
4814   MP_TAC RE_CACS_BOUNDS THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);;
4815
4816 let RE_CASN_BOUNDS = prove
4817  (`!z. --pi < Re(casn z) /\ Re(casn z) <= pi`,
4818   REWRITE_TAC[RE_CASN] THEN SIMP_TAC[CLOG_WORKS; CASN_BODY_LEMMA]);;
4819
4820 let RE_CASN_BOUND = prove
4821  (`!z. abs(Re(casn z)) <= pi`,
4822   MP_TAC RE_CASN_BOUNDS THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);;
4823
4824 (* ------------------------------------------------------------------------- *)
4825 (* Interrelations between the two functions.                                 *)
4826 (* ------------------------------------------------------------------------- *)
4827
4828 let CCOS_CASN_NZ = prove
4829  (`!z. ~(z pow 2 = Cx(&1)) ==> ~(ccos(casn z) = Cx(&0))`,
4830   REWRITE_TAC[ccos; casn; CEXP_NEG; COMPLEX_RING `ii * --ii * z = z`;
4831               COMPLEX_RING `--ii * --ii * z = --z`] THEN
4832   SIMP_TAC[CEXP_CLOG; CASN_BODY_LEMMA;
4833            COMPLEX_FIELD `~(x = Cx(&0))
4834                           ==> ((x + inv(x)) / Cx(&2) = Cx(&0) <=>
4835                                 x pow 2 = --Cx(&1))`] THEN
4836   SIMP_TAC[CSQRT; COMPLEX_FIELD
4837               `s pow 2 = Cx(&1) - z pow 2
4838                ==> ((ii * z + s) pow 2 = --Cx(&1) <=>
4839                     ii * s * z = Cx(&1) - z pow 2)`] THEN
4840   GEN_TAC THEN STRIP_TAC THEN
4841   MATCH_MP_TAC(COMPLEX_RING
4842    `~(x pow 2 + y pow 2 = Cx(&0)) ==> ~(ii * x = y)`) THEN
4843   REPEAT(POP_ASSUM MP_TAC) THEN
4844   MP_TAC(SPEC `Cx(&1) - z pow 2` CSQRT) THEN CONV_TAC COMPLEX_RING);;
4845
4846 let CSIN_CACS_NZ = prove
4847  (`!z. ~(z pow 2 = Cx(&1)) ==> ~(csin(cacs z) = Cx(&0))`,
4848   REWRITE_TAC[csin; cacs; CEXP_NEG; COMPLEX_RING `ii * --ii * z = z`;
4849               COMPLEX_RING `--ii * --ii * z = --z`] THEN
4850   SIMP_TAC[CEXP_CLOG; CACS_BODY_LEMMA;
4851            COMPLEX_FIELD `~(x = Cx(&0))
4852                           ==> ((x - inv(x)) / (Cx(&2) * ii) = Cx(&0) <=>
4853                                 x pow 2 = Cx(&1))`] THEN
4854   SIMP_TAC[CSQRT; COMPLEX_FIELD
4855               `s pow 2 = Cx(&1) - z pow 2
4856                ==> ((z + ii * s) pow 2 = Cx(&1) <=>
4857                     ii * s * z = Cx(&1) - z pow 2)`] THEN
4858   GEN_TAC THEN STRIP_TAC THEN
4859   MATCH_MP_TAC(COMPLEX_RING
4860    `~(x pow 2 + y pow 2 = Cx(&0)) ==> ~(ii * x = y)`) THEN
4861   REPEAT(POP_ASSUM MP_TAC) THEN
4862   MP_TAC(SPEC `Cx(&1) - z pow 2` CSQRT) THEN CONV_TAC COMPLEX_RING);;
4863
4864 let CCOS_CSIN_CSQRT = prove
4865  (`!z. &0 < cos(Re z) \/ cos(Re z) = &0 /\ Im(z) * sin(Re z) <= &0
4866        ==> ccos(z) = csqrt(Cx(&1) - csin(z) pow 2)`,
4867   REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC CSQRT_UNIQUE THEN
4868   REWRITE_TAC[COMPLEX_EQ_SUB_LADD] THEN ONCE_REWRITE_TAC[COMPLEX_ADD_SYM] THEN
4869   REWRITE_TAC[CSIN_CIRCLE] THEN REWRITE_TAC[RE_CCOS; IM_CCOS] THEN
4870   ASM_SIMP_TAC[REAL_LT_MUL_EQ; REAL_HALF; REAL_LT_ADD; REAL_EXP_POS_LT] THEN
4871   DISJ2_TAC THEN REWRITE_TAC[REAL_MUL_RZERO] THEN
4872   FIRST_ASSUM(MP_TAC o MATCH_MP(REAL_ARITH
4873    `x * y <= &0 ==> &0 <= --x * y`)) THEN
4874   REWRITE_TAC[REAL_MUL_POS_LE] THEN
4875   SIMP_TAC[REAL_ARITH `x / &2 = &0 <=> x = &0`; REAL_LT_RDIV_EQ; REAL_ADD_LID;
4876            REAL_SUB_LT; REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH; REAL_MUL_LZERO;
4877            REAL_SUB_0; REAL_EXP_MONO_LT; REAL_LT_SUB_RADD; REAL_EXP_INJ] THEN
4878   REAL_ARITH_TAC);;
4879
4880 let CSIN_CCOS_CSQRT = prove
4881  (`!z. &0 < sin(Re z) \/ sin(Re z) = &0 /\ &0 <= Im(z) * cos(Re z)
4882        ==> csin(z) = csqrt(Cx(&1) - ccos(z) pow 2)`,
4883   REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC CSQRT_UNIQUE THEN
4884   REWRITE_TAC[COMPLEX_EQ_SUB_LADD] THEN ONCE_REWRITE_TAC[COMPLEX_ADD_SYM] THEN
4885   REWRITE_TAC[ONCE_REWRITE_RULE[COMPLEX_ADD_SYM] CSIN_CIRCLE] THEN
4886   REWRITE_TAC[RE_CSIN; IM_CSIN] THEN
4887   ASM_SIMP_TAC[REAL_LT_MUL_EQ; REAL_HALF; REAL_LT_ADD; REAL_EXP_POS_LT] THEN
4888   DISJ2_TAC THEN REWRITE_TAC[REAL_MUL_RZERO] THEN
4889   REPEAT(POP_ASSUM MP_TAC) THEN
4890   REWRITE_TAC[REAL_MUL_POS_LE] THEN
4891   SIMP_TAC[REAL_ARITH `x / &2 = &0 <=> x = &0`; REAL_LT_RDIV_EQ; REAL_ADD_LID;
4892            REAL_SUB_LT; REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH; REAL_MUL_LZERO;
4893
4894            REAL_SUB_0; REAL_EXP_MONO_LT; REAL_LT_SUB_RADD; REAL_EXP_INJ] THEN
4895   REAL_ARITH_TAC);;
4896
4897 let CASN_CACS_SQRT_POS = prove
4898  (`!z. (&0 < Re z \/ Re z = &0 /\ &0 <= Im z)
4899        ==> casn(z) = cacs(csqrt(Cx(&1) - z pow 2))`,
4900   GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[casn; cacs] THEN
4901   AP_TERM_TAC THEN AP_TERM_TAC THEN
4902   MATCH_MP_TAC(COMPLEX_RING `w = z ==> ii * z + s = s + ii * w`) THEN
4903   MATCH_MP_TAC CSQRT_UNIQUE THEN
4904   ASM_REWRITE_TAC[CSQRT] THEN CONV_TAC COMPLEX_RING);;
4905
4906 let CACS_CASN_SQRT_POS = prove
4907  (`!z. (&0 < Re z \/ Re z = &0 /\ &0 <= Im z)
4908        ==> cacs(z) = casn(csqrt(Cx(&1) - z pow 2))`,
4909   GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[casn; cacs] THEN
4910   AP_TERM_TAC THEN AP_TERM_TAC THEN
4911   MATCH_MP_TAC(COMPLEX_RING `w = z ==> z + ii * s = ii * s + w`) THEN
4912   MATCH_MP_TAC CSQRT_UNIQUE THEN
4913   ASM_REWRITE_TAC[CSQRT] THEN CONV_TAC COMPLEX_RING);;
4914
4915 let CSIN_CACS = prove
4916  (`!z. &0 < Re z \/ Re(z) = &0 /\ &0 <= Im z
4917        ==> csin(cacs z) = csqrt(Cx(&1) - z pow 2)`,
4918   GEN_TAC THEN DISCH_TAC THEN
4919   GEN_REWRITE_TAC RAND_CONV [GSYM CSIN_CASN] THEN
4920   AP_TERM_TAC THEN MATCH_MP_TAC CACS_CASN_SQRT_POS THEN
4921   ASM_REWRITE_TAC[]);;
4922
4923 let CCOS_CASN = prove
4924  (`!z. &0 < Re z \/ Re(z) = &0 /\ &0 <= Im z
4925        ==> ccos(casn z) = csqrt(Cx(&1) - z pow 2)`,
4926   GEN_TAC THEN DISCH_TAC THEN
4927   GEN_REWRITE_TAC RAND_CONV [GSYM CCOS_CACS] THEN
4928   AP_TERM_TAC THEN MATCH_MP_TAC CASN_CACS_SQRT_POS THEN
4929   ASM_REWRITE_TAC[]);;
4930
4931 (* ------------------------------------------------------------------------- *)
4932 (* Real arcsin.                                                              *)
4933 (* ------------------------------------------------------------------------- *)
4934
4935 let asn = new_definition `asn(x) = Re(casn(Cx x))`;;
4936
4937 let REAL_ASN = prove
4938  (`!z. real z /\ abs(Re z) <= &1 ==> real(casn z)`,
4939   GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
4940   GEN_REWRITE_TAC LAND_CONV [REAL] THEN
4941   DISCH_THEN(SUBST1_TAC o SYM) THEN SPEC_TAC(`Re z`,`x:real`) THEN
4942   REWRITE_TAC[real; casn; COMPLEX_MUL_LNEG; IM_NEG; IM_MUL_II] THEN
4943   GEN_TAC THEN REWRITE_TAC[RE_CX; REAL_NEG_EQ_0] THEN DISCH_TAC THEN
4944   MATCH_MP_TAC NORM_CEXP_IMAGINARY THEN
4945   SIMP_TAC[CEXP_CLOG; CASN_BODY_LEMMA; NORM_EQ_SQUARE] THEN
4946   REWRITE_TAC[DOT_SQUARE_NORM; COMPLEX_SQNORM] THEN
4947   REWRITE_TAC[RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II; RE_CX; IM_CX] THEN
4948   ASM_SIMP_TAC[GSYM CX_POW; GSYM CX_SUB; GSYM CX_SQRT; REAL_SUB_LE;
4949                ABS_SQUARE_LE_1; RE_CX; IM_CX; REAL_NEG_0; REAL_ADD_LID;
4950                SQRT_POW_2] THEN
4951   REAL_ARITH_TAC);;
4952
4953 let CX_ASN = prove
4954  (`!x. abs(x) <= &1 ==> Cx(asn x) = casn(Cx x)`,
4955   REWRITE_TAC[asn] THEN MESON_TAC[REAL; RE_CX; REAL_CX; REAL_ASN]);;
4956
4957 let SIN_ASN = prove
4958  (`!y. --(&1) <= y /\ y <= &1 ==> sin(asn(y)) = y`,
4959   REWRITE_TAC[REAL_ARITH `--(&1) <= y /\ y <= &1 <=> abs(y) <= &1`] THEN
4960   ONCE_REWRITE_TAC[GSYM CX_INJ] THEN SIMP_TAC[CX_ASN; CX_SIN; CSIN_CASN]);;
4961
4962 let ASN_SIN = prove
4963  (`!x. --(pi / &2) <= x /\ x <= pi / &2 ==> asn(sin(x)) = x`,
4964   ONCE_REWRITE_TAC[GSYM CX_INJ] THEN SIMP_TAC[CX_ASN; SIN_BOUND; CX_SIN] THEN
4965   REPEAT STRIP_TAC THEN MATCH_MP_TAC CASN_CSIN THEN
4966   REWRITE_TAC[IM_CX; RE_CX] THEN REPEAT(POP_ASSUM MP_TAC) THEN
4967   REAL_ARITH_TAC);;
4968
4969 let ASN_BOUNDS_LT = prove
4970  (`!y. --(&1) < y /\ y < &1 ==> --(pi / &2) < asn(y) /\ asn(y) < pi / &2`,
4971   GEN_TAC THEN REWRITE_TAC[asn] THEN
4972   MP_TAC(SPEC `Cx y` CASN_BOUNDS) THEN
4973   REWRITE_TAC[RE_CX] THEN REAL_ARITH_TAC);;
4974
4975 let ASN_0 = prove
4976  (`asn(&0) = &0`,
4977   REWRITE_TAC[asn; CASN_0; RE_CX]);;
4978
4979 let ASN_1 = prove
4980  (`asn(&1) = pi / &2`,
4981   REWRITE_TAC[asn; CASN_1; RE_CX]);;
4982
4983 let ASN_NEG_1 = prove
4984  (`asn(-- &1) = --(pi / &2)`,
4985   REWRITE_TAC[asn; CX_NEG; CASN_NEG_1; RE_CX; RE_NEG]);;
4986
4987 let ASN_BOUNDS = prove
4988  (`!y. --(&1) <= y /\ y <= &1 ==> --(pi / &2) <= asn(y) /\ asn(y) <= pi / &2`,
4989   REWRITE_TAC[REAL_LE_LT] THEN REPEAT STRIP_TAC THEN
4990   MAP_EVERY MP_TAC [ASN_1; ASN_NEG_1; SPEC `y:real` ASN_BOUNDS_LT] THEN
4991   ASM_REWRITE_TAC[] THEN REPEAT(POP_ASSUM MP_TAC) THEN
4992   MP_TAC PI_POS THEN REAL_ARITH_TAC);;
4993
4994 let ASN_NEG = prove
4995  (`!x. -- &1 <= x /\ x <= &1 ==> asn(--x) = --asn(x)`,
4996   GEN_TAC THEN DISCH_TAC THEN
4997   FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o RAND_CONV)
4998      [GSYM(MATCH_MP SIN_ASN th)]) THEN
4999   REWRITE_TAC[GSYM SIN_NEG] THEN MATCH_MP_TAC ASN_SIN THEN
5000   REWRITE_TAC[REAL_ARITH `--a <= --x /\ --x <= a <=> --a <= x /\ x <= a`] THEN
5001   ASM_SIMP_TAC[ASN_BOUNDS]);;
5002
5003 let COS_ASN_NZ = prove
5004  (`!x. --(&1) < x /\ x < &1 ==> ~(cos(asn(x)) = &0)`,
5005   ONCE_REWRITE_TAC[GSYM CX_INJ] THEN SIMP_TAC[CX_ASN; CX_COS;
5006     REAL_ARITH `--(&1) < x /\ x < &1 ==> abs(x) <= &1`] THEN
5007   GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC CCOS_CASN_NZ THEN
5008   SIMP_TAC[COMPLEX_RING `x pow 2 = Cx(&1) <=> x = Cx(&1) \/ x = --Cx(&1)`] THEN
5009   REWRITE_TAC[GSYM CX_NEG; CX_INJ] THEN
5010   ASM_REAL_ARITH_TAC);;
5011
5012 let ASN_MONO_LT_EQ = prove
5013  (`!x y. abs(x) <= &1 /\ abs(y) <= &1 ==> (asn(x) < asn(y) <=> x < y)`,
5014   REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
5015   EXISTS_TAC `sin(asn(x)) < sin(asn(y))` THEN CONJ_TAC THENL
5016    [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SIN_MONO_LT_EQ THEN
5017     ONCE_REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THEN MATCH_MP_TAC ASN_BOUNDS;
5018     BINOP_TAC THEN MATCH_MP_TAC SIN_ASN] THEN
5019   ASM_REAL_ARITH_TAC);;
5020
5021 let ASN_MONO_LE_EQ = prove
5022  (`!x y. abs(x) <= &1 /\ abs(y) <= &1 ==> (asn(x) <= asn(y) <=> x <= y)`,
5023   REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
5024   ASM_SIMP_TAC[ASN_MONO_LT_EQ]);;
5025
5026 let ASN_MONO_LT = prove
5027  (`!x y. --(&1) <= x /\ x < y /\ y <= &1 ==> asn(x) < asn(y)`,
5028   MP_TAC ASN_MONO_LT_EQ THEN REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
5029   REAL_ARITH_TAC);;
5030
5031 let ASN_MONO_LE = prove
5032  (`!x y. --(&1) <= x /\ x <= y /\ y <= &1 ==> asn(x) <= asn(y)`,
5033   MP_TAC ASN_MONO_LE_EQ THEN REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
5034   REAL_ARITH_TAC);;
5035
5036 let COS_ASN = prove
5037  (`!x. --(&1) <= x /\ x <= &1 ==> cos(asn x) = sqrt(&1 - x pow 2)`,
5038   REPEAT STRIP_TAC THEN MATCH_MP_TAC(GSYM SQRT_UNIQUE) THEN
5039   ASM_SIMP_TAC[ASN_BOUNDS; COS_POS_PI_LE; REAL_EQ_SUB_RADD] THEN
5040   ASM_MESON_TAC[SIN_ASN; SIN_CIRCLE; REAL_ADD_SYM]);;
5041
5042 (* ------------------------------------------------------------------------- *)
5043 (* Real arccosine.                                                           *)
5044 (* ------------------------------------------------------------------------- *)
5045
5046 let acs = new_definition `acs(x) = Re(cacs(Cx x))`;;
5047
5048 let REAL_ACS = prove
5049  (`!z. real z /\ abs(Re z) <= &1 ==> real(cacs z)`,
5050   GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
5051   GEN_REWRITE_TAC LAND_CONV [REAL] THEN
5052   DISCH_THEN(SUBST1_TAC o SYM) THEN SPEC_TAC(`Re z`,`x:real`) THEN
5053   REWRITE_TAC[real; cacs; COMPLEX_MUL_LNEG; IM_NEG; IM_MUL_II] THEN
5054   GEN_TAC THEN REWRITE_TAC[RE_CX; REAL_NEG_EQ_0] THEN DISCH_TAC THEN
5055   MATCH_MP_TAC NORM_CEXP_IMAGINARY THEN
5056   SIMP_TAC[CEXP_CLOG; CACS_BODY_LEMMA; NORM_EQ_SQUARE] THEN
5057   REWRITE_TAC[DOT_SQUARE_NORM; COMPLEX_SQNORM] THEN
5058   REWRITE_TAC[RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II; RE_CX; IM_CX] THEN
5059   ASM_SIMP_TAC[GSYM CX_POW; GSYM CX_SUB; GSYM CX_SQRT; REAL_SUB_LE;
5060                ABS_SQUARE_LE_1; RE_CX; IM_CX; REAL_NEG_0; REAL_ADD_LID;
5061                SQRT_POW_2] THEN
5062   REAL_ARITH_TAC);;
5063
5064 let CX_ACS = prove
5065  (`!x. abs(x) <= &1 ==> Cx(acs x) = cacs(Cx x)`,
5066   REWRITE_TAC[acs] THEN MESON_TAC[REAL; RE_CX; REAL_CX; REAL_ACS]);;
5067
5068 let COS_ACS = prove
5069  (`!y. --(&1) <= y /\ y <= &1 ==> cos(acs(y)) = y`,
5070   REWRITE_TAC[REAL_ARITH `--(&1) <= y /\ y <= &1 <=> abs(y) <= &1`] THEN
5071   ONCE_REWRITE_TAC[GSYM CX_INJ] THEN SIMP_TAC[CX_ACS; CX_COS; CCOS_CACS]);;
5072
5073 let ACS_COS = prove
5074  (`!x. &0 <= x /\ x <= pi ==> acs(cos(x)) = x`,
5075   ONCE_REWRITE_TAC[GSYM CX_INJ] THEN SIMP_TAC[CX_ACS; COS_BOUND; CX_COS] THEN
5076   REPEAT STRIP_TAC THEN MATCH_MP_TAC CACS_CCOS THEN
5077   REWRITE_TAC[IM_CX; RE_CX] THEN ASM_REAL_ARITH_TAC);;
5078
5079 let ACS_BOUNDS_LT = prove
5080  (`!y. --(&1) < y /\ y < &1 ==> &0 < acs(y) /\ acs(y) < pi`,
5081   GEN_TAC THEN REWRITE_TAC[acs] THEN
5082   MP_TAC(SPEC `Cx y` CACS_BOUNDS) THEN
5083   REWRITE_TAC[RE_CX] THEN REAL_ARITH_TAC);;
5084
5085 let ACS_0 = prove
5086  (`acs(&0) = pi / &2`,
5087   REWRITE_TAC[acs; CACS_0; RE_CX]);;
5088
5089 let ACS_1 = prove
5090  (`acs(&1) = &0`,
5091   REWRITE_TAC[acs; CACS_1; RE_CX]);;
5092
5093 let ACS_NEG_1 = prove
5094  (`acs(-- &1) = pi`,
5095   REWRITE_TAC[acs; CX_NEG; CACS_NEG_1; RE_CX; RE_NEG]);;
5096
5097 let ACS_BOUNDS = prove
5098  (`!y. --(&1) <= y /\ y <= &1 ==> &0 <= acs(y) /\ acs(y) <= pi`,
5099   REWRITE_TAC[REAL_LE_LT] THEN REPEAT STRIP_TAC THEN
5100   MAP_EVERY MP_TAC [ACS_1; ACS_NEG_1; SPEC `y:real` ACS_BOUNDS_LT] THEN
5101   ASM_REWRITE_TAC[] THEN REPEAT(POP_ASSUM MP_TAC) THEN
5102   MP_TAC PI_POS THEN REAL_ARITH_TAC);;
5103
5104 let ACS_NEG = prove
5105  (`!x. -- &1 <= x /\ x <= &1 ==> acs(--x) = pi - acs(x)`,
5106   GEN_TAC THEN DISCH_TAC THEN
5107   FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o RAND_CONV)
5108      [GSYM(MATCH_MP COS_ACS th)]) THEN
5109   ONCE_REWRITE_TAC[GSYM COS_NEG] THEN REWRITE_TAC[GSYM COS_PERIODIC_PI] THEN
5110   REWRITE_TAC[REAL_ARITH `--x + y:real = y - x`] THEN MATCH_MP_TAC ACS_COS THEN
5111   SIMP_TAC[REAL_ARITH `&0 <= p - x /\ p - x <= p <=> &0 <= x /\ x <= p`] THEN
5112   ASM_SIMP_TAC[ACS_BOUNDS]);;
5113
5114 let SIN_ACS_NZ = prove
5115  (`!x. --(&1) < x /\ x < &1 ==> ~(sin(acs(x)) = &0)`,
5116   ONCE_REWRITE_TAC[GSYM CX_INJ] THEN SIMP_TAC[CX_ACS; CX_SIN;
5117     REAL_ARITH `--(&1) < x /\ x < &1 ==> abs(x) <= &1`] THEN
5118   GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC CSIN_CACS_NZ THEN
5119   SIMP_TAC[COMPLEX_RING `x pow 2 = Cx(&1) <=> x = Cx(&1) \/ x = --Cx(&1)`] THEN
5120   REWRITE_TAC[GSYM CX_NEG; CX_INJ] THEN
5121   ASM_REAL_ARITH_TAC);;
5122
5123 let ACS_MONO_LT_EQ = prove
5124  (`!x y. abs(x) <= &1 /\ abs(y) <= &1 ==> (acs(x) < acs(y) <=> y < x)`,
5125   REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
5126   EXISTS_TAC `cos(acs(y)) < cos(acs(x))` THEN CONJ_TAC THENL
5127    [CONV_TAC SYM_CONV THEN MATCH_MP_TAC COS_MONO_LT_EQ THEN
5128     ONCE_REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THEN MATCH_MP_TAC ACS_BOUNDS;
5129     BINOP_TAC THEN MATCH_MP_TAC COS_ACS] THEN
5130   ASM_REAL_ARITH_TAC);;
5131
5132 let ACS_MONO_LE_EQ = prove
5133  (`!x y. abs(x) <= &1 /\ abs(y) <= &1 ==> (acs(x) <= acs(y) <=> y <= x)`,
5134   REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
5135   ASM_SIMP_TAC[ACS_MONO_LT_EQ]);;
5136
5137 let ACS_MONO_LT = prove
5138  (`!x y. --(&1) <= x /\ x < y /\ y <= &1 ==> acs(y) < acs(x)`,
5139   REPEAT GEN_TAC THEN
5140   MP_TAC(SPECL [`y:real`; `x:real`] ACS_MONO_LT_EQ) THEN
5141   REAL_ARITH_TAC);;
5142
5143 let ACS_MONO_LE = prove
5144  (`!x y. --(&1) <= x /\ x <= y /\ y <= &1 ==> acs(y) <= acs(x)`,
5145   REPEAT GEN_TAC THEN
5146   MP_TAC(SPECL [`y:real`; `x:real`] ACS_MONO_LE_EQ) THEN
5147   REAL_ARITH_TAC);;
5148
5149 let SIN_ACS = prove
5150  (`!x. --(&1) <= x /\ x <= &1 ==> sin(acs x) = sqrt(&1 - x pow 2)`,
5151   REPEAT STRIP_TAC THEN MATCH_MP_TAC(GSYM SQRT_UNIQUE) THEN
5152   ASM_SIMP_TAC[ACS_BOUNDS; SIN_POS_PI_LE; REAL_EQ_SUB_RADD] THEN
5153   ASM_MESON_TAC[COS_ACS; SIN_CIRCLE]);;
5154
5155 let ACS_INJ = prove
5156  (`!x y. abs(x) <= &1 /\ abs(y) <= &1 ==> (acs x = acs y <=> x = y)`,
5157   REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
5158   ASM_SIMP_TAC[ACS_MONO_LE_EQ] THEN REAL_ARITH_TAC);;
5159
5160 (* ------------------------------------------------------------------------- *)
5161 (* Some interrelationships among the real inverse trig functions.            *)
5162 (* ------------------------------------------------------------------------- *)
5163
5164 let ACS_ATN = prove
5165  (`!x. -- &1 < x /\ x < &1 ==> acs(x) = pi / &2 - atn(x / sqrt(&1 - x pow 2))`,
5166   REPEAT STRIP_TAC THEN
5167   ONCE_REWRITE_TAC[REAL_ARITH `x:real = p - y <=> y - (p - x) = &0`] THEN
5168   MATCH_MP_TAC SIN_EQ_0_PI THEN
5169   ASM_SIMP_TAC[ATN_BOUND; ACS_BOUNDS; REAL_LT_IMP_LE; REAL_ARITH
5170    `abs(x) < pi / &2 /\ &0 <= y /\ y <= pi
5171     ==> --pi < x - (pi / &2 - y) /\ x - (pi / &2 - y) < pi`] THEN
5172   SUBGOAL_THEN `tan(atn(x / sqrt(&1 - x pow 2))) = tan(pi / &2 - acs x)`
5173   MP_TAC THENL
5174    [REWRITE_TAC[TAN_COT; ATN_TAN] THEN REWRITE_TAC[tan] THEN
5175     ASM_SIMP_TAC[SIN_ACS; COS_ACS; REAL_LT_IMP_LE; REAL_INV_DIV];
5176     ALL_TAC] THEN
5177   GEN_REWRITE_TAC LAND_CONV [GSYM REAL_SUB_0] THEN
5178   ASM_SIMP_TAC[SIN_ACS_NZ; GSYM SIN_COS; COS_ATN_NZ; REAL_SUB_TAN; REAL_FIELD
5179    `~(y = &0) /\ ~(z = &0) ==> (x / (y * z) = &0 <=> x = &0)`]);;
5180
5181 let ASN_PLUS_ACS = prove
5182  (`!x. -- &1 <= x /\ x <= &1 ==> asn(x) + acs(x) = pi / &2`,
5183   REPEAT STRIP_TAC THEN
5184   ONCE_REWRITE_TAC[REAL_ARITH `x + y:real = p <=> x = p - y`] THEN
5185   MATCH_MP_TAC SIN_INJ_PI THEN
5186   ASM_SIMP_TAC[SIN_PI2; COS_PI2; SIN_SUB; REAL_MUL_LZERO; REAL_SUB_RZERO] THEN
5187   ASM_SIMP_TAC[SIN_ASN; COS_ACS; REAL_MUL_LID] THEN
5188   REWRITE_TAC[REAL_ARITH `--p <= p - x <=> x <= &2 * p`;
5189               REAL_ARITH `p - x <= p <=> &0 <= x`] THEN
5190   ASM_SIMP_TAC[ASN_BOUNDS; ACS_BOUNDS; REAL_ARITH `&2 * x / &2 = x`]);;
5191
5192 let ASN_ACS = prove
5193  (`!x. -- &1 <= x /\ x <= &1 ==> asn(x) = pi / &2 - acs(x)`,
5194   SIMP_TAC[REAL_EQ_SUB_LADD; ASN_PLUS_ACS]);;
5195
5196 let ACS_ASN = prove
5197  (`!x. -- &1 <= x /\ x <= &1 ==> acs(x) = pi / &2 - asn(x)`,
5198   SIMP_TAC[ASN_ACS] THEN REAL_ARITH_TAC);;
5199
5200 let ASN_ATN = prove
5201  (`!x. -- &1 < x /\ x < &1 ==> asn(x) = atn(x / sqrt(&1 - x pow 2))`,
5202   SIMP_TAC[ASN_ACS; REAL_LT_IMP_LE; ACS_ATN] THEN REAL_ARITH_TAC);;
5203
5204 let ASN_ACS_SQRT_POS = prove
5205  (`!x. &0 <= x /\ x <= &1 ==> asn(x) = acs(sqrt(&1 - x pow 2))`,
5206   REPEAT STRIP_TAC THEN REWRITE_TAC[asn; acs] THEN
5207   ASM_SIMP_TAC[CX_SQRT; REAL_SUB_LE; REAL_POW_1_LE; CX_SUB; CX_POW] THEN
5208   AP_TERM_TAC THEN MATCH_MP_TAC CASN_CACS_SQRT_POS THEN
5209   ASM_REWRITE_TAC[RE_CX; IM_CX] THEN ASM_REAL_ARITH_TAC);;
5210
5211 let ASN_ACS_SQRT_NEG = prove
5212  (`!x. -- &1 <= x /\ x <= &0 ==> asn(x) = --acs(sqrt(&1 - x pow 2))`,
5213   REPEAT STRIP_TAC THEN
5214   ONCE_REWRITE_TAC[REAL_ARITH `x = --y <=> (--x:real) = y`] THEN
5215   ASM_SIMP_TAC[GSYM ASN_NEG; REAL_ARITH `x <= &0 ==> x <= &1`] THEN
5216   ONCE_REWRITE_TAC[REAL_ARITH `(x:real) pow 2 = (--x) pow 2`] THEN
5217   MATCH_MP_TAC ASN_ACS_SQRT_POS THEN ASM_REAL_ARITH_TAC);;
5218
5219 let ACS_ASN_SQRT_POS = prove
5220  (`!x. &0 <= x /\ x <= &1 ==> acs(x) = asn(sqrt(&1 - x pow 2))`,
5221   REPEAT STRIP_TAC THEN REWRITE_TAC[asn; acs] THEN
5222   ASM_SIMP_TAC[CX_SQRT; REAL_SUB_LE; REAL_POW_1_LE; CX_SUB; CX_POW] THEN
5223   AP_TERM_TAC THEN MATCH_MP_TAC CACS_CASN_SQRT_POS THEN
5224   ASM_REWRITE_TAC[RE_CX; IM_CX] THEN ASM_REAL_ARITH_TAC);;
5225
5226 let ACS_ASN_SQRT_NEG = prove
5227  (`!x. -- &1 <= x /\ x <= &0 ==> acs(x) = pi - asn(sqrt(&1 - x pow 2))`,
5228   REPEAT STRIP_TAC THEN MP_TAC(SPEC `--x:real` ACS_ASN_SQRT_POS) THEN
5229   ANTS_TAC THENL [ASM_REAL_ARITH_TAC; SIMP_TAC[REAL_POW_NEG; ARITH]] THEN
5230   DISCH_THEN(SUBST1_TAC o SYM) THEN
5231   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM REAL_NEG_NEG] THEN
5232   MATCH_MP_TAC ACS_NEG THEN ASM_REAL_ARITH_TAC);;
5233
5234 (* ------------------------------------------------------------------------- *)
5235 (* More delicate continuity results for arcsin and arccos.                   *)
5236 (* ------------------------------------------------------------------------- *)
5237
5238 let CONTINUOUS_ON_CASN_REAL = prove
5239  (`casn continuous_on {w | real w /\ abs(Re w) <= &1}`,
5240   MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN
5241   EXISTS_TAC `IMAGE csin {z | real z /\ abs(Re z) <= pi / &2}` THEN
5242   CONJ_TAC THENL
5243    [MATCH_MP_TAC CONTINUOUS_ON_INVERSE THEN
5244     REWRITE_TAC[CONTINUOUS_ON_CSIN] THEN CONJ_TAC THENL
5245      [REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN CONJ_TAC THENL
5246        [MATCH_MP_TAC BOUNDED_SUBSET THEN
5247         EXISTS_TAC `cball(Cx(&0),pi / &2)` THEN
5248         REWRITE_TAC[BOUNDED_CBALL; SUBSET; IN_ELIM_THM; IN_CBALL] THEN
5249         REWRITE_TAC[dist; COMPLEX_SUB_LZERO; NORM_NEG; real] THEN
5250         X_GEN_TAC `z:complex` THEN
5251         MP_TAC(SPEC `z:complex` COMPLEX_NORM_LE_RE_IM) THEN REAL_ARITH_TAC;
5252         SIMP_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`;
5253                   GSYM REAL_BOUNDS_LE] THEN
5254         SIMP_TAC[CLOSED_INTER; CLOSED_REAL_SET; CLOSED_HALFSPACE_RE_LE;
5255                  REWRITE_RULE[real_ge] CLOSED_HALFSPACE_RE_GE]];
5256       SIMP_TAC[SUBSET; IMP_CONJ; FORALL_REAL; IN_ELIM_THM; RE_CX] THEN
5257       REPEAT STRIP_TAC THEN MATCH_MP_TAC CASN_CSIN THEN
5258       REWRITE_TAC[RE_CX; IM_CX] THEN ASM_REAL_ARITH_TAC];
5259     SIMP_TAC[SUBSET; IMP_CONJ; FORALL_REAL; IN_ELIM_THM; RE_CX; IN_IMAGE] THEN
5260     X_GEN_TAC `x:real` THEN DISCH_TAC THEN
5261     EXISTS_TAC `Cx(asn x)` THEN
5262     ASM_SIMP_TAC[RE_CX; ASN_BOUNDS; REAL_BOUNDS_LE; REAL_CX; SIN_ASN;
5263                  GSYM CX_SIN] THEN
5264     ASM_MESON_TAC[REAL_BOUNDS_LE; ASN_BOUNDS]]);;
5265
5266 let CONTINUOUS_WITHIN_CASN_REAL = prove
5267  (`!z. casn continuous (at z within {w | real w /\ abs(Re w) <= &1})`,
5268   GEN_TAC THEN ASM_CASES_TAC `z IN {w | real w /\ abs(Re w) <= &1}` THENL
5269    [ASM_SIMP_TAC[REWRITE_RULE[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]
5270       CONTINUOUS_ON_CASN_REAL];
5271     MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN
5272     ASM_REWRITE_TAC[] THEN REWRITE_TAC[GSYM REAL_BOUNDS_LE] THEN
5273     ASM_SIMP_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
5274     SIMP_TAC[CLOSED_INTER; CLOSED_REAL_SET; CLOSED_HALFSPACE_RE_LE;
5275              REWRITE_RULE[real_ge] CLOSED_HALFSPACE_RE_GE]]);;
5276
5277 let CONTINUOUS_ON_CACS_REAL = prove
5278  (`cacs continuous_on {w | real w /\ abs(Re w) <= &1}`,
5279   MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN
5280   EXISTS_TAC `IMAGE ccos {z | real z /\ &0 <= Re z /\ Re z <= pi}` THEN
5281   CONJ_TAC THENL
5282    [MATCH_MP_TAC CONTINUOUS_ON_INVERSE THEN
5283     REWRITE_TAC[CONTINUOUS_ON_CCOS] THEN CONJ_TAC THENL
5284      [REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN CONJ_TAC THENL
5285        [MATCH_MP_TAC BOUNDED_SUBSET THEN
5286         EXISTS_TAC `cball(Cx(&0),&2 * pi)` THEN
5287         REWRITE_TAC[BOUNDED_CBALL; SUBSET; IN_ELIM_THM; IN_CBALL] THEN
5288         REWRITE_TAC[dist; COMPLEX_SUB_LZERO; NORM_NEG; real] THEN
5289         X_GEN_TAC `z:complex` THEN
5290         MP_TAC(SPEC `z:complex` COMPLEX_NORM_LE_RE_IM) THEN REAL_ARITH_TAC;
5291         SIMP_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
5292         SIMP_TAC[CLOSED_INTER; CLOSED_REAL_SET; CLOSED_HALFSPACE_RE_LE;
5293                  REWRITE_RULE[real_ge] CLOSED_HALFSPACE_RE_GE]];
5294       SIMP_TAC[SUBSET; IMP_CONJ; FORALL_REAL; IN_ELIM_THM; RE_CX] THEN
5295       REPEAT STRIP_TAC THEN MATCH_MP_TAC CACS_CCOS THEN
5296       REWRITE_TAC[RE_CX; IM_CX] THEN ASM_REAL_ARITH_TAC];
5297     SIMP_TAC[SUBSET; IMP_CONJ; FORALL_REAL; IN_ELIM_THM; RE_CX; IN_IMAGE] THEN
5298     X_GEN_TAC `x:real` THEN DISCH_TAC THEN
5299     EXISTS_TAC `Cx(acs x)` THEN
5300     ASM_SIMP_TAC[RE_CX; ACS_BOUNDS; REAL_BOUNDS_LE; REAL_CX; COS_ACS;
5301                  GSYM CX_COS]]);;
5302
5303 let CONTINUOUS_WITHIN_CACS_REAL = prove
5304  (`!z. cacs continuous (at z within {w | real w /\ abs(Re w) <= &1})`,
5305   GEN_TAC THEN ASM_CASES_TAC `z IN {w | real w /\ abs(Re w) <= &1}` THENL
5306    [ASM_SIMP_TAC[REWRITE_RULE[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]
5307       CONTINUOUS_ON_CACS_REAL];
5308     MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN
5309     ASM_REWRITE_TAC[] THEN REWRITE_TAC[GSYM REAL_BOUNDS_LE] THEN
5310     ASM_SIMP_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
5311     SIMP_TAC[CLOSED_INTER; CLOSED_REAL_SET; CLOSED_HALFSPACE_RE_LE;
5312              REWRITE_RULE[real_ge] CLOSED_HALFSPACE_RE_GE]]);;
5313
5314 (* ------------------------------------------------------------------------- *)
5315 (* Some limits, most involving sequences of transcendentals.                 *)
5316 (* ------------------------------------------------------------------------- *)
5317
5318 let LIM_LOG_OVER_POWER = prove
5319  (`!s. &0 < Re s
5320        ==> ((\n. clog(Cx(&n)) / Cx(&n) cpow s) --> Cx(&0)) sequentially`,
5321   REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN
5322   FIRST_ASSUM(MP_TAC o SPEC `&2` o MATCH_MP REAL_ARCH) THEN
5323   DISCH_THEN(X_CHOOSE_THEN `N:num` MP_TAC) THEN
5324   ASM_CASES_TAC `N = 0` THEN
5325   ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_OF_NUM_LT; ARITH] THEN DISCH_TAC THEN
5326   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5327   MP_TAC(ISPEC `(&N / e) pow N + &1` REAL_ARCH_SIMPLE) THEN
5328   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN
5329   ASM_CASES_TAC `M = 0` THENL
5330    [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT `~a ==> a ==> b`) THEN
5331     MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> ~(x + &1 <= &0)`) THEN
5332     ASM_SIMP_TAC[REAL_POW_LE; REAL_POS; REAL_LT_IMP_LE; REAL_LE_DIV];
5333     ALL_TAC] THEN
5334   STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
5335   SUBGOAL_THEN `~(n = 0)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
5336   REWRITE_TAC[dist; COMPLEX_SUB_RZERO; COMPLEX_NORM_DIV] THEN
5337   ASM_SIMP_TAC[NORM_CPOW_REAL; REAL_CX; RE_CX; REAL_OF_NUM_LT; LT_NZ] THEN
5338   ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_EXP_POS_LT] THEN
5339   ASM_SIMP_TAC[GSYM CX_LOG; REAL_OF_NUM_LT; LT_NZ; COMPLEX_NORM_CX] THEN
5340   ASM_SIMP_TAC[real_abs; LOG_POS; REAL_OF_NUM_LE;
5341                ARITH_RULE `~(n = 0) ==> 1 <= n`] THEN
5342   MATCH_MP_TAC REAL_LET_TRANS THEN
5343   EXISTS_TAC `&N * log(exp(log(&n) / &N))` THEN CONJ_TAC THENL
5344    [ASM_SIMP_TAC[LOG_EXP; REAL_LE_REFL; REAL_DIV_LMUL; REAL_OF_NUM_EQ];
5345     ALL_TAC] THEN
5346   MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `&N * exp(log(&n) / &N)` THEN
5347   CONJ_TAC THENL
5348    [MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[REAL_POS] THEN
5349     MATCH_MP_TAC REAL_LE_TRANS THEN
5350     EXISTS_TAC `log(&1 + exp(log(&n) / &N))` THEN CONJ_TAC THENL
5351      [MATCH_MP_TAC LOG_MONO_LE_IMP THEN
5352       REWRITE_TAC[REAL_EXP_POS_LT] THEN REAL_ARITH_TAC;
5353       MATCH_MP_TAC LOG_LE THEN REWRITE_TAC[REAL_EXP_POS_LE]];
5354     ALL_TAC] THEN
5355   SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_EXP_POS_LT] THEN
5356   REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC; GSYM REAL_EXP_NEG;
5357               GSYM REAL_EXP_ADD] THEN
5358   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
5359   ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ] THEN
5360   MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `exp(log(&n) / &N)` THEN
5361   CONJ_TAC THENL
5362    [ALL_TAC;
5363     REWRITE_TAC[REAL_EXP_MONO_LE] THEN
5364     REWRITE_TAC[REAL_ARITH
5365      `l / n <= r * l + --(l * inv n) <=>  &0 <= l * (r - &2 / n)`] THEN
5366     MATCH_MP_TAC REAL_LE_MUL THEN
5367     ASM_SIMP_TAC[LOG_POS; REAL_OF_NUM_LE; ARITH_RULE `1 <= n <=> ~(n = 0)`;
5368                  REAL_SUB_LE; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LT_NZ] THEN
5369     ASM_REAL_ARITH_TAC] THEN
5370   W(MP_TAC o PART_MATCH (rand o rand) LOG_MONO_LT o snd) THEN
5371   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LT_NZ; REAL_EXP_POS_LT] THEN
5372   DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[LOG_EXP] THEN
5373   ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; LT_NZ] THEN
5374   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
5375   ASM_SIMP_TAC[GSYM LOG_POW; REAL_LT_DIV; REAL_OF_NUM_LT; LT_NZ] THEN
5376   MATCH_MP_TAC LOG_MONO_LT_IMP THEN
5377   ASM_SIMP_TAC[REAL_POW_LT; REAL_LT_DIV; REAL_OF_NUM_LT; LT_NZ] THEN
5378   MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `&M` THEN
5379   ASM_REWRITE_TAC[REAL_OF_NUM_LE] THEN ASM_REAL_ARITH_TAC);;
5380
5381 let LIM_LOG_OVER_N = prove
5382  (`((\n. clog(Cx(&n)) / Cx(&n)) --> Cx(&0)) sequentially`,
5383   MP_TAC(SPEC `Cx(&1)` LIM_LOG_OVER_POWER) THEN SIMP_TAC[RE_CX; REAL_LT_01] THEN
5384   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
5385   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; CPOW_N; CX_INJ] THEN EXISTS_TAC `1` THEN
5386   SIMP_TAC[COMPLEX_POW_1; REAL_OF_NUM_EQ; ARITH_RULE `1 <= n <=> ~(n = 0)`]);;
5387
5388 let LIM_1_OVER_POWER = prove
5389  (`!s. &0 < Re s
5390        ==> ((\n. Cx(&1) / Cx(&n) cpow s) --> Cx(&0)) sequentially`,
5391   REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_NULL_COMPLEX_BOUND THEN
5392   EXISTS_TAC `\n. clog(Cx(&n)) / Cx(&n) cpow s` THEN
5393   ASM_SIMP_TAC[LIM_LOG_OVER_POWER] THEN
5394   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
5395   MP_TAC(ISPEC `exp(&1)` REAL_ARCH_SIMPLE) THEN
5396   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
5397   ASM_CASES_TAC `N = 0` THENL
5398    [ASM_SIMP_TAC[GSYM REAL_NOT_LT; REAL_EXP_POS_LT]; ALL_TAC] THEN
5399   DISCH_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
5400   REWRITE_TAC[complex_div; COMPLEX_NORM_MUL] THEN
5401   MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN
5402   SUBGOAL_THEN `~(n = 0)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
5403   ASM_SIMP_TAC[GSYM CX_LOG; REAL_OF_NUM_LT; LT_NZ;
5404                COMPLEX_NORM_CX; REAL_ABS_NUM] THEN
5405   MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= abs y`) THEN
5406   ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LE] THEN
5407   ASM_SIMP_TAC[EXP_LOG; REAL_OF_NUM_LT; LT_NZ] THEN
5408   RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC);;
5409
5410 let LIM_1_OVER_N = prove
5411  (`((\n. Cx(&1) / Cx(&n)) --> Cx(&0)) sequentially`,
5412   MP_TAC(SPEC `Cx(&1)` LIM_1_OVER_POWER) THEN SIMP_TAC[RE_CX; REAL_LT_01] THEN
5413   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
5414   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; CPOW_N; CX_INJ] THEN EXISTS_TAC `1` THEN
5415   SIMP_TAC[COMPLEX_POW_1; REAL_OF_NUM_EQ; ARITH_RULE `1 <= n <=> ~(n = 0)`]);;
5416
5417 let LIM_INV_N = prove
5418  (`((\n. inv(Cx(&n))) --> Cx(&0)) sequentially`,
5419   MP_TAC LIM_1_OVER_N THEN REWRITE_TAC[complex_div; COMPLEX_MUL_LID]);;
5420
5421 let LIM_1_OVER_LOG = prove
5422  (`((\n. Cx(&1) / clog(Cx(&n))) --> Cx(&0)) sequentially`,
5423   REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN
5424   DISCH_TAC THEN X_CHOOSE_TAC `N:num` (SPEC `exp(inv e)` REAL_ARCH_SIMPLE) THEN
5425   EXISTS_TAC `N + 1` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
5426   REWRITE_TAC[dist; COMPLEX_SUB_RZERO; COMPLEX_MUL_LID; complex_div] THEN
5427   SUBGOAL_THEN `0 < n` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
5428   RULE_ASSUM_TAC(REWRITE_RULE
5429    [GSYM REAL_OF_NUM_LT; GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_ADD]) THEN
5430   ASM_SIMP_TAC[GSYM CX_LOG; COMPLEX_NORM_CX; COMPLEX_NORM_INV] THEN
5431   GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN
5432   MATCH_MP_TAC REAL_LT_INV2 THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN
5433   MATCH_MP_TAC(REAL_ARITH `a < x ==> a < abs x`) THEN
5434   ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LT] THEN
5435   ASM_SIMP_TAC[EXP_LOG] THEN ASM_REAL_ARITH_TAC);;
5436
5437 let LIM_N_TIMES_POWN = prove
5438  (`!z. norm(z) < &1 ==> ((\n. Cx(&n) * z pow n) --> Cx(&0)) sequentially`,
5439   REPEAT STRIP_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN
5440   ASM_SIMP_TAC[COMPLEX_POW_ZERO; LIM_CASES_FINITE_SEQUENTIALLY; LIM_CONST;
5441                COND_RAND; FINITE_SING; SING_GSPEC; COMPLEX_MUL_RZERO] THEN
5442   MP_TAC LIM_LOG_OVER_N THEN
5443   REWRITE_TAC[LIM_SEQUENTIALLY; dist; COMPLEX_SUB_RZERO] THEN
5444   DISCH_THEN(MP_TAC o SPEC `log(inv(norm(z:complex))) / &2`) THEN
5445   ASM_SIMP_TAC[LOG_POS_LT; REAL_INV_1_LT; COMPLEX_NORM_NZ; REAL_HALF] THEN
5446   DISCH_THEN(X_CHOOSE_THEN `N1:num` (LABEL_TAC "+")) THEN
5447   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5448   FIRST_ASSUM(X_CHOOSE_THEN `N2:num` STRIP_ASSUME_TAC o
5449               GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN
5450   EXISTS_TAC `MAX 1 (MAX N1 N2)` THEN
5451   REWRITE_TAC[ARITH_RULE `MAX a b <= c <=> a <= c /\ b <= c`] THEN
5452   X_GEN_TAC `n:num` THEN STRIP_TAC THEN
5453   FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN
5454   ASM_SIMP_TAC[GSYM CX_LOG; REAL_OF_NUM_LT; LE_1; GSYM CX_DIV;
5455                COMPLEX_NORM_CX; REAL_ABS_DIV; REAL_ABS_NUM] THEN
5456   ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; ARITH; real_abs;
5457                LOG_POS; REAL_OF_NUM_LE] THEN
5458   ONCE_REWRITE_TAC[REAL_ARITH `a / b * &2 = (&2 * a) / b`] THEN
5459   ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN
5460   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [REAL_MUL_SYM] THEN
5461   GEN_REWRITE_TAC LAND_CONV [GSYM REAL_EXP_MONO_LT] THEN
5462   ASM_SIMP_TAC[REAL_EXP_N; EXP_LOG; REAL_OF_NUM_LT; LE_1;
5463                REAL_LT_INV_EQ; COMPLEX_NORM_NZ] THEN
5464   REWRITE_TAC[REAL_POW_INV] THEN
5465   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM REAL_MUL_LID] THEN
5466   ASM_SIMP_TAC[GSYM real_div; REAL_LT_RDIV_EQ; REAL_POW_LT; COMPLEX_NORM_NZ;
5467                COMPLEX_NORM_MUL; COMPLEX_NORM_NUM; COMPLEX_NORM_POW] THEN
5468   DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N2)` THEN
5469   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
5470   EXISTS_TAC `inv(&n)` THEN
5471   ASM_SIMP_TAC[REAL_LE_INV2; REAL_OF_NUM_LE; REAL_OF_NUM_LT; LE_1] THEN
5472   MATCH_MP_TAC REAL_LE_LCANCEL_IMP THEN EXISTS_TAC `&n` THEN
5473   ASM_SIMP_TAC[REAL_MUL_RINV; REAL_LT_IMP_NZ; REAL_OF_NUM_LT; LE_1] THEN
5474   ASM_REAL_ARITH_TAC);;
5475
5476 let LIM_N_OVER_POWN = prove
5477  (`!z. &1 < norm(z) ==> ((\n. Cx(&n) / z pow n) --> Cx(&0)) sequentially`,
5478   ASM_SIMP_TAC[complex_div; GSYM COMPLEX_POW_INV; COMPLEX_NORM_INV;
5479                REAL_INV_LT_1; LIM_N_TIMES_POWN]);;
5480
5481 let LIM_POWN = prove
5482  (`!z. norm(z) < &1 ==> ((\n. z pow n) --> Cx(&0)) sequentially`,
5483   REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_NULL_COMPARISON_COMPLEX THEN
5484   EXISTS_TAC `\n. Cx(&n) * z pow n` THEN ASM_SIMP_TAC[LIM_N_TIMES_POWN] THEN
5485   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
5486   REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_CX; REAL_ABS_NUM] THEN
5487   REWRITE_TAC[REAL_ARITH `a <= n * a <=> &0 <= (n - &1) * a`] THEN
5488   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN
5489   ASM_REWRITE_TAC[NORM_POS_LE; REAL_SUB_LE; REAL_OF_NUM_LE]);;
5490
5491 (* ------------------------------------------------------------------------- *)
5492 (* Roots of unity.                                                           *)
5493 (* ------------------------------------------------------------------------- *)
5494
5495 let COMPLEX_ROOT_POLYFUN = prove
5496  (`!n z a.
5497         1 <= n
5498         ==> (z pow n = a <=>
5499              vsum(0..n) (\i. (if i = 0 then --a else if i = n then Cx(&1)
5500                               else Cx(&0)) * z pow i) = Cx(&0))`,
5501   ASM_SIMP_TAC[VSUM_CLAUSES_RIGHT; LE_1; LE_0] THEN
5502   SIMP_TAC[VSUM_CLAUSES_LEFT; LE_0; ADD_CLAUSES] THEN
5503   ASM_SIMP_TAC[LE_1; ARITH_RULE `1 <= n /\ 1 <= i /\ i <= n - 1
5504                            ==> ~(i = n)`] THEN
5505   REWRITE_TAC[COMPLEX_MUL_LZERO; complex_pow; COMPLEX_MUL_RID] THEN
5506   REWRITE_TAC[GSYM COMPLEX_VEC_0; VSUM_0; VECTOR_ADD_RID] THEN
5507   REWRITE_TAC[COMPLEX_VEC_0] THEN CONV_TAC COMPLEX_RING);;
5508
5509 let COMPLEX_ROOT_UNITY = prove
5510  (`!n j. ~(n = 0)
5511          ==> cexp(Cx(&2) * Cx pi * ii * Cx(&j / &n)) pow n = Cx(&1)`,
5512   REWRITE_TAC[GSYM CEXP_N; CX_DIV] THEN
5513   ASM_SIMP_TAC[CX_INJ; complex_div; REAL_OF_NUM_EQ; COMPLEX_FIELD
5514     `~(n = Cx(&0)) ==> n * t * p * ii * j * inv(n) = j * (ii * t * p)`] THEN
5515   REWRITE_TAC[CEXP_N; GSYM CX_MUL] THEN
5516   REWRITE_TAC[CEXP_EULER; GSYM CX_MUL; GSYM CX_SIN; GSYM CX_COS] THEN
5517   REWRITE_TAC[COS_NPI; SIN_NPI; REAL_POW_NEG; COMPLEX_MUL_RZERO;
5518               REAL_POW_ONE; ARITH_EVEN; COMPLEX_ADD_RID; COMPLEX_POW_ONE]);;
5519
5520 let COMPLEX_ROOT_UNITY_EQ = prove
5521  (`!n j k. ~(n = 0)
5522            ==> (cexp(Cx(&2) * Cx pi * ii * Cx(&j / &n)) =
5523                 cexp(Cx(&2) * Cx pi * ii * Cx(&k / &n)) <=> (j == k) (mod n))`,
5524   REPEAT STRIP_TAC THEN REWRITE_TAC[CEXP_EQ; num_congruent; CX_MUL] THEN
5525   REWRITE_TAC[COMPLEX_RING
5526    `t * p * ii * j = t * p * ii * k + (t * n * p) * ii <=>
5527         (t * p * ii = Cx(&0)) \/ j - k = n`] THEN
5528   SIMP_TAC[COMPLEX_ENTIRE; II_NZ; CX_INJ; PI_NZ; REAL_OF_NUM_EQ; ARITH] THEN
5529   REWRITE_TAC[GSYM CX_SUB; CX_INJ] THEN
5530   ASM_SIMP_TAC[REAL_OF_NUM_EQ; REAL_FIELD
5531    `~(n = &0) ==> (j / n - k / n = m <=> j - k = n * m)`] THEN
5532   REWRITE_TAC[int_congruent] THEN
5533   REWRITE_TAC[int_eq; int_sub_th; int_mul_th; int_of_num_th] THEN
5534   MESON_TAC[int_abstr; int_rep]);;
5535
5536 let COMPLEX_ROOT_UNITY_EQ_1 = prove
5537  (`!n j. ~(n = 0)
5538          ==> (cexp(Cx(&2) * Cx pi * ii * Cx(&j / &n)) = Cx(&1) <=>
5539               n divides j)`,
5540   REPEAT STRIP_TAC THEN
5541   SUBGOAL_THEN `Cx(&1) = cexp(Cx(&2) * Cx pi * ii * Cx(&n / &n))`
5542   SUBST1_TAC THENL
5543    [ASM_SIMP_TAC[REAL_DIV_REFL; REAL_OF_NUM_EQ; COMPLEX_MUL_RID] THEN
5544     ONCE_REWRITE_TAC[COMPLEX_RING `t * p * ii = ii * t * p`] THEN
5545     REWRITE_TAC[CEXP_EULER; GSYM CX_MUL; GSYM CX_SIN; GSYM CX_COS] THEN
5546     REWRITE_TAC[COS_NPI; SIN_NPI] THEN SIMPLE_COMPLEX_ARITH_TAC;
5547     ASM_SIMP_TAC[COMPLEX_ROOT_UNITY_EQ] THEN CONV_TAC NUMBER_RULE]);;
5548
5549 let FINITE_CARD_COMPLEX_ROOTS_UNITY = prove
5550  (`!n. 1 <= n
5551        ==> FINITE {z | z pow n = Cx(&1)} /\ CARD {z | z pow n = Cx(&1)} <= n`,
5552   REPEAT GEN_TAC THEN DISCH_TAC THEN ASM_SIMP_TAC[COMPLEX_ROOT_POLYFUN] THEN
5553   MATCH_MP_TAC COMPLEX_POLYFUN_ROOTBOUND THEN
5554   DISCH_THEN(MP_TAC o SPEC `n:num`) THEN
5555   ASM_SIMP_TAC[IN_NUMSEG; LE_1; LE_0; LE_REFL] THEN CONV_TAC COMPLEX_RING);;
5556
5557 let FINITE_COMPLEX_ROOTS_UNITY = prove
5558  (`!n. ~(n = 0) ==> FINITE {z | z pow n = Cx(&1)}`,
5559   SIMP_TAC[FINITE_CARD_COMPLEX_ROOTS_UNITY; LE_1]);;
5560
5561 let FINITE_CARD_COMPLEX_ROOTS_UNITY_EXPLICIT = prove
5562  (`!n. 1 <= n
5563        ==> FINITE {cexp(Cx(&2) * Cx pi * ii * Cx(&j / &n)) | j | j < n} /\
5564            CARD {cexp(Cx(&2) * Cx pi * ii * Cx(&j / &n)) | j | j < n} = n`,
5565   let lemma = prove (* So we don't need to load number theories yet *)
5566    (`!x y n:num. (x == y) (mod n) /\ x < y + n /\ y < x + n ==> x = y`,
5567     REWRITE_TAC[num_congruent; GSYM INT_OF_NUM_EQ; GSYM INT_OF_NUM_LT] THEN
5568     REWRITE_TAC[GSYM INT_OF_NUM_ADD] THEN
5569     REWRITE_TAC[INT_ARITH `x < y + n /\ y < x + n <=> abs(x - y:int) < n`] THEN
5570     REPEAT GEN_TAC THEN REWRITE_TAC[int_congruent] THEN
5571     DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `d:int`) MP_TAC) THEN
5572     ONCE_REWRITE_TAC[GSYM INT_SUB_0] THEN
5573     ASM_SIMP_TAC[INT_ABS_MUL; INT_ENTIRE; INT_ABS_NUM;
5574                  INT_ARITH `n * x:int < n <=> n * x < n * &1`] THEN
5575     DISJ_CASES_TAC(INT_ARITH `&n:int = &0 \/ &0:int < &n`) THEN
5576     ASM_SIMP_TAC[INT_LT_LMUL_EQ] THEN INT_ARITH_TAC) in
5577   REWRITE_TAC[GSYM HAS_SIZE] THEN
5578   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [SIMPLE_IMAGE_GEN] THEN
5579   MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN REWRITE_TAC[IN_ELIM_THM] THEN
5580   ASM_SIMP_TAC[HAS_SIZE_NUMSEG_LT; COMPLEX_ROOT_UNITY_EQ; LE_1] THEN
5581   REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma THEN EXISTS_TAC `n:num` THEN
5582   ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC);;
5583
5584 let COMPLEX_ROOTS_UNITY = prove
5585  (`!n. 1 <= n
5586        ==> {z | z pow n = Cx(&1)} =
5587            {cexp(Cx(&2) * Cx pi * ii * Cx(&j / &n)) | j | j < n}`,
5588   REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC CARD_SUBSET_LE THEN
5589   ASM_SIMP_TAC[FINITE_CARD_COMPLEX_ROOTS_UNITY;
5590                FINITE_CARD_COMPLEX_ROOTS_UNITY_EXPLICIT] THEN
5591   GEN_REWRITE_TAC LAND_CONV [SIMPLE_IMAGE_GEN] THEN
5592   REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
5593   ASM_SIMP_TAC[COMPLEX_ROOT_UNITY; LE_1]);;
5594
5595 let CARD_COMPLEX_ROOTS_UNITY = prove
5596  (`!n. 1 <= n ==> CARD {z | z pow n = Cx(&1)} = n`,
5597   SIMP_TAC[COMPLEX_ROOTS_UNITY; FINITE_CARD_COMPLEX_ROOTS_UNITY_EXPLICIT]);;
5598
5599 let HAS_SIZE_COMPLEX_ROOTS_UNITY = prove
5600  (`!n. 1 <= n ==> {z | z pow n = Cx(&1)} HAS_SIZE n`,
5601   SIMP_TAC[HAS_SIZE; CARD_COMPLEX_ROOTS_UNITY; FINITE_COMPLEX_ROOTS_UNITY;
5602            LE_1]);;
5603
5604 let COMPLEX_NOT_ROOT_UNITY = prove
5605  (`!n. 1 <= n ==> ?u. norm u = &1 /\ ~(u pow n = Cx(&1))`,
5606   GEN_TAC THEN DISCH_TAC THEN
5607   ABBREV_TAC `u = cexp (Cx pi * ii * Cx (&1 / &n))` THEN
5608   EXISTS_TAC `u : complex` THEN CONJ_TAC THEN EXPAND_TAC "u" THEN
5609   REWRITE_TAC [NORM_CEXP; RE_MUL_CX; RE_II; REAL_MUL_LZERO;
5610                REAL_MUL_RZERO; REAL_EXP_0] THEN
5611   EXPAND_TAC "u" THEN REWRITE_TAC[GSYM CEXP_N] THEN
5612   ASM_SIMP_TAC[CX_DIV; LE_1; CX_INJ; REAL_OF_NUM_EQ; COMPLEX_FIELD
5613        `~(n = Cx(&0)) ==> n * p * i * Cx(&1) / n = i * p`] THEN
5614   REWRITE_TAC[CEXP_EULER; RE_CX; IM_CX; GSYM CX_COS; GSYM CX_SIN] THEN
5615   REWRITE_TAC[COS_PI; SIN_PI] THEN CONV_TAC COMPLEX_RING);;
5616
5617 (* ------------------------------------------------------------------------- *)
5618 (* Relation between clog and Arg, and hence continuity of Arg.               *)
5619 (* ------------------------------------------------------------------------- *)
5620
5621 let ARG_CLOG = prove
5622  (`!z. &0 < Arg z ==> Arg z = Im(clog(--z)) + pi`,
5623   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THENL
5624    [ASM_REWRITE_TAC[Arg_DEF; REAL_LT_REFL]; ALL_TAC] THEN
5625   DISCH_TAC THEN MP_TAC(last(CONJUNCTS(SPEC `z:complex` ARG))) THEN
5626   ASM_SIMP_TAC[CX_INJ; COMPLEX_NORM_ZERO; COMPLEX_FIELD
5627    `~(z = Cx(&0)) ==> (w = z * a <=> a = w / z)`] THEN
5628   DISCH_THEN(MP_TAC o AP_TERM `( * ) (cexp(--(ii * Cx pi)))`) THEN
5629   REWRITE_TAC[GSYM CEXP_ADD] THEN DISCH_THEN(MP_TAC o AP_TERM `clog`) THEN
5630   W(MP_TAC o PART_MATCH (lhs o rand) CLOG_CEXP o lhand o lhand o snd) THEN
5631   REWRITE_TAC[IM_ADD; IM_MUL_II; RE_CX; IM_NEG] THEN
5632   ASM_SIMP_TAC[REAL_LT_ADDR; ARG; REAL_ARITH
5633     `z < &2 * pi ==> --pi + z <= pi`] THEN
5634   DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[CEXP_NEG; CEXP_EULER] THEN
5635   REWRITE_TAC[GSYM CX_SIN; GSYM CX_COS; SIN_PI; COS_PI] THEN
5636   REWRITE_TAC[CX_NEG; COMPLEX_MUL_RZERO; COMPLEX_ADD_RID;
5637               SIMPLE_COMPLEX_ARITH `inv(--Cx(&1)) * z / w = --z / w`] THEN
5638   DISCH_THEN(MP_TAC o AP_TERM `Im`) THEN
5639   REWRITE_TAC[IM_ADD; IM_NEG; IM_MUL_II; RE_CX] THEN
5640   MATCH_MP_TAC(REAL_RING `w = z ==> --pi + x = w ==> x = z + pi`) THEN
5641   REWRITE_TAC[complex_div] THEN
5642   W(MP_TAC o PART_MATCH (lhs o rand) CLOG_MUL_SIMPLE o rand o lhand o snd) THEN
5643   ASM_SIMP_TAC[CX_INJ; REAL_INV_EQ_0; COMPLEX_NORM_ZERO; COMPLEX_NEG_EQ_0;
5644     GSYM CX_INV; GSYM CX_LOG; REAL_LT_INV_EQ; COMPLEX_NORM_NZ; IM_CX] THEN
5645   ASM_SIMP_TAC[REAL_ADD_RID; CLOG_WORKS; COMPLEX_NEG_EQ_0] THEN
5646   DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[IM_ADD; IM_CX; REAL_ADD_RID]);;
5647
5648 let CONTINUOUS_AT_ARG = prove
5649  (`!z. ~(real z /\ &0 <= Re z) ==> (Cx o Arg) continuous (at z)`,
5650   let lemma = prove
5651    (`(\z. Cx(Im(f z) + pi)) = (Cx o Im) o (\z. f z + ii * Cx pi)`,
5652     REWRITE_TAC[FUN_EQ_THM; o_DEF; IM_ADD; IM_CX; IM_MUL_II; RE_CX]) in
5653   REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_AT] THEN
5654   MATCH_MP_TAC LIM_TRANSFORM_WITHIN_OPEN THEN
5655   EXISTS_TAC `\z. Cx(Im(clog(--z)) + pi)` THEN
5656   EXISTS_TAC `(:complex) DIFF {z | real z /\ &0 <= Re z}` THEN
5657   ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; IN_ELIM_THM; GSYM closed] THEN
5658   ASM_SIMP_TAC[o_THM; ARG_CLOG; ARG_LT_NZ; ARG_EQ_0] THEN CONJ_TAC THENL
5659    [REWRITE_TAC[SET_RULE `{z | P z /\ Q z} = P INTER {z | Q z}`] THEN
5660     MATCH_MP_TAC CLOSED_INTER THEN
5661     REWRITE_TAC[CLOSED_REAL; GSYM real_ge; CLOSED_HALFSPACE_RE_GE];
5662     REWRITE_TAC[GSYM CONTINUOUS_AT; lemma] THEN
5663     MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN
5664     REWRITE_TAC[CONTINUOUS_AT_CX_IM] THEN
5665     MATCH_MP_TAC CONTINUOUS_ADD THEN REWRITE_TAC[CONTINUOUS_CONST] THEN
5666     MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_AT_COMPOSE) THEN
5667     GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM ETA_AX] THEN
5668     SIMP_TAC[CONTINUOUS_NEG; CONTINUOUS_AT_ID] THEN
5669     MATCH_MP_TAC CONTINUOUS_AT_CLOG THEN POP_ASSUM MP_TAC THEN
5670     REWRITE_TAC[real; IM_NEG; RE_NEG] THEN REAL_ARITH_TAC]);;
5671
5672 let CONTINUOUS_WITHIN_UPPERHALF_ARG = prove
5673  (`!z. ~(z = Cx(&0))
5674        ==> (Cx o Arg) continuous (at z) within {z | &0 <= Im z}`,
5675   REPEAT STRIP_TAC THEN ASM_CASES_TAC `real z /\ &0 <= Re z` THEN
5676   ASM_SIMP_TAC[CONTINUOUS_AT_ARG; CONTINUOUS_AT_WITHIN] THEN
5677   FIRST_X_ASSUM(CONJUNCTS_THEN2
5678    (ASSUME_TAC o GEN_REWRITE_RULE I [real]) MP_TAC) THEN
5679   SUBGOAL_THEN `~(Re z = &0)` ASSUME_TAC THENL
5680    [DISCH_TAC THEN UNDISCH_TAC `~(z = Cx(&0))` THEN
5681     ASM_REWRITE_TAC[COMPLEX_EQ; RE_CX; IM_CX];
5682     GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT]] THEN
5683   ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
5684   MP_TAC(ISPEC `rotate2d (pi / &2) z` CONTINUOUS_AT_ARG) THEN ANTS_TAC THENL
5685    [ASM_REWRITE_TAC[ROTATE2D_PI2; real; IM_MUL_II]; ALL_TAC] THEN
5686   REWRITE_TAC[continuous_at; continuous_within] THEN
5687   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
5688   ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
5689   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN
5690   REWRITE_TAC[o_THM; dist; GSYM CX_SUB; COMPLEX_NORM_CX] THEN
5691   STRIP_TAC THEN ASM_REWRITE_TAC[IN_ELIM_THM] THEN
5692   X_GEN_TAC `w:complex` THEN STRIP_TAC THEN
5693   SUBGOAL_THEN `Arg z = &0` ASSUME_TAC THENL
5694    [ASM_SIMP_TAC[ARG_EQ_0; real; REAL_LT_IMP_LE]; ALL_TAC] THEN
5695   ASM_CASES_TAC `Arg w = &0` THEN
5696   ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_ABS_NUM] THEN
5697   SUBGOAL_THEN `&0 < Arg w` ASSUME_TAC THENL
5698    [ASM_REWRITE_TAC[ARG; REAL_LT_LE]; ALL_TAC] THEN
5699   FIRST_X_ASSUM(MP_TAC o SPEC `rotate2d (pi / &2) w`) THEN
5700   ASM_REWRITE_TAC[GSYM ROTATE2D_SUB; NORM_ROTATE2D] THEN
5701   MP_TAC(ISPECL [`pi / &2`; `z:complex`] ARG_ROTATE2D) THEN ANTS_TAC THENL
5702    [ASM_REWRITE_TAC[] THEN MP_TAC PI_POS THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN
5703   DISCH_THEN SUBST1_TAC THEN ASM_REWRITE_TAC[REAL_ADD_RID] THEN
5704   MATCH_MP_TAC(REAL_ARITH
5705    `w' = p + w ==> abs(w' - p) < e ==> abs(w - &0) < e`) THEN
5706   MATCH_MP_TAC ARG_ROTATE2D THEN CONJ_TAC THENL
5707    [DISCH_TAC THEN UNDISCH_TAC `&0 < Arg w` THEN
5708     ASM_REWRITE_TAC[Arg_DEF; REAL_LT_REFL];
5709     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM ARG_LE_PI]) THEN
5710     MP_TAC(SPEC `w:complex` ARG) THEN REAL_ARITH_TAC]);;
5711
5712 let CONTINUOUS_ON_UPPERHALF_ARG = prove
5713  (`(Cx o Arg) continuous_on ({z | &0 <= Im z} DIFF {Cx(&0)})`,
5714   REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
5715   X_GEN_TAC `z:complex` THEN REWRITE_TAC[IN_DIFF; IN_SING; IN_ELIM_THM] THEN
5716   STRIP_TAC THEN FIRST_ASSUM(MP_TAC o
5717     MATCH_MP CONTINUOUS_WITHIN_UPPERHALF_ARG) THEN
5718   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_WITHIN_SUBSET) THEN
5719   SET_TAC[]);;
5720
5721 let CONTINUOUS_ON_COMPOSE_ARG = prove
5722  (`!s p:real->real^N.
5723         (p o drop) continuous_on interval[vec 0,lift(&2 * pi)] /\
5724         p(&2 * pi) = p(&0) /\ ~(Cx(&0) IN s)
5725         ==> (\z. p(Arg z)) continuous_on s`,
5726   let ulemma = prove
5727    (`!s. s INTER {z | &0 <= Im z} UNION s INTER {z | Im z <= &0} = s`,
5728     SET_TAC[REAL_LE_TOTAL]) in
5729   REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THEN
5730   EXISTS_TAC
5731    `\z. if &0 <= Im z then p(Arg z)
5732         else p(&2 * pi - Arg(cnj z)):real^N` THEN
5733   REWRITE_TAC[IN_UNIV; IN_SING; IN_DIFF] THEN CONJ_TAC THENL
5734    [X_GEN_TAC `z:complex` THEN DISCH_TAC THEN
5735     COND_CASES_TAC THEN ASM_REWRITE_TAC[ARG_CNJ] THEN
5736     COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_SUB_SUB2] THEN
5737     SUBGOAL_THEN `Arg z = &0`
5738      (fun th -> ASM_REWRITE_TAC[REAL_SUB_RZERO; th]) THEN
5739     ASM_REWRITE_TAC[ARG_EQ_0];
5740     GEN_REWRITE_TAC RAND_CONV [GSYM ulemma] THEN
5741     MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN REWRITE_TAC[ulemma] THEN
5742     SIMP_TAC[CLOSED_IN_CLOSED_INTER; CLOSED_HALFSPACE_IM_LE;
5743              REWRITE_RULE[real_ge] CLOSED_HALFSPACE_IM_GE] THEN
5744     REWRITE_TAC[IN_INTER; IN_DIFF; IN_UNIV; IN_SING; IN_ELIM_THM] THEN
5745     SIMP_TAC[GSYM CONJ_ASSOC; REAL_LE_ANTISYM; TAUT `~(p /\ ~p)`] THEN
5746     REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL
5747      [GEN_REWRITE_TAC (BINOP_CONV o LAND_CONV) [GSYM o_DEF] THEN
5748       SUBGOAL_THEN `(p:real->real^N) = (p o drop) o lift` SUBST1_TAC THENL
5749        [REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]; ALL_TAC] THEN
5750       ONCE_REWRITE_TAC[GSYM o_ASSOC] THEN
5751       CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL
5752        [REWRITE_TAC[o_DEF; GSYM CONTINUOUS_ON_CX_LIFT] THEN
5753         MP_TAC CONTINUOUS_ON_UPPERHALF_ARG THEN REWRITE_TAC[o_DEF] THEN
5754         MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN
5755         ASM SET_TAC[];
5756         FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
5757           CONTINUOUS_ON_SUBSET)) THEN
5758         REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTER; IN_ELIM_THM] THEN
5759         REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; o_THM; DROP_VEC] THEN
5760         SIMP_TAC[ARG; REAL_LT_IMP_LE];
5761         REWRITE_TAC[o_DEF; LIFT_SUB] THEN MATCH_MP_TAC CONTINUOUS_ON_SUB THEN
5762         REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
5763         GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [GSYM o_DEF] THEN
5764         REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
5765         REWRITE_TAC[CONTINUOUS_ON_CNJ; o_DEF; GSYM CONTINUOUS_ON_CX_LIFT] THEN
5766         MP_TAC CONTINUOUS_ON_UPPERHALF_ARG THEN REWRITE_TAC[o_DEF] THEN
5767         MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN
5768         SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTER; IN_ELIM_THM; IN_DIFF] THEN
5769         SIMP_TAC[IN_SING; CNJ_EQ_0; IM_CNJ; REAL_NEG_GE0] THEN ASM SET_TAC[];
5770         FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
5771           CONTINUOUS_ON_SUBSET)) THEN
5772         REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTER; IN_ELIM_THM] THEN
5773         REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; o_THM; DROP_VEC] THEN
5774         X_GEN_TAC `z:complex` THEN STRIP_TAC THEN
5775         MP_TAC(SPEC `cnj z` ARG) THEN REAL_ARITH_TAC];
5776       REWRITE_TAC[GSYM ARG_EQ_0_PI; GSYM real; ARG_CNJ] THEN
5777       REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
5778       COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_SUB_SUB2; REAL_SUB_RZERO] THEN
5779       ASM_REWRITE_TAC[REAL_ARITH `&2 * x - x = x`]]]);;
5780
5781 let OPEN_ARG_LTT = prove
5782  (`!s t. &0 <= s /\ t <= &2 * pi ==> open {z | s < Arg z /\ Arg z < t}`,
5783   REPEAT STRIP_TAC THEN
5784   MP_TAC(ISPECL [`Cx o Arg`; `(:complex) DIFF {z | real z /\ &0 <= Re z}`;
5785                    `{z | Re(z) > s} INTER {z | Re(z) < t}`]
5786            CONTINUOUS_OPEN_PREIMAGE) THEN
5787   ASM_SIMP_TAC[OPEN_INTER; OPEN_HALFSPACE_RE_GT; OPEN_HALFSPACE_RE_LT] THEN
5788   ANTS_TAC THENL
5789    [CONJ_TAC THENL
5790      [MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
5791       REWRITE_TAC[IN_DIFF; IN_UNIV; IN_ELIM_THM; CONTINUOUS_AT_ARG];
5792       REWRITE_TAC[GSYM closed] THEN
5793       REWRITE_TAC[SET_RULE `{z | P z /\ Q z} = P INTER {z | Q z}`] THEN
5794       MATCH_MP_TAC CLOSED_INTER THEN
5795       REWRITE_TAC[CLOSED_REAL; GSYM real_ge; CLOSED_HALFSPACE_RE_GE]];
5796     MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN REWRITE_TAC[EXTENSION] THEN
5797     ASM_SIMP_TAC[IN_DIFF; IN_INTER; IN_UNIV; IN_ELIM_THM; o_THM; RE_CX;
5798                  GSYM ARG_EQ_0] THEN
5799     ASM_REAL_ARITH_TAC]);;
5800
5801 let OPEN_ARG_GT = prove
5802  (`!t. open {z | t < Arg z}`,
5803   GEN_TAC THEN DISJ_CASES_TAC(REAL_ARITH `t < &0 \/ &0 <= t`) THENL
5804    [SUBGOAL_THEN `{z | t < Arg z} = (:complex)`
5805      (fun th -> SIMP_TAC[th; OPEN_UNIV]) THEN
5806     REWRITE_TAC[EXTENSION; IN_UNIV; IN_ELIM_THM] THEN
5807     MP_TAC ARG THEN MATCH_MP_TAC MONO_FORALL THEN ASM_REAL_ARITH_TAC;
5808     MP_TAC(ISPECL [`t:real`; `&2 * pi`] OPEN_ARG_LTT) THEN
5809     ASM_REWRITE_TAC[ARG; REAL_LE_REFL]]);;
5810
5811 let CLOSED_ARG_LE = prove
5812  (`!t. closed {z | Arg z <= t}`,
5813   REWRITE_TAC[closed; DIFF; IN_UNIV; IN_ELIM_THM] THEN
5814   REWRITE_TAC[REAL_NOT_LE; OPEN_ARG_GT]);;
5815
5816 (* ------------------------------------------------------------------------- *)
5817 (* Relation between Arg and arctangent in upper halfplane.                   *)
5818 (* ------------------------------------------------------------------------- *)
5819
5820 let ARG_ATAN_UPPERHALF = prove
5821  (`!z. &0 < Im z ==> Arg(z) = pi / &2 - atn(Re z / Im z)`,
5822   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THEN
5823   ASM_REWRITE_TAC[IM_CX; REAL_LT_REFL] THEN DISCH_TAC THEN
5824   MATCH_MP_TAC ARG_UNIQUE THEN EXISTS_TAC `norm(z:complex)` THEN
5825   ASM_REWRITE_TAC[COMPLEX_NORM_NZ] THEN CONJ_TAC THENL
5826    [ALL_TAC; MP_TAC(ISPEC `Re z / Im z` ATN_BOUNDS) THEN REAL_ARITH_TAC] THEN
5827   REWRITE_TAC[CEXP_EULER; GSYM CX_SIN; GSYM CX_COS] THEN
5828   REWRITE_TAC[SIN_SUB; COS_SUB; SIN_PI2; COS_PI2] THEN
5829   REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; SIN_ATN; COS_ATN] THEN
5830   SUBGOAL_THEN `sqrt(&1 + (Re z / Im z) pow 2) = norm(z) / Im z`
5831   SUBST1_TAC THENL
5832    [MATCH_MP_TAC SQRT_UNIQUE THEN
5833     ASM_SIMP_TAC[REAL_LE_DIV; NORM_POS_LE; REAL_LT_IMP_LE] THEN
5834     REWRITE_TAC[REAL_POW_DIV; COMPLEX_SQNORM] THEN
5835     UNDISCH_TAC `&0 < Im z` THEN CONV_TAC REAL_FIELD;
5836     REWRITE_TAC[REAL_ADD_LID; REAL_SUB_RZERO; real_div] THEN
5837     REWRITE_TAC[COMPLEX_EQ; RE_MUL_CX; IM_MUL_CX; RE_MUL_II; IM_MUL_II;
5838                 RE_ADD; IM_ADD; RE_CX; IM_CX] THEN
5839     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM COMPLEX_NORM_NZ]) THEN
5840     POP_ASSUM MP_TAC THEN CONV_TAC REAL_FIELD]);;
5841
5842 (* ------------------------------------------------------------------------- *)
5843 (* Real n'th roots.                                                          *)
5844 (* ------------------------------------------------------------------------- *)
5845
5846 let root = new_definition
5847  `root(n) x = @u:real. (&0 <= x ==> &0 <= u) /\ u pow n = x`;;
5848
5849 let ROOT_0 = prove
5850  (`!n. ~(n = 0) ==> root n (&0) = &0`,
5851   SIMP_TAC[root; REAL_LT_REFL; REAL_POW_EQ_0; REAL_LE_REFL; SELECT_REFL;
5852            REAL_ARITH `&0 <= u /\ u = &0 <=> u = &0`]);;
5853
5854 let ROOT_1 = prove
5855  (`!n. ~(n = 0) ==> root n (&1) = &1`,
5856   SIMP_TAC[root; REAL_POS; REAL_POW_EQ_1; CONJ_ASSOC] THEN
5857   REWRITE_TAC[REAL_ARITH `&0 <= u /\ abs u = &1 <=> u = &1`] THEN
5858   SIMP_TAC[TAUT `a /\ b <=> ~(a ==> ~b)`] THEN
5859   CONV_TAC REAL_RAT_REDUCE_CONV);;
5860
5861 let ROOT_2 = prove
5862  (`!x. root 2 x = sqrt x`,
5863   GEN_TAC THEN REWRITE_TAC[sqrt; root] THEN
5864   AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `y:real` THEN
5865   ASM_CASES_TAC `x:real = y pow 2` THEN
5866   ASM_REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE] THEN REAL_ARITH_TAC);;
5867
5868 let ROOT_WORKS = prove
5869  (`!n x. ODD n \/ ~(n = 0) /\ &0 <= x
5870          ==> (&0 <= x ==> &0 <= root n x) /\ (root n x) pow n = x`,
5871   REPEAT GEN_TAC THEN
5872   ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[ARITH] THEN DISCH_TAC THEN
5873   REWRITE_TAC[root] THEN CONV_TAC SELECT_CONV THEN
5874   REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC
5875    (REAL_ARITH `x = &0 \/ &0 < x \/ &0 < --x`)
5876   THENL
5877    [EXISTS_TAC `&0` THEN ASM_REWRITE_TAC[REAL_POW_ZERO];
5878     EXISTS_TAC `exp(log x / &n)` THEN REWRITE_TAC[REAL_EXP_POS_LE] THEN
5879     ASM_SIMP_TAC[GSYM REAL_EXP_N; REAL_DIV_LMUL; REAL_OF_NUM_EQ; EXP_LOG];
5880     FIRST_X_ASSUM(DISJ_CASES_THEN ASSUME_TAC) THENL
5881      [ALL_TAC; ASM_REAL_ARITH_TAC] THEN
5882     EXISTS_TAC `--exp(log(--x) / &n)` THEN REWRITE_TAC[REAL_POW_NEG] THEN
5883     ASM_SIMP_TAC[GSYM NOT_ODD; REAL_ARITH `&0 < --x ==> ~(&0 <= x)`] THEN
5884     ASM_SIMP_TAC[GSYM REAL_EXP_N; REAL_DIV_LMUL; REAL_OF_NUM_EQ; EXP_LOG;
5885                  REAL_NEG_NEG]]);;
5886
5887 let REAL_POW_ROOT = prove
5888  (`!n x. ODD n \/ ~(n = 0) /\ &0 <= x ==> (root n x) pow n = x`,
5889   SIMP_TAC[ROOT_WORKS]);;
5890
5891 let ROOT_POS_LE = prove
5892  (`!n x. ~(n = 0) /\ &0 <= x ==> &0 <= root n x`,
5893   SIMP_TAC[ROOT_WORKS]);;
5894
5895 let ROOT_POS_LT = prove
5896  (`!n x. ~(n = 0) /\ &0 < x ==> &0 < root n x`,
5897   REPEAT GEN_TAC THEN SIMP_TAC[REAL_LT_LE; ROOT_POS_LE] THEN STRIP_TAC THEN
5898   DISCH_THEN(ASSUME_TAC o SYM) THEN
5899   MP_TAC(SPECL [`n:num`; `x:real`] REAL_POW_ROOT) THEN
5900   ASM_REWRITE_TAC[REAL_POW_ZERO]);;
5901
5902 let REAL_ROOT_POW = prove
5903  (`!n x. ODD n \/ ~(n = 0) /\ &0 <= x ==> root n (x pow n) = x`,
5904   REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[root] THEN
5905   GEN_REWRITE_TAC RAND_CONV [GSYM SELECT_REFL] THEN
5906   AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `y:real` THEN
5907   MP_TAC(SPECL [`n:num`; `&0`; `x:real`] REAL_POW_LE2_ODD_EQ) THEN
5908   POP_ASSUM MP_TAC THEN REWRITE_TAC[REAL_POW_EQ_EQ; GSYM NOT_EVEN] THEN
5909   ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[ARITH] THEN
5910   COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_POW_LE; REAL_POW_ZERO] THEN
5911   ASM_REAL_ARITH_TAC);;
5912
5913 let ROOT_UNIQUE = prove
5914  (`!n x y. y pow n = x /\ (ODD n \/ ~(n = 0) /\ &0 <= y) ==> root n x = y`,
5915   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
5916   UNDISCH_THEN `(y:real) pow n = x` (SUBST_ALL_TAC o SYM) THEN
5917   MATCH_MP_TAC REAL_ROOT_POW THEN ASM_REWRITE_TAC[]);;
5918
5919 let REAL_ROOT_MUL = prove
5920  (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y
5921            ==> root n (x * y) = root n x * root n y`,
5922   REPEAT STRIP_TAC THEN MATCH_MP_TAC ROOT_UNIQUE THEN
5923   ASM_SIMP_TAC[REAL_POW_MUL; REAL_POW_ROOT; REAL_LE_MUL; ROOT_POS_LE]);;
5924
5925 let REAL_ROOT_INV = prove
5926  (`!n x. ~(n = 0) /\ &0 <= x ==> root n (inv x) = inv(root n x)`,
5927   REPEAT STRIP_TAC THEN MATCH_MP_TAC ROOT_UNIQUE THEN
5928   ASM_SIMP_TAC[REAL_POW_INV; REAL_POW_ROOT; REAL_LE_INV_EQ; ROOT_POS_LE]);;
5929
5930 let REAL_ROOT_DIV = prove
5931  (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y
5932            ==> root n (x / y) = root n x / root n y`,
5933   SIMP_TAC[real_div; REAL_ROOT_MUL; REAL_ROOT_INV; REAL_LE_INV_EQ]);;
5934
5935 let ROOT_MONO_LT = prove
5936  (`!n x y. ~(n = 0) /\ &0 <= x /\ x < y ==> root n x < root n y`,
5937   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5938   MATCH_MP_TAC(REAL_ARITH
5939    `(&0 <= x /\ &0 <= y ==> (v <= u ==> y <= x))
5940     ==> &0 <= x /\ x < y ==> u < v`) THEN
5941   REPEAT STRIP_TAC THEN
5942   SUBGOAL_THEN `(root n y) pow n <= (root n x) pow n` MP_TAC THENL
5943    [MATCH_MP_TAC REAL_POW_LE2 THEN ASM_SIMP_TAC[ROOT_POS_LE];
5944     ASM_SIMP_TAC[REAL_POW_ROOT]]);;
5945
5946 let ROOT_MONO_LE = prove
5947  (`!n x y. ~(n = 0) /\ &0 <= x /\ x <= y ==> root n x <= root n y`,
5948   MESON_TAC[ROOT_MONO_LT; REAL_LE_LT]);;
5949
5950 let ROOT_MONO_LT_EQ = prove
5951  (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y ==> (root n x < root n y <=> x < y)`,
5952   MESON_TAC[ROOT_MONO_LT; REAL_NOT_LT; ROOT_MONO_LE]);;
5953
5954 let ROOT_MONO_LE_EQ = prove
5955  (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y
5956            ==> (root n x <= root n y <=> x <= y)`,
5957   MESON_TAC[ROOT_MONO_LT; REAL_NOT_LT; ROOT_MONO_LE]);;
5958
5959 let ROOT_INJ = prove
5960  (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y ==> (root n x = root n y <=> x = y)`,
5961   SIMP_TAC[GSYM REAL_LE_ANTISYM; ROOT_MONO_LE_EQ]);;
5962
5963 let REAL_ROOT_LE = prove
5964  (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y
5965            ==> (root n x <= y <=> x <= y pow n)`,
5966   MESON_TAC[REAL_ROOT_POW; REAL_POW_LE; ROOT_MONO_LE_EQ]);;
5967
5968 let REAL_LE_ROOT = prove
5969  (`!n x y. ~(n = 0) /\ &0 <= x /\ &0 <= y
5970            ==> (x <= root n y <=> x pow n <= y)`,
5971   MESON_TAC[REAL_ROOT_POW; REAL_POW_LE; ROOT_MONO_LE_EQ]);;
5972
5973 let LOG_ROOT = prove
5974  (`!n x. ~(n = 0) /\ &0 < x ==> log(root n x) = log x / &n`,
5975   SIMP_TAC[REAL_EQ_RDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN
5976   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
5977   SIMP_TAC[GSYM LOG_POW; ROOT_POS_LT; REAL_POW_ROOT; REAL_LT_IMP_LE]);;
5978
5979 let ROOT_EXP_LOG = prove
5980  (`!n x. ~(n = 0) /\ &0 < x ==> root n x = exp(log x / &n)`,
5981   REPEAT GEN_TAC THEN DISCH_TAC THEN
5982   FIRST_ASSUM(MP_TAC o MATCH_MP ROOT_POS_LT) THEN
5983   REWRITE_TAC[GSYM REAL_EXP_LOG] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
5984   AP_TERM_TAC THEN ASM_SIMP_TAC[LOG_ROOT]);;
5985
5986 (* ------------------------------------------------------------------------- *)
5987 (* Real power function. This involves a few arbitrary choices.               *)
5988 (*                                                                           *)
5989 (* The value of x^y is unarguable when x > 0.                                *)
5990 (*                                                                           *)
5991 (* We make 0^0 = 1 to agree with "pow", but otherwise 0^y = 0.               *)
5992 (*                                                                           *)
5993 (* There is a sensible real value for (-x)^(p/q) where q is odd and either   *)
5994 (* p is even [(-x)^y = x^y] or odd [(-x)^y = -x^y].                          *)
5995 (*                                                                           *)
5996 (* In all other cases, we return (-x)^y = -x^y. This is meaningless but at   *)
5997 (* least it covers half the cases above without another case split.          *)
5998 (*                                                                           *)
5999 (* As for laws of indices, we do have x^-y = 1/x^y. Of course we can't  have *)
6000 (* x^(yz) = x^y^z or x^(y+z) = x^y x^z since then (-1)^(1/2)^2 = -1.         *)
6001 (* ------------------------------------------------------------------------- *)
6002
6003 parse_as_infix("rpow",(24,"left"));;
6004
6005 let rpow = new_definition
6006   `x rpow y = if &0 < x then exp(y * log x)
6007                else if x = &0 then if y = &0 then &1 else &0
6008                else if ?m n. ODD(m) /\ ODD(n) /\ (abs y = &m / &n)
6009                     then --(exp(y * log(--x)))
6010                     else exp(y * log(--x))`;;
6011
6012 let RPOW_POW = prove
6013  (`!x n. x rpow &n = x pow n`,
6014   REPEAT GEN_TAC THEN REWRITE_TAC[rpow] THEN
6015   COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_EXP_N; EXP_LOG] THEN
6016   COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_POW_ZERO; REAL_OF_NUM_EQ] THEN
6017   ASM_SIMP_TAC[EXP_LOG; REAL_ARITH `~(&0 < x) /\ ~(x = &0) ==> &0 < --x`] THEN
6018   REWRITE_TAC[REAL_POW_NEG; REAL_ABS_NUM] THEN
6019   SUBGOAL_THEN `(?p q. ODD(p) /\ ODD(q) /\ &n = &p / &q) <=> ODD n`
6020    (fun th -> SIMP_TAC[th; GSYM NOT_ODD; REAL_NEG_NEG; COND_ID]) THEN
6021   EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL
6022    [REPEAT GEN_TAC THEN ASM_CASES_TAC `q = 0` THEN
6023     ASM_REWRITE_TAC[ARITH_ODD] THEN
6024     REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
6025     ASM_SIMP_TAC[REAL_OF_NUM_EQ; REAL_FIELD
6026      `~(q = &0) ==> (n = p / q <=> q * n = p)`] THEN
6027     REWRITE_TAC[REAL_OF_NUM_MUL; REAL_OF_NUM_EQ] THEN
6028     ASM_MESON_TAC[ODD_MULT];
6029     DISCH_TAC THEN MAP_EVERY EXISTS_TAC [`n:num`; `1`] THEN
6030     ASM_REWRITE_TAC[REAL_DIV_1; ARITH_ODD]]);;
6031
6032 let RPOW_NEG = prove
6033  (`!x y. x rpow (--y) = inv(x rpow y)`,
6034   REPEAT GEN_TAC THEN REWRITE_TAC[rpow] THEN
6035   COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_MUL_LNEG; REAL_EXP_NEG] THEN
6036   COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_NEG_EQ_0] THENL
6037    [COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_INV_0; REAL_INV_1];
6038     REWRITE_TAC[REAL_ABS_NEG] THEN
6039     COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_INV_NEG]]);;
6040
6041 let RPOW_ZERO = prove
6042  (`!y. &0 rpow y = if y = &0 then &1 else &0`,
6043   REWRITE_TAC[rpow; REAL_LT_REFL]);;
6044
6045 let RPOW_POS_LT = prove
6046  (`!x y. &0 < x ==> &0 < x rpow y`,
6047   SIMP_TAC[rpow; REAL_EXP_POS_LT]);;
6048
6049 let RPOW_POS_LE = prove
6050  (`!x y. &0 <= x ==> &0 <= x rpow y`,
6051   REPEAT GEN_TAC THEN ASM_CASES_TAC `x = &0` THENL
6052    [ASM_REWRITE_TAC[RPOW_ZERO] THEN MESON_TAC[REAL_POS];
6053     ASM_SIMP_TAC[RPOW_POS_LT; REAL_LE_LT]]);;
6054
6055 let RPOW_LT2 = prove
6056  (`!x y z. &0 <= x /\ x < y /\ &0 < z ==> x rpow z < y rpow z`,
6057   REPEAT GEN_TAC THEN ASM_CASES_TAC `x = &0` THEN
6058   ASM_SIMP_TAC[RPOW_ZERO; REAL_LT_IMP_NZ; RPOW_POS_LT] THEN
6059   REPEAT STRIP_TAC THEN REWRITE_TAC[rpow] THEN
6060   ASM_CASES_TAC `&0 < x /\ &0 < y` THENL
6061    [ALL_TAC; MATCH_MP_TAC(TAUT `F ==> p`) THEN ASM_REAL_ARITH_TAC] THEN
6062   ASM_SIMP_TAC[REAL_EXP_MONO_LT; REAL_LT_LMUL_EQ] THEN
6063   MATCH_MP_TAC LOG_MONO_LT_IMP THEN ASM_REAL_ARITH_TAC);;
6064
6065 let RPOW_LE2 = prove
6066  (`!x y z. &0 <= x /\ x <= y /\ &0 <= z ==> x rpow z <= y rpow z`,
6067   REPEAT GEN_TAC THEN ASM_CASES_TAC `z = &0` THEN
6068   ASM_REWRITE_TAC[RPOW_POW; real_pow; REAL_LE_REFL] THEN
6069   ASM_CASES_TAC `x:real = y` THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN
6070   ASM_MESON_TAC[RPOW_LT2; REAL_LE_LT]);;
6071
6072 let REAL_ABS_RPOW = prove
6073  (`!x y. abs(x rpow y) = abs(x) rpow y`,
6074   REPEAT GEN_TAC THEN REWRITE_TAC[rpow] THEN
6075   ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[REAL_ABS_NUM; REAL_LT_REFL] THENL
6076    [REAL_ARITH_TAC; ALL_TAC] THEN
6077   ASM_REWRITE_TAC[GSYM REAL_ABS_NZ; REAL_ABS_ZERO] THEN
6078   COND_CASES_TAC THEN
6079   ASM_SIMP_TAC[REAL_ABS_EXP; REAL_ARITH `&0 < x ==> abs x = x`] THEN
6080   COND_CASES_TAC THEN REWRITE_TAC[REAL_ABS_NEG; REAL_ABS_EXP] THEN
6081   AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN ASM_REAL_ARITH_TAC);;
6082
6083 let RPOW_ONE = prove
6084  (`!z. &1 rpow z = &1`,
6085   REWRITE_TAC[rpow; REAL_LT_01; LOG_1; REAL_MUL_RZERO; REAL_EXP_0]);;
6086
6087 let RPOW_RPOW = prove
6088  (`!x y z. &0 <= x ==> x rpow y rpow z = x rpow (y * z)`,
6089   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_LT] THEN
6090   ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[] THENL
6091    [ASM_REWRITE_TAC[RPOW_ZERO; REAL_ENTIRE] THEN
6092     ASM_CASES_TAC `y = &0` THEN ASM_REWRITE_TAC[RPOW_ZERO; RPOW_ONE];
6093     SIMP_TAC[rpow; REAL_EXP_POS_LT; LOG_EXP] THEN
6094     REWRITE_TAC[REAL_MUL_AC]]);;
6095
6096 let RPOW_LNEG = prove
6097  (`!x y. --x rpow y =
6098          if ?m n. ODD m /\ ODD n /\ abs y = &m / &n
6099          then --(x rpow y) else x rpow y`,
6100   REPEAT GEN_TAC THEN REWRITE_TAC[rpow] THEN
6101   ASM_CASES_TAC `x = &0` THEN
6102   ASM_REWRITE_TAC[REAL_NEG_0; REAL_ABS_NUM; REAL_LT_REFL] THENL
6103    [ASM_CASES_TAC `y = &0` THEN ASM_REWRITE_TAC[REAL_NEG_0; COND_ID] THEN
6104     REWRITE_TAC[REAL_ARITH `abs(&0) = m / n <=> m * inv n = &0`] THEN
6105     SIMP_TAC[REAL_ENTIRE; REAL_INV_EQ_0; REAL_OF_NUM_EQ] THEN MESON_TAC[ODD];
6106     ASM_SIMP_TAC[REAL_ARITH `~(x = &0) ==> (&0 < --x <=> ~(&0 < x))`] THEN
6107     ASM_REWRITE_TAC[REAL_NEG_EQ_0] THEN
6108     ASM_CASES_TAC `&0 < x` THEN ASM_REWRITE_TAC[REAL_NEG_NEG; COND_ID]]);;
6109
6110 let RPOW_EQ_0 = prove
6111  (`!x y. x rpow y = &0 <=> x = &0 /\ ~(y = &0)`,
6112   REPEAT GEN_TAC THEN REWRITE_TAC[rpow] THEN
6113   ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[REAL_LT_REFL] THEN
6114   REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_NEG_EQ_0; REAL_EXP_NZ]) THEN
6115   REAL_ARITH_TAC);;
6116
6117 let RPOW_MUL = prove
6118  (`!x y z. (x * y) rpow z = x rpow z * y rpow z`,
6119   SUBGOAL_THEN
6120     `!x y z. &0 <= x /\ &0 <= y ==> (x * y) rpow z = x rpow z * y rpow z`
6121   ASSUME_TAC THENL
6122    [REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_LT] THEN
6123     ASM_CASES_TAC `z = &0` THEN
6124     ASM_REWRITE_TAC[RPOW_POW; real_pow; REAL_MUL_LID] THEN
6125     ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[REAL_MUL_LZERO; RPOW_ZERO] THEN
6126     ASM_CASES_TAC `y = &0` THEN ASM_REWRITE_TAC[REAL_MUL_RZERO; RPOW_ZERO] THEN
6127     SIMP_TAC[rpow; REAL_LT_MUL; LOG_MUL; REAL_ADD_LDISTRIB; REAL_EXP_ADD];
6128     REPEAT GEN_TAC THEN
6129     REPEAT_TCL DISJ_CASES_THEN (ANTE_RES_THEN (MP_TAC o SPEC `z:real`))
6130      (REAL_ARITH `&0 <= x /\ &0 <= y \/ &0 <= x /\ &0 <= --y \/
6131                   &0 <= --x /\ &0 <= y \/ &0 <= --x /\ &0 <= --y`) THEN
6132     REWRITE_TAC[RPOW_LNEG; REAL_MUL_RNEG; REAL_MUL_LNEG] THEN
6133     COND_CASES_TAC THEN
6134     ASM_REWRITE_TAC[REAL_MUL_RNEG; REAL_MUL_LNEG; REAL_EQ_NEG2]]);;
6135
6136 let RPOW_INV = prove
6137  (`!x y. inv(x) rpow y = inv(x rpow y)`,
6138   REPEAT GEN_TAC THEN REWRITE_TAC[rpow; REAL_LT_INV_EQ] THEN
6139   SIMP_TAC[LOG_INV; REAL_MUL_RNEG; REAL_EXP_NEG] THEN
6140   COND_CASES_TAC THEN REWRITE_TAC[] THEN
6141   REWRITE_TAC[REAL_INV_EQ_0] THEN
6142   REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_INV_1; REAL_INV_0]) THEN
6143   ASM_SIMP_TAC[GSYM REAL_INV_NEG; LOG_INV;
6144                REAL_ARITH `~(&0 < x) /\ ~(x = &0) ==> &0 < --x`] THEN
6145   REWRITE_TAC[REAL_MUL_RNEG; REAL_EXP_NEG; REAL_INV_NEG]);;
6146
6147 let REAL_INV_RPOW = prove
6148  (`!x y. inv(x rpow y) = inv(x) rpow y`,
6149   REWRITE_TAC[RPOW_INV]);;
6150
6151 let RPOW_ADD = prove
6152  (`!x y z. &0 < x ==> x rpow (y + z) = x rpow y * x rpow z`,
6153   REPEAT STRIP_TAC THEN
6154   ASM_REWRITE_TAC[rpow; REAL_ADD_RDISTRIB; REAL_EXP_ADD]);;
6155
6156 let RPOW_ADD_ALT = prove
6157  (`!x y z. &0 <= x /\ (x = &0 /\ y + z = &0 ==> y = &0 \/ z = &0)
6158            ==> x rpow (y + z) = x rpow y * x rpow z`,
6159   REPEAT GEN_TAC THEN
6160   ASM_CASES_TAC `x = &0` THEN ASM_SIMP_TAC[REAL_LE_LT; RPOW_ADD] THEN
6161   REWRITE_TAC[RPOW_ZERO] THEN
6162   ASM_CASES_TAC `y = &0` THEN
6163   ASM_REWRITE_TAC[REAL_MUL_LID; REAL_ADD_LID] THEN
6164   ASM_CASES_TAC `y + z = &0` THEN ASM_REWRITE_TAC[] THEN
6165   ASM_REAL_ARITH_TAC);;
6166
6167 let RPOW_SQRT = prove
6168  (`!x. &0 <= x ==> x rpow (&1 / &2) = sqrt x`,
6169   REPEAT STRIP_TAC THEN
6170   MATCH_MP_TAC(REAL_RING
6171    `x pow 2 = y pow 2 /\ (x + y = &0 ==> x = &0 /\ y = &0)
6172     ==> x = y`) THEN
6173   CONJ_TAC THENL
6174    [ASM_SIMP_TAC[SQRT_POW_2] THEN
6175     ASM_SIMP_TAC[GSYM RPOW_POW; RPOW_RPOW] THEN
6176     CONV_TAC REAL_RAT_REDUCE_CONV THEN
6177     REWRITE_TAC[RPOW_POW; REAL_POW_1];
6178     MATCH_MP_TAC(REAL_ARITH
6179      `&0 <= x /\ &0 <= y ==> x + y = &0 ==> x = &0 /\ y = &0`) THEN
6180     ASM_SIMP_TAC[SQRT_POS_LE; RPOW_POS_LE]]);;
6181
6182 let RPOW_MONO = prove
6183  (`!a b x. &1 <= x /\ a <= b ==> x rpow a <= x rpow b`,
6184   SIMP_TAC[rpow; REAL_ARITH `&1 <= x ==> &0 < x`] THEN
6185   SIMP_TAC[REAL_EXP_MONO_LE; LOG_POS; REAL_LE_RMUL]);;
6186
6187 let RPOW_MONO_INV = prove
6188  (`!a b x. &0 < x /\ x <= &1 /\ b <= a ==> x rpow a <= x rpow b`,
6189   REPEAT STRIP_TAC THEN
6190   GEN_REWRITE_TAC BINOP_CONV [GSYM REAL_INV_INV] THEN
6191   MATCH_MP_TAC REAL_LE_INV2 THEN
6192   ASM_SIMP_TAC[REAL_LT_INV_EQ; RPOW_POS_LT; GSYM RPOW_INV] THEN
6193   MATCH_MP_TAC RPOW_MONO THEN
6194   ASM_SIMP_TAC[REAL_INV_1_LE]);;
6195
6196 let RPOW_1_LE = prove
6197  (`!a x. &0 <= x /\ x <= &1 /\ &0 <= a ==> x rpow a <= &1`,
6198   REPEAT STRIP_TAC THEN  MATCH_MP_TAC REAL_LE_TRANS THEN
6199   EXISTS_TAC `&1 rpow a` THEN CONJ_TAC THENL
6200    [MATCH_MP_TAC RPOW_LE2 THEN ASM_REAL_ARITH_TAC;
6201     REWRITE_TAC[RPOW_ONE; REAL_LE_REFL]]);;
6202
6203 let REAL_ROOT_RPOW = prove
6204  (`!n x. ~(n = 0) /\ (&0 <= x \/ ODD n) ==> root n x = x rpow (inv(&n))`,
6205   REPEAT GEN_TAC THEN ASM_CASES_TAC `x = &0` THEN
6206   ASM_SIMP_TAC[ROOT_0; RPOW_ZERO; REAL_INV_EQ_0; REAL_OF_NUM_EQ] THEN
6207   ASM_CASES_TAC `&0 <= x` THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THENL
6208    [ASM_SIMP_TAC[ROOT_EXP_LOG; rpow; REAL_LT_LE] THEN AP_TERM_TAC THEN
6209     REAL_ARITH_TAC;
6210     ASM_REWRITE_TAC[rpow] THEN COND_CASES_TAC THENL
6211      [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
6212     REWRITE_TAC[REAL_ABS_INV; REAL_ABS_NUM] THEN
6213     REWRITE_TAC[REAL_ARITH `inv x = &1 / x`] THEN
6214     COND_CASES_TAC THENL [ALL_TAC; ASM_MESON_TAC[ARITH]] THEN
6215     MATCH_MP_TAC ROOT_UNIQUE THEN
6216     ASM_REWRITE_TAC[REAL_POW_NEG; GSYM REAL_EXP_N; GSYM NOT_ODD] THEN
6217     ASM_SIMP_TAC[REAL_OF_NUM_EQ; REAL_FIELD
6218       `~(n = &0) ==> n * &1 / n * x = x`] THEN
6219     ONCE_REWRITE_TAC[REAL_ARITH `--x:real = y <=> x = --y`] THEN
6220     MATCH_MP_TAC EXP_LOG THEN ASM_REAL_ARITH_TAC]);;
6221
6222 (* ------------------------------------------------------------------------- *)
6223 (* Formulation of loop homotopy in terms of maps out of S^1                  *)
6224 (* ------------------------------------------------------------------------- *)
6225
6226 let HOMOTOPIC_CIRCLEMAPS_IMP_HOMOTOPIC_LOOPS = prove
6227  (`!f:complex->real^N g s.
6228         homotopic_with (\h. T) (sphere(vec 0,&1),s) f g
6229         ==> homotopic_loops s (f o cexp o (\t. Cx(&2 * pi * drop t) * ii))
6230                               (g o cexp o (\t. Cx(&2 * pi * drop t) * ii))`,
6231   REWRITE_TAC[homotopic_loops; sphere; DIST_0] THEN REPEAT STRIP_TAC THEN
6232   MATCH_MP_TAC HOMOTOPIC_WITH_COMPOSE_CONTINUOUS_RIGHT THEN
6233   EXISTS_TAC `{z:complex | norm z = &1}` THEN
6234   REWRITE_TAC[pathstart; pathfinish; o_THM; DROP_VEC] THEN
6235   ONCE_REWRITE_TAC[REAL_ARITH `&2 * pi * n = &2 * n * pi`] THEN
6236   REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; o_THM; IN_ELIM_THM] THEN
6237   ASM_SIMP_TAC[CEXP_INTEGER_2PI; INTEGER_CLOSED] THEN
6238   REWRITE_TAC[ONCE_REWRITE_RULE[COMPLEX_MUL_SYM] NORM_CEXP_II] THEN
6239   MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN REWRITE_TAC[CONTINUOUS_ON_CEXP] THEN
6240   REWRITE_TAC[CX_MUL] THEN
6241   REPEAT(MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN
6242          REWRITE_TAC[CONTINUOUS_ON_CONST]) THEN
6243   SIMP_TAC[CONTINUOUS_ON_CX_DROP; CONTINUOUS_ON_ID]);;
6244
6245 let HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_CIRCLEMAPS = prove
6246  (`!p q s:real^N->bool.
6247         homotopic_loops s p q
6248         ==> homotopic_with (\h. T) (sphere(vec 0,&1),s)
6249                                    (p o (\z. lift(Arg z / (&2 * pi))))
6250                                    (q o (\z. lift(Arg z / (&2 * pi))))`,
6251  let ulemma = prove
6252    (`!s. s INTER (UNIV PCROSS {z | &0 <= Im z}) UNION
6253          s INTER (UNIV PCROSS {z | Im z <= &0}) = s`,
6254     REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_INTER; IN_UNION;
6255                  PASTECART_IN_PCROSS] THEN
6256     SET_TAC[REAL_LE_TOTAL]) in
6257   REPEAT GEN_TAC THEN REWRITE_TAC[homotopic_loops; sphere; DIST_0] THEN
6258   GEN_REWRITE_TAC LAND_CONV [homotopic_with] THEN
6259   SIMP_TAC[pathstart; pathfinish; LEFT_IMP_EXISTS_THM; HOMOTOPIC_WITH] THEN
6260   X_GEN_TAC `h:real^(1,1)finite_sum->real^N` THEN STRIP_TAC THEN
6261   EXISTS_TAC `\w. (h:real^(1,1)finite_sum->real^N)
6262                   (pastecart (fstcart w)
6263                              (lift(Arg(sndcart w) / (&2 * pi))))` THEN
6264   ASM_REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; o_THM] THEN
6265   CONJ_TAC THENL
6266    [MATCH_MP_TAC CONTINUOUS_ON_EQ THEN
6267     EXISTS_TAC
6268      `(\z. if &0 <= Im(sndcart z)
6269            then h (pastecart (fstcart z) (lift(Arg(sndcart z) / (&2 * pi))))
6270            else h (pastecart (fstcart z)
6271                              (vec 1 - lift(Arg(cnj(sndcart z)) / (&2 * pi)))))
6272       :real^(1,2)finite_sum->real^N` THEN
6273     REWRITE_TAC[FORALL_IN_PCROSS; FSTCART_PASTECART; SNDCART_PASTECART] THEN
6274     REWRITE_TAC[IN_ELIM_THM] THEN CONJ_TAC THENL
6275      [MAP_EVERY X_GEN_TAC [`t:real^1`; `z:complex`] THEN STRIP_TAC THEN
6276       COND_CASES_TAC THEN ASM_REWRITE_TAC[ARG_CNJ] THEN
6277       COND_CASES_TAC THENL [ASM_MESON_TAC[real; REAL_LE_REFL]; ALL_TAC] THEN
6278       SIMP_TAC[PI_POS; LIFT_SUB; LIFT_NUM; REAL_FIELD
6279         `&0 < pi ==> (&2 * pi - z) / (&2 * pi) = &1 - z / (&2 * pi)`] THEN
6280       REWRITE_TAC[VECTOR_ARITH `a - (a - b):real^N = b`];
6281       GEN_REWRITE_TAC RAND_CONV [GSYM ulemma] THEN
6282       MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN REWRITE_TAC[ulemma] THEN
6283       SIMP_TAC[CLOSED_IN_CLOSED_INTER; CLOSED_HALFSPACE_IM_LE; CLOSED_UNIV;
6284         CLOSED_PCROSS; REWRITE_RULE[real_ge] CLOSED_HALFSPACE_IM_GE] THEN
6285       REWRITE_TAC[FORALL_PASTECART; PASTECART_IN_PCROSS; IN_INTER; IN_DIFF;
6286        FSTCART_PASTECART; SNDCART_PASTECART; IN_UNIV; IN_SING; IN_ELIM_THM;
6287        GSYM CONJ_ASSOC; REAL_LE_ANTISYM; TAUT `~(p /\ ~p)`] THEN
6288       REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL
6289        [ALL_TAC;
6290         REWRITE_TAC[GSYM ARG_EQ_0_PI; GSYM real; ARG_CNJ] THEN
6291         REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
6292         SIMP_TAC[REAL_ARITH `&2 * x - x = x`; COND_ID; GSYM LIFT_NUM; PI_POS;
6293          GSYM LIFT_SUB; REAL_FIELD
6294           `&0 < pi ==> &1 - pi / (&2 * pi) = pi / (&2 * pi)`] THEN
6295         COND_CASES_TAC THEN
6296         SIMP_TAC[REAL_SUB_RZERO; REAL_DIV_REFL; REAL_ENTIRE; REAL_OF_NUM_EQ;
6297                  ARITH_EQ; PI_NZ] THEN
6298         SIMP_TAC[real_div; REAL_MUL_LZERO; REAL_SUB_REFL; REAL_SUB_RZERO] THEN
6299         ASM_SIMP_TAC[LIFT_NUM]] THEN
6300       GEN_REWRITE_TAC (BINOP_CONV o LAND_CONV) [GSYM o_DEF] THEN
6301       CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL
6302        [MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN
6303         SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART] THEN
6304         REWRITE_TAC[real_div; REWRITE_RULE[REAL_MUL_SYM] LIFT_CMUL] THEN
6305         MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN
6306         GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM o_DEF] THEN
6307         REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
6308         SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN
6309         REWRITE_TAC[o_DEF; GSYM CONTINUOUS_ON_CX_LIFT] THEN
6310         MP_TAC CONTINUOUS_ON_UPPERHALF_ARG THEN REWRITE_TAC[o_DEF] THEN
6311         MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN
6312         REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_PASTECART; IN_INTER;
6313                     PASTECART_IN_PCROSS; IN_ELIM_THM; SNDCART_PASTECART] THEN
6314         MAP_EVERY X_GEN_TAC [`t:real^1`; `z:complex`] THEN
6315         SIMP_TAC[IN_DIFF; IN_ELIM_THM; IN_SING] THEN
6316         ASM_CASES_TAC `z = Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_NORM_0] THEN
6317         REWRITE_TAC[REAL_OF_NUM_EQ; ARITH_EQ];
6318         FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
6319           CONTINUOUS_ON_SUBSET)) THEN
6320         REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_PASTECART; IN_INTER;
6321                     PASTECART_IN_PCROSS; IN_ELIM_THM; SNDCART_PASTECART;
6322                     FSTCART_PASTECART] THEN
6323         SIMP_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN
6324         SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; PI_POS; REAL_MUL_LZERO;
6325              REAL_MUL_LID; REAL_ARITH `&0 < &2 * x <=> &0 < x`] THEN
6326         SIMP_TAC[ARG; REAL_LT_IMP_LE];
6327         MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN
6328         SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART] THEN
6329         MATCH_MP_TAC CONTINUOUS_ON_SUB THEN
6330         REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
6331         REWRITE_TAC[real_div; REWRITE_RULE[REAL_MUL_SYM] LIFT_CMUL] THEN
6332         MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN
6333         GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM o_DEF] THEN
6334         REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
6335         GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM o_DEF] THEN
6336         SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_SNDCART; CONTINUOUS_ON_COMPOSE;
6337                  CONTINUOUS_ON_CNJ] THEN
6338         REWRITE_TAC[o_DEF; GSYM CONTINUOUS_ON_CX_LIFT] THEN
6339         MP_TAC CONTINUOUS_ON_UPPERHALF_ARG THEN REWRITE_TAC[o_DEF] THEN
6340         MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN
6341         REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_PASTECART; IN_INTER;
6342                     PASTECART_IN_PCROSS; IN_ELIM_THM; SNDCART_PASTECART] THEN
6343         MAP_EVERY X_GEN_TAC [`t:real^1`; `z:complex`] THEN
6344         SIMP_TAC[IN_DIFF; IN_ELIM_THM; IN_SING] THEN
6345         SIMP_TAC[IM_CNJ; REAL_NEG_GE0; CNJ_EQ_0] THEN
6346         ASM_CASES_TAC `z = Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_NORM_0] THEN
6347         REWRITE_TAC[REAL_OF_NUM_EQ; ARITH_EQ];
6348         FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
6349           CONTINUOUS_ON_SUBSET)) THEN
6350         REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_PASTECART; IN_INTER;
6351                     PASTECART_IN_PCROSS; IN_ELIM_THM; SNDCART_PASTECART;
6352                     FSTCART_PASTECART] THEN
6353         SIMP_TAC[IN_INTERVAL_1; DROP_SUB; DROP_VEC; LIFT_DROP] THEN
6354         REWRITE_TAC[REAL_ARITH `&0 <= &1 - x /\ &1 - x <= &1 <=>
6355                                 &0 <= x /\ x <= &1`] THEN
6356         SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; PI_POS; REAL_MUL_LZERO;
6357              REAL_MUL_LID; REAL_ARITH `&0 < &2 * x <=> &0 < x`] THEN
6358         SIMP_TAC[ARG; REAL_LT_IMP_LE]]];
6359     REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_PCROSS; IN_ELIM_THM] THEN
6360     REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN
6361     REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
6362      `IMAGE h s SUBSET t ==> y IN s ==> h y IN t`)) THEN
6363     ASM_REWRITE_TAC[PASTECART_IN_PCROSS; IN_INTERVAL_1; LIFT_DROP] THEN
6364     SIMP_TAC[DROP_VEC; REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; PI_POS;
6365              REAL_ARITH `&0 < &2 * x <=> &0 < x`] THEN
6366     SIMP_TAC[REAL_MUL_LZERO; REAL_MUL_LID; ARG; REAL_LT_IMP_LE]]);;
6367
6368 let SIMPLY_CONNECTED_EQ_HOMOTOPIC_CIRCLEMAPS,
6369     SIMPLY_CONNECTED_EQ_CONTRACTIBLE_CIRCLEMAP =
6370  (CONJ_PAIR o prove)
6371  (`(!s:real^N->bool.
6372         simply_connected s <=>
6373         !f g:complex->real^N.
6374               f continuous_on sphere(vec 0,&1) /\
6375               IMAGE f (sphere(vec 0,&1)) SUBSET s /\
6376               g continuous_on sphere(vec 0,&1) /\
6377               IMAGE g (sphere(vec 0,&1)) SUBSET s
6378               ==> homotopic_with (\h. T) (sphere(vec 0,&1),s) f g) /\
6379    (!s:real^N->bool.
6380       simply_connected s <=>
6381       path_connected s /\
6382       !f:real^2->real^N.
6383               f continuous_on sphere(vec 0,&1) /\
6384               IMAGE f (sphere(vec 0,&1)) SUBSET s
6385               ==> ?a. homotopic_with (\h. T) (sphere(vec 0,&1),s) f (\x. a))`,
6386   REWRITE_TAC[AND_FORALL_THM] THEN GEN_TAC THEN MATCH_MP_TAC(TAUT
6387    `(p ==> q) /\ (q ==> r) /\ (r ==> p) ==> (p <=> q) /\ (p <=> r)`) THEN
6388   REPEAT CONJ_TAC THENL
6389    [REWRITE_TAC[simply_connected] THEN DISCH_TAC THEN
6390     MAP_EVERY X_GEN_TAC [`f:complex->real^N`; `g:complex->real^N`] THEN
6391     STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
6392      [`(f:complex->real^N) o cexp o (\t. Cx(&2 * pi * drop t) * ii)`;
6393       `(g:complex->real^N) o cexp o (\t. Cx(&2 * pi * drop t) * ii)`]) THEN
6394     ONCE_REWRITE_TAC[TAUT `p1 /\ q1 /\ r1 /\ p2 /\ q2 /\ r2 <=>
6395                            (p1 /\ r1 /\ q1) /\ (p2 /\ r2 /\ q2)`] THEN
6396     REWRITE_TAC[GSYM HOMOTOPIC_LOOPS_REFL] THEN
6397     ASM_SIMP_TAC[HOMOTOPIC_CIRCLEMAPS_IMP_HOMOTOPIC_LOOPS;
6398                  HOMOTOPIC_WITH_REFL] THEN
6399     DISCH_THEN(MP_TAC o MATCH_MP HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_CIRCLEMAPS) THEN
6400     MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] HOMOTOPIC_WITH_EQ) THEN
6401     REWRITE_TAC[IN_SPHERE_0; LIFT_DROP; o_DEF] THEN X_GEN_TAC `z:complex` THEN
6402     REPEAT STRIP_TAC THEN AP_TERM_TAC THEN MP_TAC(SPEC `z:complex` ARG) THEN
6403     ASM_REWRITE_TAC[COMPLEX_MUL_LID] THEN
6404     DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN SIMP_TAC[PI_POS;
6405       REAL_FIELD `&0 < pi ==> &2 * pi * x / (&2 * pi) = x`] THEN
6406     ASM_MESON_TAC[COMPLEX_MUL_SYM];
6407     DISCH_TAC THEN CONJ_TAC THENL
6408      [REWRITE_TAC[PATH_CONNECTED_EQ_HOMOTOPIC_POINTS] THEN
6409       MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN STRIP_TAC THEN
6410       FIRST_X_ASSUM(MP_TAC o SPECL
6411        [`(\x. a):complex->real^N`; `(\x. b):complex->real^N`]) THEN
6412       REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
6413       ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN DISCH_THEN
6414        (MP_TAC o MATCH_MP HOMOTOPIC_CIRCLEMAPS_IMP_HOMOTOPIC_LOOPS) THEN
6415       REWRITE_TAC[o_DEF; LINEPATH_REFL];
6416       X_GEN_TAC `f:complex->real^N` THEN STRIP_TAC THEN
6417       EXISTS_TAC `f(Cx(&1)):real^N` THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
6418       ASM_REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
6419       RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE; IN_SPHERE_0]) THEN
6420       REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_SPHERE_0] THEN
6421       REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
6422       REWRITE_TAC[COMPLEX_NORM_CX] THEN REAL_ARITH_TAC];
6423     STRIP_TAC THEN
6424     ASM_REWRITE_TAC[SIMPLY_CONNECTED_EQ_CONTRACTIBLE_LOOP_SOME] THEN
6425     X_GEN_TAC `p:real^1->real^N` THEN STRIP_TAC THEN
6426     FIRST_X_ASSUM(MP_TAC o SPEC
6427      `(p:real^1->real^N) o (\z. lift(Arg z / (&2 * pi)))`) THEN
6428     ANTS_TAC THENL
6429      [MP_TAC(ISPECL [`s:real^N->bool`; `p:real^1->real^N`]
6430         HOMOTOPIC_LOOPS_REFL) THEN
6431       ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o MATCH_MP
6432         HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_CIRCLEMAPS) THEN
6433       SIMP_TAC[HOMOTOPIC_WITH_REFL];
6434       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN
6435       STRIP_TAC THEN FIRST_ASSUM
6436        (MP_TAC o MATCH_MP HOMOTOPIC_CIRCLEMAPS_IMP_HOMOTOPIC_LOOPS) THEN
6437       FIRST_ASSUM(MP_TAC o MATCH_MP HOMOTOPIC_WITH_IMP_SUBSET) THEN
6438       REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_SPHERE_0; o_DEF] THEN
6439       DISCH_THEN(MP_TAC o SPEC `Cx(&1)` o CONJUNCT2) THEN
6440       REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM] THEN
6441       STRIP_TAC THEN ASM_REWRITE_TAC[LINEPATH_REFL] THEN
6442       MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HOMOTOPIC_LOOPS_TRANS) THEN
6443       MATCH_MP_TAC HOMOTOPIC_LOOPS_EQ THEN ASM_REWRITE_TAC[] THEN
6444       REWRITE_TAC[IN_INTERVAL_1; FORALL_LIFT; LIFT_DROP; DROP_VEC] THEN
6445       X_GEN_TAC `t:real` THEN STRIP_TAC THEN ASM_CASES_TAC `t = &1` THENL
6446        [ASM_REWRITE_TAC[REAL_ARITH `&2 * pi * &1 = &2 * &1 * pi`] THEN
6447         SIMP_TAC[CEXP_INTEGER_2PI; INTEGER_CLOSED; ARG_NUM] THEN
6448         REWRITE_TAC[real_div; REAL_MUL_LZERO; LIFT_NUM] THEN
6449         ASM_MESON_TAC[pathstart; pathfinish];
6450         AP_TERM_TAC THEN AP_TERM_TAC THEN SIMP_TAC[PI_POS; REAL_FIELD
6451          `&0 < pi ==> (t = x / (&2 * pi) <=> x = &2 * pi * t)`] THEN
6452         MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `Im(Cx (&2 * pi * t) * ii)` THEN
6453         CONJ_TAC THENL [MATCH_MP_TAC ARG_CEXP; ALL_TAC] THEN
6454         SIMP_TAC[IM_MUL_II; RE_CX; REAL_ARITH
6455           `a < &2 * pi <=> a < &2 * pi * &1`] THEN
6456         ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_LMUL_EQ; REAL_OF_NUM_LT; ARITH;
6457                      PI_POS; REAL_LT_IMP_LE; REAL_POS; REAL_LE_MUL] THEN
6458         ASM_REWRITE_TAC[REAL_LT_LE]]]]);;
6459
6460 let HOMOTOPY_EQUIVALENT_SIMPLE_CONNECTEDNESS = prove
6461  (`!s:real^M->bool t:real^N->bool.
6462         s homotopy_equivalent t
6463         ==> (simply_connected s <=> simply_connected t)`,
6464   REWRITE_TAC[SIMPLY_CONNECTED_EQ_HOMOTOPIC_CIRCLEMAPS] THEN
6465   REWRITE_TAC[HOMOTOPY_EQUIVALENT_HOMOTOPIC_TRIVIALITY]);;
6466
6467 (* ------------------------------------------------------------------------- *)
6468 (* Homeomorphism of simple closed curves to circles.                         *)
6469 (* ------------------------------------------------------------------------- *)
6470
6471 let HOMEOMORPHIC_SIMPLE_PATH_IMAGE_CIRCLE = prove
6472  (`!g:real^1->real^N a:real^2 r.
6473         simple_path g /\ pathfinish g = pathstart g /\ &0 < r
6474         ==> (path_image g) homeomorphic sphere(a,r)`,
6475   REPEAT STRIP_TAC THEN
6476   TRANS_TAC HOMEOMORPHIC_TRANS `sphere(vec 0:real^2,&1)` THEN
6477   ASM_SIMP_TAC[HOMEOMORPHIC_SPHERES; REAL_LT_01] THEN MP_TAC(ISPECL
6478    [`g:real^1->real^N`; `g:real^1->real^N`; `path_image(g:real^1->real^N)`]
6479    HOMOTOPIC_LOOPS_IMP_HOMOTOPIC_CIRCLEMAPS) THEN
6480   REWRITE_TAC[HOMOTOPIC_LOOPS_REFL; HOMOTOPIC_WITH_REFL; SUBSET_REFL] THEN
6481   ASM_SIMP_TAC[SIMPLE_PATH_IMP_PATH] THEN STRIP_TAC THEN
6482   ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN REWRITE_TAC[homeomorphic] THEN
6483   EXISTS_TAC `(g:real^1->real^N) o (\z. lift(Arg z / (&2 * pi)))` THEN
6484   MATCH_MP_TAC HOMEOMORPHISM_COMPACT THEN
6485   ASM_REWRITE_TAC[COMPACT_SPHERE] THEN CONJ_TAC THENL
6486    [MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN
6487     REWRITE_TAC[SUBSET; path_image; FORALL_IN_IMAGE; IN_INTERVAL_1] THEN
6488     X_GEN_TAC `t:real^1` THEN REWRITE_TAC[DROP_VEC] THEN STRIP_TAC THEN
6489     REWRITE_TAC[IN_IMAGE; o_THM; IN_SPHERE_0] THEN
6490     ASM_CASES_TAC `t:real^1 = vec 1` THENL
6491      [EXISTS_TAC `Cx(&1)` THEN
6492       ASM_REWRITE_TAC[ARG_NUM; COMPLEX_NORM_CX; real_div; REAL_MUL_LZERO] THEN
6493       REWRITE_TAC[LIFT_NUM; REAL_ABS_NUM] THEN
6494       ASM_MESON_TAC[pathstart; pathfinish];
6495       EXISTS_TAC `cexp(ii * Cx(&2 * pi * drop t))` THEN
6496       REWRITE_TAC[NORM_CEXP_II] THEN AP_TERM_TAC THEN
6497       W(MP_TAC o PART_MATCH (lhand o rand) ARG_CEXP o
6498         lhand o rand o rand o snd) THEN
6499       REWRITE_TAC[IM_MUL_II; RE_CX] THEN ANTS_TAC THENL
6500        [ASM_SIMP_TAC[REAL_LE_MUL; PI_POS_LE; REAL_POS] THEN
6501         SIMP_TAC[REAL_ARITH `&2 * pi * x < &2 * pi <=> pi * x < pi * &1`;
6502                  REAL_LT_LMUL_EQ; PI_POS] THEN
6503         ASM_REWRITE_TAC[REAL_LT_LE] THEN
6504         ASM_REWRITE_TAC[GSYM LIFT_EQ; LIFT_DROP; LIFT_NUM];
6505         DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[GSYM DROP_EQ; LIFT_DROP] THEN
6506         MP_TAC PI_POS THEN CONV_TAC REAL_FIELD]];
6507     MAP_EVERY X_GEN_TAC [`w:complex`; `z:complex`] THEN
6508     REWRITE_TAC[IN_SPHERE_0] THEN STRIP_TAC THEN
6509     MAP_EVERY (SUBST1_TAC o last o CONJUNCTS o C SPEC ARG)
6510      [`w:complex`; `z:complex`] THEN
6511     FIRST_X_ASSUM(MP_TAC o SYM o SYM) THEN
6512     ASM_REWRITE_TAC[o_DEF; COMPLEX_MUL_LID] THEN DISCH_TAC THEN
6513     AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
6514     MATCH_MP_TAC(REAL_FIELD
6515      `&0 < pi /\ x / (&2 * pi) = y / (&2 * pi) ==> x = y`) THEN
6516     REWRITE_TAC[PI_POS; GSYM LIFT_EQ] THEN
6517     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [simple_path]) THEN
6518     DISCH_THEN(MP_TAC  o SPECL
6519      [`lift(Arg w / (&2 * pi))`; `lift(Arg z / (&2 * pi))`] o CONJUNCT2) THEN
6520     ASM_REWRITE_TAC[GSYM LIFT_NUM; IN_INTERVAL_1; LIFT_DROP; LIFT_EQ] THEN
6521     ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; PI_POS;
6522                  REAL_ARITH `&0 < &2 * x <=> &0 < x`;
6523                  REAL_FIELD `&0 < y ==> (x / y = &1 <=> x = y)`] THEN
6524     SIMP_TAC[REAL_MUL_LZERO; REAL_MUL_LID; ARG; REAL_LT_IMP_LE;
6525              REAL_LT_IMP_NE]]);;
6526
6527 let HOMEOMORPHIC_SIMPLE_PATH_IMAGES = prove
6528  (`!g:real^1->real^M h:real^1->real^N.
6529         simple_path g /\ pathfinish g = pathstart g /\
6530         simple_path h /\ pathfinish h = pathstart h
6531         ==> (path_image g) homeomorphic (path_image h)`,
6532   REPEAT STRIP_TAC THEN
6533   TRANS_TAC HOMEOMORPHIC_TRANS `sphere(vec 0:real^2,&1)` THEN
6534   CONJ_TAC THENL [ALL_TAC; ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM]] THEN
6535   MATCH_MP_TAC HOMEOMORPHIC_SIMPLE_PATH_IMAGE_CIRCLE THEN
6536   ASM_REWRITE_TAC[REAL_LT_01]);;
6537
6538 let ANR_PATH_IMAGE_SIMPLE_PATH = prove
6539  (`!g:real^1->real^N.
6540         simple_path g ==> ?t. open t /\ (path_image g) retract_of t`,
6541   REPEAT STRIP_TAC THEN
6542   ASM_CASES_TAC `pathfinish g:real^N = pathstart g` THENL
6543    [MP_TAC(ISPECL [`g:real^1->real^N`; `vec 0:real^2`; `&1`]
6544         HOMEOMORPHIC_SIMPLE_PATH_IMAGE_CIRCLE) THEN
6545     ASM_REWRITE_TAC[REAL_LT_01] THEN
6546     DISCH_THEN(SUBST1_TAC o MATCH_MP HOMEOMORPHIC_ANRNESS) THEN
6547     EXISTS_TAC `(:real^2) DELETE (vec 0)` THEN
6548     SIMP_TAC[OPEN_DELETE; OPEN_UNIV] THEN
6549     MATCH_MP_TAC SPHERE_RETRACT_OF_PUNCTURED_UNIVERSE THEN
6550     REWRITE_TAC[REAL_LT_01];
6551     EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[OPEN_UNIV] THEN
6552     MATCH_MP_TAC ABSOLUTE_RETRACT_PATH_IMAGE_ARC THEN
6553     ASM_REWRITE_TAC[ARC_SIMPLE_PATH; SUBSET_UNIV]]);;