Update from HH
[Multivariate Analysis/.git] / Multivariate / complexes.ml
1 (* ========================================================================= *)
2 (* The type "real^2" regarded as the complex numbers.                        *)
3 (*                                                                           *)
4 (*              (c) Copyright, John Harrison 1998-2008                       *)
5 (*              (c) Copyright, Valentina Bruno 2010                          *)
6 (* ========================================================================= *)
7
8 needs "Multivariate/integration.ml";;
9
10 new_type_abbrev("complex",`:real^2`);;
11
12 let prioritize_complex() =
13   overload_interface("--",`vector_neg:complex->complex`);
14   overload_interface("+",`vector_add:complex->complex->complex`);
15   overload_interface("-",`vector_sub:complex->complex->complex`);
16   overload_interface("*",`complex_mul:complex->complex->complex`);
17   overload_interface("/",`complex_div:complex->complex->complex`);
18   overload_interface("pow",`complex_pow:complex->num->complex`);
19   overload_interface("inv",`complex_inv:complex->complex`);;
20
21 prioritize_complex();;
22
23 (* ------------------------------------------------------------------------- *)
24 (* Real and imaginary parts of a number.                                     *)
25 (* ------------------------------------------------------------------------- *)
26
27 let RE_DEF = new_definition
28   `Re(z:complex) = z$1`;;
29
30 let IM_DEF = new_definition
31   `Im(z:complex) = z$2`;;
32
33 (* ------------------------------------------------------------------------- *)
34 (* Real injection and imaginary unit.                                        *)
35 (* ------------------------------------------------------------------------- *)
36
37 let complex = new_definition
38  `complex(x,y) = vector[x;y]:complex`;;
39
40 let CX_DEF = new_definition
41  `Cx(a) = complex(a,&0)`;;
42
43 let ii = new_definition
44   `ii = complex(&0,&1)`;;
45
46 (* ------------------------------------------------------------------------- *)
47 (* Complex multiplication.                                                   *)
48 (* ------------------------------------------------------------------------- *)
49
50 let complex_mul = new_definition
51   `w * z = complex(Re(w) * Re(z) - Im(w) * Im(z),
52                    Re(w) * Im(z) + Im(w) * Re(z))`;;
53
54 let complex_inv = new_definition
55   `inv(z) = complex(Re(z) / (Re(z) pow 2 + Im(z) pow 2),
56                     --(Im(z)) / (Re(z) pow 2 + Im(z) pow 2))`;;
57
58 let complex_div = new_definition
59   `w / z = w * inv(z)`;;
60
61 let complex_pow = define
62   `(x pow 0 = Cx(&1)) /\
63    (!n. x pow (SUC n) = x * x pow n)`;;
64
65 (* ------------------------------------------------------------------------- *)
66 (* Various handy rewrites.                                                   *)
67 (* ------------------------------------------------------------------------- *)
68
69 let RE = prove
70  (`(Re(complex(x,y)) = x)`,
71   REWRITE_TAC[RE_DEF; complex; VECTOR_2]);;
72
73 let IM = prove
74  (`Im(complex(x,y)) = y`,
75   REWRITE_TAC[IM_DEF; complex; VECTOR_2]);;
76
77 let COMPLEX_EQ = prove
78  (`!w z. (w = z) <=> (Re(w) = Re(z)) /\ (Im(w) = Im(z))`,
79   SIMP_TAC[CART_EQ; FORALL_2; DIMINDEX_2; RE_DEF; IM_DEF]);;
80
81 let COMPLEX = prove
82  (`!z. complex(Re(z),Im(z)) = z`,
83   REWRITE_TAC[COMPLEX_EQ; RE; IM]);;
84
85 let COMPLEX_EQ_0 = prove
86  (`z = Cx(&0) <=> Re(z) pow 2 + Im(z) pow 2 = &0`,
87   REWRITE_TAC[COMPLEX_EQ; CX_DEF; RE; IM] THEN
88   EQ_TAC THEN SIMP_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
89   DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH
90    `!x y:real. x + y = &0 ==> &0 <= x /\ &0 <= y ==> x = &0 /\ y = &0`)) THEN
91   REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE; REAL_ENTIRE]);;
92
93 let FORALL_COMPLEX = prove
94  (`(!z. P z) <=> (!x y. P(complex(x,y)))`,
95   MESON_TAC[COMPLEX]);;
96
97 let EXISTS_COMPLEX = prove
98  (`(?z. P z) <=> (?x y. P(complex(x,y)))`,
99   MESON_TAC[COMPLEX]);;
100
101 (* ------------------------------------------------------------------------- *)
102 (* Pseudo-definitions of other general vector concepts over R^2.             *)
103 (* ------------------------------------------------------------------------- *)
104
105 let complex_neg = prove
106  (`--z = complex(--(Re(z)),--(Im(z)))`,
107   REWRITE_TAC[COMPLEX_EQ; RE; IM] THEN REWRITE_TAC[RE_DEF; IM_DEF] THEN
108   SIMP_TAC[VECTOR_NEG_COMPONENT; DIMINDEX_2; ARITH]);;
109
110 let complex_add = prove
111  (`w + z = complex(Re(w) + Re(z),Im(w) + Im(z))`,
112   REWRITE_TAC[COMPLEX_EQ; RE; IM] THEN REWRITE_TAC[RE_DEF; IM_DEF] THEN
113   SIMP_TAC[VECTOR_ADD_COMPONENT; DIMINDEX_2; ARITH]);;
114
115 let complex_sub = VECTOR_ARITH `(w:complex) - z = w + --z`;;
116
117 let complex_norm = prove
118  (`norm(z) = sqrt(Re(z) pow 2 + Im(z) pow 2)`,
119   REWRITE_TAC[vector_norm; dot; RE_DEF; IM_DEF; SUM_2; DIMINDEX_2] THEN
120   AP_TERM_TAC THEN REAL_ARITH_TAC);;
121
122 let COMPLEX_SQNORM = prove
123  (`norm(z) pow 2 = Re(z) pow 2 + Im(z) pow 2`,
124   REWRITE_TAC[NORM_POW_2; dot; RE_DEF; IM_DEF; SUM_2; DIMINDEX_2] THEN
125   REAL_ARITH_TAC);;
126
127 (* ------------------------------------------------------------------------- *)
128 (* Crude tactic to automate very simple algebraic equivalences.              *)
129 (* ------------------------------------------------------------------------- *)
130
131 let SIMPLE_COMPLEX_ARITH_TAC =
132   REWRITE_TAC[COMPLEX_EQ; RE; IM; CX_DEF;
133               complex_add; complex_neg; complex_sub; complex_mul;
134               complex_inv; complex_div] THEN
135   CONV_TAC REAL_FIELD;;
136
137 let SIMPLE_COMPLEX_ARITH tm = prove(tm,SIMPLE_COMPLEX_ARITH_TAC);;
138
139 (* ------------------------------------------------------------------------- *)
140 (* Basic algebraic properties that can be proved automatically by this.      *)
141 (* ------------------------------------------------------------------------- *)
142
143 let COMPLEX_ADD_SYM = prove
144  (`!x y. x + y = y + x`,
145   SIMPLE_COMPLEX_ARITH_TAC);;
146
147 let COMPLEX_ADD_ASSOC = prove
148  (`!x y z. x + y + z = (x + y) + z`,
149   SIMPLE_COMPLEX_ARITH_TAC);;
150
151 let COMPLEX_ADD_LID = prove
152  (`!x. Cx(&0) + x = x`,
153   SIMPLE_COMPLEX_ARITH_TAC);;
154
155 let COMPLEX_ADD_LINV = prove
156  (`!x. --x + x = Cx(&0)`,
157   SIMPLE_COMPLEX_ARITH_TAC);;
158
159 let COMPLEX_MUL_SYM = prove
160  (`!x y. x * y = y * x`,
161   SIMPLE_COMPLEX_ARITH_TAC);;
162
163 let COMPLEX_MUL_ASSOC = prove
164  (`!x y z. x * y * z = (x * y) * z`,
165   SIMPLE_COMPLEX_ARITH_TAC);;
166
167 let COMPLEX_MUL_LID = prove
168  (`!x. Cx(&1) * x = x`,
169   SIMPLE_COMPLEX_ARITH_TAC);;
170
171 let COMPLEX_ADD_LDISTRIB = prove
172  (`!x y z. x * (y + z) = x * y + x * z`,
173   SIMPLE_COMPLEX_ARITH_TAC);;
174
175 let COMPLEX_ADD_AC = prove
176  (`(m + n = n + m) /\ ((m + n) + p = m + n + p) /\ (m + n + p = n + m + p)`,
177   SIMPLE_COMPLEX_ARITH_TAC);;
178
179 let COMPLEX_MUL_AC = prove
180  (`(m * n = n * m) /\ ((m * n) * p = m * n * p) /\ (m * n * p = n * m * p)`,
181   SIMPLE_COMPLEX_ARITH_TAC);;
182
183 let COMPLEX_ADD_RID = prove
184  (`!x. x + Cx(&0) = x`,
185   SIMPLE_COMPLEX_ARITH_TAC);;
186
187 let COMPLEX_MUL_RID = prove
188  (`!x. x * Cx(&1) = x`,
189   SIMPLE_COMPLEX_ARITH_TAC);;
190
191 let COMPLEX_ADD_RINV = prove
192  (`!x. x + --x = Cx(&0)`,
193   SIMPLE_COMPLEX_ARITH_TAC);;
194
195 let COMPLEX_ADD_RDISTRIB = prove
196  (`!x y z. (x + y) * z = x * z + y * z`,
197   SIMPLE_COMPLEX_ARITH_TAC);;
198
199 let COMPLEX_EQ_ADD_LCANCEL = prove
200  (`!x y z. (x + y = x + z) <=> (y = z)`,
201   SIMPLE_COMPLEX_ARITH_TAC);;
202
203 let COMPLEX_EQ_ADD_RCANCEL = prove
204  (`!x y z. (x + z = y + z) <=> (x = y)`,
205   SIMPLE_COMPLEX_ARITH_TAC);;
206
207 let COMPLEX_MUL_RZERO = prove
208  (`!x. x * Cx(&0) = Cx(&0)`,
209   SIMPLE_COMPLEX_ARITH_TAC);;
210
211 let COMPLEX_MUL_LZERO = prove
212  (`!x. Cx(&0) * x = Cx(&0)`,
213   SIMPLE_COMPLEX_ARITH_TAC);;
214
215 let COMPLEX_NEG_NEG = prove
216  (`!x. --(--x) = x`,
217   SIMPLE_COMPLEX_ARITH_TAC);;
218
219 let COMPLEX_MUL_RNEG = prove
220  (`!x y. x * --y = --(x * y)`,
221   SIMPLE_COMPLEX_ARITH_TAC);;
222
223 let COMPLEX_MUL_LNEG = prove
224  (`!x y. --x * y = --(x * y)`,
225   SIMPLE_COMPLEX_ARITH_TAC);;
226
227 let COMPLEX_NEG_ADD = prove
228  (`!x y. --(x + y) = --x + --y`,
229   SIMPLE_COMPLEX_ARITH_TAC);;
230
231 let COMPLEX_NEG_0 = prove
232  (`--Cx(&0) = Cx(&0)`,
233   SIMPLE_COMPLEX_ARITH_TAC);;
234
235 let COMPLEX_EQ_ADD_LCANCEL_0 = prove
236  (`!x y. (x + y = x) <=> (y = Cx(&0))`,
237   SIMPLE_COMPLEX_ARITH_TAC);;
238
239 let COMPLEX_EQ_ADD_RCANCEL_0 = prove
240  (`!x y. (x + y = y) <=> (x = Cx(&0))`,
241   SIMPLE_COMPLEX_ARITH_TAC);;
242
243 let COMPLEX_LNEG_UNIQ = prove
244  (`!x y. (x + y = Cx(&0)) <=> (x = --y)`,
245   SIMPLE_COMPLEX_ARITH_TAC);;
246
247 let COMPLEX_RNEG_UNIQ = prove
248  (`!x y. (x + y = Cx(&0)) <=> (y = --x)`,
249   SIMPLE_COMPLEX_ARITH_TAC);;
250
251 let COMPLEX_NEG_LMUL = prove
252  (`!x y. --(x * y) = --x * y`,
253   SIMPLE_COMPLEX_ARITH_TAC);;
254
255 let COMPLEX_NEG_RMUL = prove
256  (`!x y. --(x * y) = x * --y`,
257   SIMPLE_COMPLEX_ARITH_TAC);;
258
259 let COMPLEX_NEG_MUL2 = prove
260  (`!x y. --x * --y = x * y`,
261   SIMPLE_COMPLEX_ARITH_TAC);;
262
263 let COMPLEX_SUB_ADD = prove
264  (`!x y. x - y + y = x`,
265   SIMPLE_COMPLEX_ARITH_TAC);;
266
267 let COMPLEX_SUB_ADD2 = prove
268  (`!x y. y + x - y = x`,
269   SIMPLE_COMPLEX_ARITH_TAC);;
270
271 let COMPLEX_SUB_REFL = prove
272  (`!x. x - x = Cx(&0)`,
273   SIMPLE_COMPLEX_ARITH_TAC);;
274
275 let COMPLEX_SUB_0 = prove
276  (`!x y. (x - y = Cx(&0)) <=> (x = y)`,
277   SIMPLE_COMPLEX_ARITH_TAC);;
278
279 let COMPLEX_NEG_EQ_0 = prove
280  (`!x. (--x = Cx(&0)) <=> (x = Cx(&0))`,
281   SIMPLE_COMPLEX_ARITH_TAC);;
282
283 let COMPLEX_NEG_SUB = prove
284  (`!x y. --(x - y) = y - x`,
285   SIMPLE_COMPLEX_ARITH_TAC);;
286
287 let COMPLEX_ADD_SUB = prove
288  (`!x y. (x + y) - x = y`,
289   SIMPLE_COMPLEX_ARITH_TAC);;
290
291 let COMPLEX_NEG_EQ = prove
292  (`!x y. (--x = y) <=> (x = --y)`,
293   SIMPLE_COMPLEX_ARITH_TAC);;
294
295 let COMPLEX_NEG_MINUS1 = prove
296  (`!x. --x = --Cx(&1) * x`,
297   SIMPLE_COMPLEX_ARITH_TAC);;
298
299 let COMPLEX_SUB_SUB = prove
300  (`!x y. x - y - x = --y`,
301   SIMPLE_COMPLEX_ARITH_TAC);;
302
303 let COMPLEX_ADD2_SUB2 = prove
304  (`!a b c d. (a + b) - (c + d) = a - c + b - d`,
305   SIMPLE_COMPLEX_ARITH_TAC);;
306
307 let COMPLEX_SUB_LZERO = prove
308  (`!x. Cx(&0) - x = --x`,
309   SIMPLE_COMPLEX_ARITH_TAC);;
310
311 let COMPLEX_SUB_RZERO = prove
312  (`!x. x - Cx(&0) = x`,
313   SIMPLE_COMPLEX_ARITH_TAC);;
314
315 let COMPLEX_SUB_LNEG = prove
316  (`!x y. --x - y = --(x + y)`,
317   SIMPLE_COMPLEX_ARITH_TAC);;
318
319 let COMPLEX_SUB_RNEG = prove
320  (`!x y. x - --y = x + y`,
321   SIMPLE_COMPLEX_ARITH_TAC);;
322
323 let COMPLEX_SUB_NEG2 = prove
324  (`!x y. --x - --y = y - x`,
325   SIMPLE_COMPLEX_ARITH_TAC);;
326
327 let COMPLEX_SUB_TRIANGLE = prove
328  (`!a b c. a - b + b - c = a - c`,
329   SIMPLE_COMPLEX_ARITH_TAC);;
330
331 let COMPLEX_EQ_SUB_LADD = prove
332  (`!x y z. (x = y - z) <=> (x + z = y)`,
333   SIMPLE_COMPLEX_ARITH_TAC);;
334
335 let COMPLEX_EQ_SUB_RADD = prove
336  (`!x y z. (x - y = z) <=> (x = z + y)`,
337   SIMPLE_COMPLEX_ARITH_TAC);;
338
339 let COMPLEX_SUB_SUB2 = prove
340  (`!x y. x - (x - y) = y`,
341   SIMPLE_COMPLEX_ARITH_TAC);;
342
343 let COMPLEX_ADD_SUB2 = prove
344  (`!x y. x - (x + y) = --y`,
345   SIMPLE_COMPLEX_ARITH_TAC);;
346
347 let COMPLEX_DIFFSQ = prove
348  (`!x y. (x + y) * (x - y) = x * x - y * y`,
349   SIMPLE_COMPLEX_ARITH_TAC);;
350
351 let COMPLEX_EQ_NEG2 = prove
352  (`!x y. (--x = --y) <=> (x = y)`,
353   SIMPLE_COMPLEX_ARITH_TAC);;
354
355 let COMPLEX_SUB_LDISTRIB = prove
356  (`!x y z. x * (y - z) = x * y - x * z`,
357   SIMPLE_COMPLEX_ARITH_TAC);;
358
359 let COMPLEX_SUB_RDISTRIB = prove
360  (`!x y z. (x - y) * z = x * z - y * z`,
361   SIMPLE_COMPLEX_ARITH_TAC);;
362
363 let COMPLEX_MUL_2 = prove
364  (`!x. Cx(&2) * x = x + x`,
365   SIMPLE_COMPLEX_ARITH_TAC);;
366
367 (* ------------------------------------------------------------------------- *)
368 (* Sometimes here we need to tweak non-zeroness assertions.                  *)
369 (* ------------------------------------------------------------------------- *)
370
371 let II_NZ = prove
372  (`~(ii = Cx(&0))`,
373   REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);;
374
375 let COMPLEX_MUL_LINV = prove
376  (`!z. ~(z = Cx(&0)) ==> (inv(z) * z = Cx(&1))`,
377   REWRITE_TAC[COMPLEX_EQ_0] THEN SIMPLE_COMPLEX_ARITH_TAC);;
378
379 let COMPLEX_ENTIRE = prove
380  (`!x y. (x * y = Cx(&0)) <=> (x = Cx(&0)) \/ (y = Cx(&0))`,
381   REWRITE_TAC[COMPLEX_EQ_0] THEN SIMPLE_COMPLEX_ARITH_TAC);;
382
383 let COMPLEX_MUL_RINV = prove
384  (`!z. ~(z = Cx(&0)) ==> (z * inv(z) = Cx(&1))`,
385   REWRITE_TAC[COMPLEX_EQ_0] THEN SIMPLE_COMPLEX_ARITH_TAC);;
386
387 let COMPLEX_DIV_REFL = prove
388  (`!x. ~(x = Cx(&0)) ==> (x / x = Cx(&1))`,
389   REWRITE_TAC[COMPLEX_EQ_0] THEN SIMPLE_COMPLEX_ARITH_TAC);;
390
391 (* ------------------------------------------------------------------------- *)
392 (* Homomorphic embedding properties for Cx mapping.                          *)
393 (* ------------------------------------------------------------------------- *)
394
395 let CX_INJ = prove
396  (`!x y. (Cx(x) = Cx(y)) <=> (x = y)`,
397   REWRITE_TAC[CX_DEF; COMPLEX_EQ; RE; IM]);;
398
399 let CX_NEG = prove
400  (`!x. Cx(--x) = --(Cx(x))`,
401   REWRITE_TAC[CX_DEF; complex_neg; RE; IM; REAL_NEG_0]);;
402
403 let CX_ADD = prove
404  (`!x y. Cx(x + y) = Cx(x) + Cx(y)`,
405   REWRITE_TAC[CX_DEF; complex_add; RE; IM; REAL_ADD_LID]);;
406
407 let CX_SUB = prove
408  (`!x y. Cx(x - y) = Cx(x) - Cx(y)`,
409   REWRITE_TAC[complex_sub; real_sub; CX_ADD; CX_NEG]);;
410
411 let CX_INV = prove
412  (`!x. Cx(inv x) = inv(Cx x)`,
413   GEN_TAC THEN REWRITE_TAC[CX_DEF; complex_inv; RE; IM; COMPLEX_EQ] THEN
414   ASM_CASES_TAC `x = &0` THEN ASM_REWRITE_TAC[] THEN
415   CONV_TAC REAL_RAT_REDUCE_CONV THEN
416   POP_ASSUM MP_TAC THEN CONV_TAC REAL_FIELD);;
417
418 let CX_MUL = prove
419  (`!x y. Cx(x * y) = Cx(x) * Cx(y)`,
420   REWRITE_TAC[CX_DEF; complex_mul; RE; IM; REAL_MUL_LZERO; REAL_MUL_RZERO] THEN
421   REWRITE_TAC[REAL_SUB_RZERO; REAL_ADD_RID]);;
422
423 let CX_POW = prove
424  (`!x n. Cx(x pow n) = Cx(x) pow n`,
425   GEN_TAC THEN INDUCT_TAC THEN
426   ASM_REWRITE_TAC[complex_pow; real_pow; CX_MUL]);;
427
428 let CX_DIV = prove
429  (`!x y. Cx(x / y) = Cx(x) / Cx(y)`,
430   REWRITE_TAC[complex_div; real_div; CX_MUL; CX_INV]);;
431
432 let CX_ABS = prove
433  (`!x. Cx(abs x) = Cx(norm(Cx(x)))`,
434   REWRITE_TAC[CX_DEF; complex_norm; COMPLEX_EQ; RE; IM] THEN
435   REWRITE_TAC[REAL_POW_2; REAL_MUL_LZERO; REAL_ADD_RID] THEN
436   REWRITE_TAC[GSYM REAL_POW_2; POW_2_SQRT_ABS]);;
437
438 let COMPLEX_NORM_CX = prove
439  (`!x. norm(Cx(x)) = abs(x)`,
440   REWRITE_TAC[GSYM CX_INJ; CX_ABS]);;
441
442 (* ------------------------------------------------------------------------- *)
443 (* Some "linear" things hold for Re and Im too.                              *)
444 (* ------------------------------------------------------------------------- *)
445
446 let RE_CX = prove
447  (`!x. Re(Cx x) = x`,
448   REWRITE_TAC[RE; CX_DEF]);;
449
450 let RE_NEG = prove
451  (`!x. Re(--x) = --Re(x)`,
452   REWRITE_TAC[complex_neg; RE]);;
453
454 let RE_ADD = prove
455  (`!x y. Re(x + y) = Re(x) + Re(y)`,
456   REWRITE_TAC[complex_add; RE]);;
457
458 let RE_SUB = prove
459  (`!x y. Re(x - y) = Re(x) - Re(y)`,
460   REWRITE_TAC[complex_sub; real_sub; RE_ADD; RE_NEG]);;
461
462 let IM_CX = prove
463  (`!x. Im(Cx x) = &0`,
464   REWRITE_TAC[IM; CX_DEF]);;
465
466 let IM_NEG = prove
467  (`!x. Im(--x) = --Im(x)`,
468   REWRITE_TAC[complex_neg; IM]);;
469
470 let IM_ADD = prove
471  (`!x y. Im(x + y) = Im(x) + Im(y)`,
472   REWRITE_TAC[complex_add; IM]);;
473
474 let IM_SUB = prove
475  (`!x y. Im(x - y) = Im(x) - Im(y)`,
476   REWRITE_TAC[complex_sub; real_sub; IM_ADD; IM_NEG]);;
477
478 (* ------------------------------------------------------------------------- *)
479 (* An "expansion" theorem into the traditional notation.                     *)
480 (* ------------------------------------------------------------------------- *)
481
482 let COMPLEX_EXPAND = prove
483  (`!z. z = Cx(Re z) + ii * Cx(Im z)`,
484   REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);;
485
486 let COMPLEX_TRAD = prove
487  (`!x y. complex(x,y) = Cx(x) + ii * Cx(y)`,
488   REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);;
489
490 (* ------------------------------------------------------------------------- *)
491 (* Real and complex parts of ii and multiples.                               *)
492 (* ------------------------------------------------------------------------- *)
493
494 let RE_II = prove
495  (`Re ii = &0`,
496   REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);;
497
498 let IM_II = prove
499  (`Im ii = &1`,
500   REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);;
501
502 let RE_MUL_II = prove
503  (`!z. Re(z * ii) = --(Im z) /\ Re(ii * z) = --(Im z)`,
504   REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);;
505
506 let IM_MUL_II = prove
507  (`!z. Im(z * ii) = Re z /\ Im(ii * z) = Re z`,
508   REWRITE_TAC[ii] THEN SIMPLE_COMPLEX_ARITH_TAC);;
509
510 let COMPLEX_NORM_II = prove
511  (`norm ii = &1`,
512   REWRITE_TAC[complex_norm; RE_II; IM_II] THEN
513   CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[SQRT_1]);;
514
515 (* ------------------------------------------------------------------------- *)
516 (* Limited "multiplicative" theorems for Re and Im.                          *)
517 (* ------------------------------------------------------------------------- *)
518
519 let RE_CMUL = prove
520  (`!a z. Re(a % z) = a * Re z`,
521   SIMP_TAC[RE_DEF; VECTOR_MUL_COMPONENT; DIMINDEX_2; ARITH]);;
522
523 let IM_CMUL = prove
524  (`!a z. Im(a % z) = a * Im z`,
525   SIMP_TAC[IM_DEF; VECTOR_MUL_COMPONENT; DIMINDEX_2; ARITH]);;
526
527 let RE_MUL_CX = prove
528  (`!x z. Re(Cx(x) * z) = x * Re z /\
529          Re(z * Cx(x)) = Re z * x`,
530   SIMPLE_COMPLEX_ARITH_TAC);;
531
532 let IM_MUL_CX = prove
533  (`!x z. Im(Cx(x) * z) = x * Im z /\
534          Im(z * Cx(x)) = Im z * x`,
535   SIMPLE_COMPLEX_ARITH_TAC);;
536
537 let RE_DIV_CX = prove
538  (`!z x. Re(z / Cx(x)) = Re(z) / x`,
539   REWRITE_TAC[complex_div; real_div; GSYM CX_INV; RE_MUL_CX]);;
540
541 let IM_DIV_CX = prove
542  (`!z x. Im(z / Cx(x)) = Im(z) / x`,
543   REWRITE_TAC[complex_div; real_div; GSYM CX_INV; IM_MUL_CX]);;
544
545 (* ------------------------------------------------------------------------- *)
546 (* Syntax constructors etc. for complex constants.                           *)
547 (* ------------------------------------------------------------------------- *)
548
549 let is_complex_const =
550   let cx_tm = `Cx` in
551   fun tm ->
552     is_comb tm &
553     let l,r = dest_comb tm in l = cx_tm & is_ratconst r;;
554
555 let dest_complex_const =
556   let cx_tm = `Cx` in
557   fun tm ->
558     let l,r = dest_comb tm in
559     if l = cx_tm then rat_of_term r
560     else failwith "dest_complex_const";;
561
562 let mk_complex_const =
563   let cx_tm = `Cx` in
564   fun r ->
565     mk_comb(cx_tm,term_of_rat r);;
566
567 (* ------------------------------------------------------------------------- *)
568 (* Conversions for arithmetic on complex constants.                          *)
569 (* ------------------------------------------------------------------------- *)
570
571 let COMPLEX_RAT_EQ_CONV =
572   GEN_REWRITE_CONV I [CX_INJ] THENC REAL_RAT_EQ_CONV;;
573
574 let COMPLEX_RAT_MUL_CONV =
575   GEN_REWRITE_CONV I [GSYM CX_MUL] THENC RAND_CONV REAL_RAT_MUL_CONV;;
576
577 let COMPLEX_RAT_ADD_CONV =
578   GEN_REWRITE_CONV I [GSYM CX_ADD] THENC RAND_CONV REAL_RAT_ADD_CONV;;
579
580 let COMPLEX_RAT_POW_CONV =
581   let x_tm = `x:real`
582   and n_tm = `n:num` in
583   let pth = SYM(SPECL [x_tm; n_tm] CX_POW) in
584   fun tm ->
585     let lop,r = dest_comb tm in
586     let op,bod = dest_comb lop in
587     let th1 = INST [rand bod,x_tm; r,n_tm] pth in
588     let tm1,tm2 = dest_comb(concl th1) in
589     if rand tm1 <> tm then failwith "COMPLEX_RAT_POW_CONV" else
590     let tm3,tm4 = dest_comb tm2 in
591     TRANS th1 (AP_TERM tm3 (REAL_RAT_REDUCE_CONV tm4));;
592
593 (* ------------------------------------------------------------------------- *)
594 (* Complex polynomial normalizer.                                            *)
595 (* ------------------------------------------------------------------------- *)
596
597 let COMPLEX_POLY_CLAUSES = prove
598  (`(!x y z. x + (y + z) = (x + y) + z) /\
599    (!x y. x + y = y + x) /\
600    (!x. Cx(&0) + x = x) /\
601    (!x y z. x * (y * z) = (x * y) * z) /\
602    (!x y. x * y = y * x) /\
603    (!x. Cx(&1) * x = x) /\
604    (!x. Cx(&0) * x = Cx(&0)) /\
605    (!x y z. x * (y + z) = x * y + x * z) /\
606    (!x. x pow 0 = Cx(&1)) /\
607    (!x n. x pow (SUC n) = x * x pow n)`,
608   REWRITE_TAC[complex_pow] THEN SIMPLE_COMPLEX_ARITH_TAC)
609 and COMPLEX_POLY_NEG_CLAUSES = prove
610  (`(!x. --x = Cx(-- &1) * x) /\
611    (!x y. x - y = x + Cx(-- &1) * y)`,
612   SIMPLE_COMPLEX_ARITH_TAC);;
613
614 let COMPLEX_POLY_NEG_CONV,COMPLEX_POLY_ADD_CONV,COMPLEX_POLY_SUB_CONV,
615     COMPLEX_POLY_MUL_CONV,COMPLEX_POLY_POW_CONV,COMPLEX_POLY_CONV =
616   SEMIRING_NORMALIZERS_CONV COMPLEX_POLY_CLAUSES COMPLEX_POLY_NEG_CLAUSES
617    (is_complex_const,
618     COMPLEX_RAT_ADD_CONV,COMPLEX_RAT_MUL_CONV,COMPLEX_RAT_POW_CONV)
619    (<);;
620
621 (* ------------------------------------------------------------------------- *)
622 (* Extend it to handle "inv" and division, by constants after normalization. *)
623 (* ------------------------------------------------------------------------- *)
624
625 let COMPLEX_RAT_INV_CONV =
626   REWR_CONV(GSYM CX_INV) THENC RAND_CONV REAL_RAT_INV_CONV;;
627
628 let COMPLEX_POLY_CONV =
629   let neg_tm = `(--):complex->complex`
630   and inv_tm = `inv:complex->complex`
631   and add_tm = `(+):complex->complex->complex`
632   and sub_tm = `(-):complex->complex->complex`
633   and mul_tm = `(*):complex->complex->complex`
634   and div_tm = `(/):complex->complex->complex`
635   and pow_tm = `(pow):complex->num->complex`
636   and div_conv = REWR_CONV complex_div in
637   let rec COMPLEX_POLY_CONV tm =
638     if not(is_comb tm) or is_ratconst tm then REFL tm else
639     let lop,r = dest_comb tm in
640     if lop = neg_tm then
641       let th1 = AP_TERM lop (COMPLEX_POLY_CONV r) in
642       TRANS th1 (COMPLEX_POLY_NEG_CONV (rand(concl th1)))
643     else if lop = inv_tm then
644       let th1 = AP_TERM lop (COMPLEX_POLY_CONV r) in
645       TRANS th1 (TRY_CONV COMPLEX_RAT_INV_CONV (rand(concl th1)))
646     else if not(is_comb lop) then REFL tm else
647     let op,l = dest_comb lop in
648     if op = pow_tm then
649       let th1 = AP_THM (AP_TERM op (COMPLEX_POLY_CONV l)) r in
650       TRANS th1 (TRY_CONV COMPLEX_POLY_POW_CONV (rand(concl th1)))
651     else if op = add_tm or op = mul_tm or op = sub_tm then
652       let th1 = MK_COMB(AP_TERM op (COMPLEX_POLY_CONV l),
653                         COMPLEX_POLY_CONV r) in
654       let fn = if op = add_tm then COMPLEX_POLY_ADD_CONV
655                else if op = mul_tm then COMPLEX_POLY_MUL_CONV
656                else COMPLEX_POLY_SUB_CONV in
657       TRANS th1 (fn (rand(concl th1)))
658     else if op = div_tm then
659       let th1 = div_conv tm in
660       TRANS th1 (COMPLEX_POLY_CONV (rand(concl th1)))
661     else REFL tm in
662   COMPLEX_POLY_CONV;;
663
664 (* ------------------------------------------------------------------------- *)
665 (* Complex number version of usual ring procedure.                           *)
666 (* ------------------------------------------------------------------------- *)
667
668 let COMPLEX_RING,complex_ideal_cofactors =
669   let COMPLEX_INTEGRAL = prove
670    (`(!x. Cx(&0) * x = Cx(&0)) /\
671      (!x y z. (x + y = x + z) <=> (y = z)) /\
672      (!w x y z. (w * y + x * z = w * z + x * y) <=> (w = x) \/ (y = z))`,
673     REWRITE_TAC[COMPLEX_ENTIRE; SIMPLE_COMPLEX_ARITH
674      `(w * y + x * z = w * z + x * y) <=>
675       (w - x) * (y - z) = Cx(&0)`] THEN
676     SIMPLE_COMPLEX_ARITH_TAC)
677   and COMPLEX_RABINOWITSCH = prove
678    (`!x y:complex. ~(x = y) <=> ?z. (x - y) * z = Cx(&1)`,
679     REPEAT GEN_TAC THEN
680     GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM COMPLEX_SUB_0] THEN
681     MESON_TAC[COMPLEX_MUL_RINV; COMPLEX_MUL_LZERO;
682               SIMPLE_COMPLEX_ARITH `~(Cx(&1) = Cx(&0))`])
683   and COMPLEX_IIII = prove
684    (`ii * ii + Cx(&1) = Cx(&0)`,
685     REWRITE_TAC[ii; CX_DEF; complex_mul; complex_add; RE; IM] THEN
686     AP_TERM_TAC THEN BINOP_TAC THEN REAL_ARITH_TAC) in
687   let ring,ideal =
688     RING_AND_IDEAL_CONV
689         (dest_complex_const,mk_complex_const,COMPLEX_RAT_EQ_CONV,
690          `(--):complex->complex`,`(+):complex->complex->complex`,
691          `(-):complex->complex->complex`,`(inv):complex->complex`,
692          `(*):complex->complex->complex`,`(/):complex->complex->complex`,
693          `(pow):complex->num->complex`,
694          COMPLEX_INTEGRAL,COMPLEX_RABINOWITSCH,COMPLEX_POLY_CONV)
695   and ii_tm = `ii` and iiii_tm = concl COMPLEX_IIII in
696   (fun tm -> if free_in ii_tm tm then
697              MP (ring (mk_imp(iiii_tm,tm))) COMPLEX_IIII
698              else ring tm),
699   ideal;;
700
701 (* ------------------------------------------------------------------------- *)
702 (* Most basic properties of inverses.                                        *)
703 (* ------------------------------------------------------------------------- *)
704
705 let COMPLEX_INV_0 = prove
706  (`inv(Cx(&0)) = Cx(&0)`,
707   SIMPLE_COMPLEX_ARITH_TAC);;
708
709 let COMPLEX_INV_1 = prove
710  (`inv(Cx(&1)) = Cx(&1)`,
711   SIMPLE_COMPLEX_ARITH_TAC);;
712
713 let COMPLEX_INV_MUL = prove
714  (`!w z. inv(w * z) = inv(w) * inv(z)`,
715   REPEAT GEN_TAC THEN
716   MAP_EVERY ASM_CASES_TAC [`w = Cx(&0)`; `z = Cx(&0)`] THEN
717   ASM_REWRITE_TAC[COMPLEX_INV_0; COMPLEX_MUL_LZERO; COMPLEX_MUL_RZERO] THEN
718   REPEAT(POP_ASSUM MP_TAC) THEN
719   REWRITE_TAC[complex_mul; complex_inv; RE; IM; COMPLEX_EQ; CX_DEF] THEN
720   REWRITE_TAC[GSYM REAL_SOS_EQ_0] THEN CONV_TAC REAL_FIELD);;
721
722 let COMPLEX_POW_INV = prove
723  (`!x n. (inv x) pow n = inv(x pow n)`,
724   GEN_TAC THEN INDUCT_TAC THEN
725   ASM_REWRITE_TAC[complex_pow; COMPLEX_INV_1; COMPLEX_INV_MUL]);;
726
727 let COMPLEX_INV_INV = prove
728  (`!x:complex. inv(inv x) = x`,
729   GEN_TAC THEN ASM_CASES_TAC `x = Cx(&0)` THEN
730   ASM_REWRITE_TAC[COMPLEX_INV_0] THEN
731   POP_ASSUM MP_TAC THEN
732   MAP_EVERY (fun t -> MP_TAC(SPEC t COMPLEX_MUL_RINV))
733    [`x:complex`; `inv(x):complex`] THEN
734   CONV_TAC COMPLEX_RING);;
735
736 let COMPLEX_INV_DIV = prove
737  (`!w z:complex. inv(w / z) = z / w`,
738   REWRITE_TAC[complex_div; COMPLEX_INV_MUL; COMPLEX_INV_INV] THEN
739   REWRITE_TAC[COMPLEX_MUL_AC]);;
740
741 (* ------------------------------------------------------------------------- *)
742 (* And also field procedure.                                                 *)
743 (* ------------------------------------------------------------------------- *)
744
745 let COMPLEX_EQ_MUL_LCANCEL = prove
746  (`!x y z. (x * y = x * z) <=> (x = Cx(&0)) \/ (y = z)`,
747   CONV_TAC COMPLEX_RING);;
748
749 let COMPLEX_EQ_MUL_RCANCEL = prove
750  (`!x y z. (x * z = y * z) <=> (x = y) \/ (z = Cx(&0))`,
751   CONV_TAC COMPLEX_RING);;
752
753 let COMPLEX_FIELD =
754   let prenex_conv =
755     TOP_DEPTH_CONV BETA_CONV THENC
756     PURE_REWRITE_CONV[FORALL_SIMP; EXISTS_SIMP; complex_div;
757                COMPLEX_INV_INV; COMPLEX_INV_MUL; GSYM COMPLEX_POW_INV] THENC
758     NNFC_CONV THENC DEPTH_BINOP_CONV `(/\)` CONDS_CELIM_CONV THENC
759     PRENEX_CONV
760   and setup_conv = NNF_CONV THENC WEAK_CNF_CONV THENC CONJ_CANON_CONV
761   and is_inv =
762     let inv_tm = `inv:complex->complex`
763     and is_div = is_binop `(/):complex->complex->complex` in
764     fun tm -> (is_div tm or (is_comb tm & rator tm = inv_tm)) &
765               not(is_ratconst(rand tm)) in
766   let BASIC_COMPLEX_FIELD tm =
767     let is_freeinv t = is_inv t & free_in t tm in
768     let itms = setify(map rand (find_terms is_freeinv tm)) in
769     let hyps = map (fun t -> SPEC t COMPLEX_MUL_RINV) itms in
770     let tm' = itlist (fun th t -> mk_imp(concl th,t)) hyps tm in
771     let th1 = setup_conv tm' in
772     let cjs = conjuncts(rand(concl th1)) in
773     let ths = map COMPLEX_RING cjs in
774     let th2 = EQ_MP (SYM th1) (end_itlist CONJ ths) in
775     rev_itlist (C MP) hyps th2 in
776   fun tm ->
777     let th0 = prenex_conv tm in
778     let tm0 = rand(concl th0) in
779     let avs,bod = strip_forall tm0 in
780     let th1 = setup_conv bod in
781     let ths = map BASIC_COMPLEX_FIELD (conjuncts(rand(concl th1))) in
782     EQ_MP (SYM th0) (GENL avs (EQ_MP (SYM th1) (end_itlist CONJ ths)));;
783
784 (* ------------------------------------------------------------------------- *)
785 (* More trivial lemmas.                                                      *)
786 (* ------------------------------------------------------------------------- *)
787
788 let COMPLEX_DIV_1 = prove
789  (`!z. z / Cx(&1) = z`,
790   CONV_TAC COMPLEX_FIELD);;
791
792 let COMPLEX_DIV_LMUL = prove
793  (`!x y. ~(y = Cx(&0)) ==> y * x / y = x`,
794   CONV_TAC COMPLEX_FIELD);;
795
796 let COMPLEX_DIV_RMUL = prove
797  (`!x y. ~(y = Cx(&0)) ==> x / y * y = x`,
798   CONV_TAC COMPLEX_FIELD);;
799
800 let COMPLEX_INV_EQ_0 = prove
801  (`!x. inv x = Cx(&0) <=> x = Cx(&0)`,
802   GEN_TAC THEN ASM_CASES_TAC `x = Cx(&0)` THEN
803   ASM_REWRITE_TAC[COMPLEX_INV_0] THEN POP_ASSUM MP_TAC THEN
804   CONV_TAC COMPLEX_FIELD);;
805
806 let COMPLEX_INV_NEG = prove
807  (`!x:complex. inv(--x) = --(inv x)`,
808   GEN_TAC THEN ASM_CASES_TAC `x = Cx(&0)` THEN
809   ASM_REWRITE_TAC[COMPLEX_INV_0; COMPLEX_NEG_0] THEN
810   POP_ASSUM MP_TAC THEN CONV_TAC COMPLEX_FIELD);;
811
812 let COMPLEX_NEG_INV = prove
813  (`!x:complex. --(inv x) = inv(--x)`,
814   REWRITE_TAC[COMPLEX_INV_NEG]);;
815
816 let COMPLEX_INV_EQ_1 = prove
817  (`!x. inv x = Cx(&1) <=> x = Cx(&1)`,
818   GEN_TAC THEN ASM_CASES_TAC `x = Cx(&0)` THEN
819   ASM_REWRITE_TAC[COMPLEX_INV_0] THEN POP_ASSUM MP_TAC THEN
820   CONV_TAC COMPLEX_FIELD);;
821
822 let COMPLEX_DIV_EQ_0 = prove
823  (`!w z. w / z = Cx(&0) <=> w = Cx(&0) \/ z = Cx(&0)`,
824   REWRITE_TAC[complex_div; COMPLEX_INV_EQ_0; COMPLEX_ENTIRE]);;
825
826 (* ------------------------------------------------------------------------- *)
827 (* Powers.                                                                   *)
828 (* ------------------------------------------------------------------------- *)
829
830 let COMPLEX_POW_ADD = prove
831  (`!x m n. x pow (m + n) = x pow m * x pow n`,
832   GEN_TAC THEN INDUCT_TAC THEN
833   ASM_REWRITE_TAC[ADD_CLAUSES; complex_pow;
834                   COMPLEX_MUL_LID; COMPLEX_MUL_ASSOC]);;
835
836 let COMPLEX_POW_POW = prove
837  (`!x m n. (x pow m) pow n = x pow (m * n)`,
838   GEN_TAC THEN GEN_TAC THEN INDUCT_TAC THEN
839   ASM_REWRITE_TAC[complex_pow; MULT_CLAUSES; COMPLEX_POW_ADD]);;
840
841 let COMPLEX_POW_1 = prove
842  (`!x. x pow 1 = x`,
843   REWRITE_TAC[num_CONV `1`] THEN REWRITE_TAC[complex_pow; COMPLEX_MUL_RID]);;
844
845 let COMPLEX_POW_2 = prove
846  (`!x. x pow 2 = x * x`,
847   REWRITE_TAC[num_CONV `2`] THEN REWRITE_TAC[complex_pow; COMPLEX_POW_1]);;
848
849 let COMPLEX_POW_NEG = prove
850  (`!x n. (--x) pow n = if EVEN n then x pow n else --(x pow n)`,
851   GEN_TAC THEN INDUCT_TAC THEN
852   ASM_REWRITE_TAC[complex_pow; EVEN] THEN
853   ASM_CASES_TAC `EVEN n` THEN
854   ASM_REWRITE_TAC[COMPLEX_MUL_RNEG; COMPLEX_MUL_LNEG; COMPLEX_NEG_NEG]);;
855
856 let COMPLEX_POW_ONE = prove
857  (`!n. Cx(&1) pow n = Cx(&1)`,
858   INDUCT_TAC THEN ASM_REWRITE_TAC[complex_pow; COMPLEX_MUL_LID]);;
859
860 let COMPLEX_POW_MUL = prove
861  (`!x y n. (x * y) pow n = (x pow n) * (y pow n)`,
862   GEN_TAC THEN GEN_TAC THEN INDUCT_TAC THEN
863   ASM_REWRITE_TAC[complex_pow; COMPLEX_MUL_LID; COMPLEX_MUL_AC]);;
864
865 let COMPLEX_POW_DIV = prove
866  (`!x y n. (x / y) pow n = (x pow n) / (y pow n)`,
867   REWRITE_TAC[complex_div; COMPLEX_POW_MUL; COMPLEX_POW_INV]);;
868
869 let COMPLEX_POW_II_2 = prove
870  (`ii pow 2 = --Cx(&1)`,
871   REWRITE_TAC[ii; COMPLEX_POW_2; complex_mul; CX_DEF; RE; IM; complex_neg] THEN
872   CONV_TAC REAL_RAT_REDUCE_CONV);;
873
874 let COMPLEX_POW_EQ_0 = prove
875  (`!x n. (x pow n = Cx(&0)) <=> (x = Cx(&0)) /\ ~(n = 0)`,
876   GEN_TAC THEN INDUCT_TAC THEN
877   ASM_REWRITE_TAC[NOT_SUC; complex_pow; COMPLEX_ENTIRE] THENL
878    [SIMPLE_COMPLEX_ARITH_TAC; CONV_TAC TAUT]);;
879
880 let COMPLEX_POW_ZERO = prove
881  (`!n. Cx(&0) pow n = if n = 0 then Cx(&1) else Cx(&0)`,
882   INDUCT_TAC THEN REWRITE_TAC[complex_pow; COMPLEX_MUL_LZERO; NOT_SUC]);;
883
884 let COMPLEX_INV_II = prove
885  (`inv ii = --ii`,
886   CONV_TAC COMPLEX_FIELD);;
887
888 let COMPLEX_DIV_POW = prove
889  (`!x:complex n k:num.
890       ~(x= Cx(&0)) /\ k <= n /\ ~(k = 0)
891       ==> x pow (n-k) = x pow n / x pow k`,
892   REPEAT STRIP_TAC THEN SUBGOAL_THEN `x:complex pow (n - k) * x pow k =
893   x pow n / x pow k * x pow k` (fun th-> ASM_MESON_TAC
894   [th;COMPLEX_POW_EQ_0;COMPLEX_EQ_MUL_RCANCEL])
895   THEN ASM_SIMP_TAC[GSYM COMPLEX_POW_ADD;SUB_ADD] THEN
896   MP_TAC (MESON [COMPLEX_POW_EQ_0;ASSUME `~(k = 0)`; ASSUME `~(x = Cx(&0))`]
897   `~(x pow k = Cx(&0))`) THEN ASM_SIMP_TAC[COMPLEX_DIV_RMUL]);;
898
899 (* ------------------------------------------------------------------------- *)
900 (* Norms (aka "moduli").                                                     *)
901 (* ------------------------------------------------------------------------- *)
902
903 let COMPLEX_VEC_0 = prove
904  (`vec 0 = Cx(&0)`,
905   SIMP_TAC[CART_EQ; VEC_COMPONENT; CX_DEF; complex;
906            DIMINDEX_2; FORALL_2; VECTOR_2]);;
907
908 let COMPLEX_NORM_ZERO = prove
909  (`!z. (norm z = &0) <=> (z = Cx(&0))`,
910   REWRITE_TAC[NORM_EQ_0; COMPLEX_VEC_0]);;
911
912 let COMPLEX_NORM_NUM = prove
913  (`!n. norm(Cx(&n)) = &n`,
914   REWRITE_TAC[COMPLEX_NORM_CX; REAL_ABS_NUM]);;
915
916 let COMPLEX_NORM_0 = prove
917  (`norm(Cx(&0)) = &0`,
918   MESON_TAC[COMPLEX_NORM_ZERO]);;
919
920 let COMPLEX_NORM_NZ = prove
921  (`!z. &0 < norm(z) <=> ~(z = Cx(&0))`,
922   REWRITE_TAC[NORM_POS_LT; COMPLEX_VEC_0]);;
923
924 let COMPLEX_NORM_MUL = prove
925  (`!w z. norm(w * z) = norm(w) * norm(z)`,
926   REPEAT GEN_TAC THEN REWRITE_TAC[complex_norm; complex_mul; RE; IM] THEN
927   SIMP_TAC[GSYM SQRT_MUL; REAL_POW_2; REAL_LE_ADD; REAL_LE_SQUARE] THEN
928   AP_TERM_TAC THEN REAL_ARITH_TAC);;
929
930 let COMPLEX_NORM_POW = prove
931  (`!z n. norm(z pow n) = norm(z) pow n`,
932   GEN_TAC THEN INDUCT_TAC THEN
933   ASM_REWRITE_TAC[complex_pow; real_pow; COMPLEX_NORM_NUM; COMPLEX_NORM_MUL]);;
934
935 let COMPLEX_NORM_INV = prove
936  (`!z. norm(inv z) = inv(norm z)`,
937   GEN_TAC THEN REWRITE_TAC[complex_norm; complex_inv; RE; IM] THEN
938   REWRITE_TAC[REAL_POW_2; real_div] THEN
939   REWRITE_TAC[REAL_ARITH `(r * d) * r * d + (--i * d) * --i * d =
940                           (r * r + i * i) * d * d:real`] THEN
941   ASM_CASES_TAC `Re z * Re z + Im z * Im z = &0` THENL
942    [ASM_REWRITE_TAC[REAL_INV_0; SQRT_0; REAL_MUL_LZERO]; ALL_TAC] THEN
943   CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_MUL_RINV_UNIQ THEN
944   SIMP_TAC[GSYM SQRT_MUL; REAL_LE_MUL; REAL_LE_INV_EQ; REAL_LE_ADD;
945            REAL_LE_SQUARE] THEN
946   ONCE_REWRITE_TAC[AC REAL_MUL_AC
947    `a * a * b * b:real = (a * b) * (a * b)`] THEN
948   ASM_SIMP_TAC[REAL_MUL_RINV; REAL_MUL_LID; SQRT_1]);;
949
950 let COMPLEX_NORM_DIV = prove
951  (`!w z. norm(w / z) = norm(w) / norm(z)`,
952   REWRITE_TAC[complex_div; real_div; COMPLEX_NORM_INV; COMPLEX_NORM_MUL]);;
953
954 let COMPLEX_NORM_TRIANGLE_SUB = prove
955  (`!w z. norm(w) <= norm(w + z) + norm(z)`,
956   MESON_TAC[NORM_TRIANGLE; NORM_NEG; COMPLEX_ADD_ASSOC;
957             COMPLEX_ADD_RINV; COMPLEX_ADD_RID]);;
958
959 let COMPLEX_NORM_ABS_NORM = prove
960  (`!w z. abs(norm w - norm z) <= norm(w - z)`,
961   REPEAT GEN_TAC THEN
962   MATCH_MP_TAC(REAL_ARITH
963    `a - b <= x /\ b - a <= x ==> abs(a - b) <= x:real`) THEN
964   MESON_TAC[COMPLEX_NEG_SUB; NORM_NEG; REAL_LE_SUB_RADD; complex_sub;
965             COMPLEX_NORM_TRIANGLE_SUB]);;
966
967 let COMPLEX_POW_EQ_1 = prove
968  (`!z n. z pow n = Cx(&1) ==> norm(z) = &1 \/ n = 0`,
969   REPEAT GEN_TAC THEN
970   DISCH_THEN(MP_TAC o AP_TERM `norm:complex->real`) THEN
971   SIMP_TAC[COMPLEX_NORM_POW; COMPLEX_NORM_CX; REAL_POW_EQ_1; REAL_ABS_NUM] THEN
972   SIMP_TAC[REAL_ABS_NORM] THEN CONV_TAC TAUT);;
973
974 (* ------------------------------------------------------------------------- *)
975 (* Complex conjugate.                                                        *)
976 (* ------------------------------------------------------------------------- *)
977
978 let cnj = new_definition
979   `cnj(z) = complex(Re(z),--(Im(z)))`;;
980
981 (* ------------------------------------------------------------------------- *)
982 (* Conjugation is an automorphism.                                           *)
983 (* ------------------------------------------------------------------------- *)
984
985 let CNJ_INJ = prove
986  (`!w z. (cnj(w) = cnj(z)) <=> (w = z)`,
987   REWRITE_TAC[cnj; COMPLEX_EQ; RE; IM; REAL_EQ_NEG2]);;
988
989 let CNJ_CNJ = prove
990  (`!z. cnj(cnj z) = z`,
991   REWRITE_TAC[cnj; COMPLEX_EQ; RE; IM; REAL_NEG_NEG]);;
992
993 let CNJ_CX = prove
994  (`!x. cnj(Cx x) = Cx x`,
995   REWRITE_TAC[cnj; COMPLEX_EQ; CX_DEF; REAL_NEG_0; RE; IM]);;
996
997 let COMPLEX_NORM_CNJ = prove
998  (`!z. norm(cnj z) = norm(z)`,
999   REWRITE_TAC[complex_norm; cnj; REAL_POW_2] THEN
1000   REWRITE_TAC[REAL_MUL_LNEG; REAL_MUL_RNEG; RE; IM; REAL_NEG_NEG]);;
1001
1002 let CNJ_NEG = prove
1003  (`!z. cnj(--z) = --(cnj z)`,
1004   REWRITE_TAC[cnj; complex_neg; COMPLEX_EQ; RE; IM]);;
1005
1006 let CNJ_INV = prove
1007  (`!z. cnj(inv z) = inv(cnj z)`,
1008   REWRITE_TAC[cnj; complex_inv; COMPLEX_EQ; RE; IM] THEN
1009   REWRITE_TAC[real_div; REAL_NEG_NEG; REAL_POW_2;
1010               REAL_MUL_LNEG; REAL_MUL_RNEG]);;
1011
1012 let CNJ_ADD = prove
1013  (`!w z. cnj(w + z) = cnj(w) + cnj(z)`,
1014   REWRITE_TAC[cnj; complex_add; COMPLEX_EQ; RE; IM] THEN
1015   REWRITE_TAC[REAL_NEG_ADD; REAL_MUL_LNEG; REAL_MUL_RNEG; REAL_NEG_NEG]);;
1016
1017 let CNJ_SUB = prove
1018  (`!w z. cnj(w - z) = cnj(w) - cnj(z)`,
1019   REWRITE_TAC[complex_sub; CNJ_ADD; CNJ_NEG]);;
1020
1021 let CNJ_MUL = prove
1022  (`!w z. cnj(w * z) = cnj(w) * cnj(z)`,
1023   REWRITE_TAC[cnj; complex_mul; COMPLEX_EQ; RE; IM] THEN
1024   REWRITE_TAC[REAL_NEG_ADD; REAL_MUL_LNEG; REAL_MUL_RNEG; REAL_NEG_NEG]);;
1025
1026 let CNJ_DIV = prove
1027  (`!w z. cnj(w / z) = cnj(w) / cnj(z)`,
1028   REWRITE_TAC[complex_div; CNJ_MUL; CNJ_INV]);;
1029
1030 let CNJ_POW = prove
1031  (`!z n. cnj(z pow n) = cnj(z) pow n`,
1032   GEN_TAC THEN INDUCT_TAC THEN
1033   ASM_REWRITE_TAC[complex_pow; CNJ_MUL; CNJ_CX]);;
1034
1035 let RE_CNJ = prove
1036  (`!z. Re(cnj z) = Re z`,
1037   REWRITE_TAC[cnj; RE]);;
1038
1039 let IM_CNJ = prove
1040  (`!z. Im(cnj z) = --Im z`,
1041   REWRITE_TAC[cnj; IM]);;
1042
1043 let CNJ_EQ_CX = prove
1044  (`!x z. cnj z = Cx x <=> z = Cx x`,
1045   REWRITE_TAC[COMPLEX_EQ; RE_CNJ; IM_CNJ; RE_CX; IM_CX] THEN
1046   CONV_TAC REAL_RING);;
1047
1048 let CNJ_EQ_0 = prove
1049  (`!z. cnj z = Cx(&0) <=> z = Cx(&0)`,
1050   REWRITE_TAC[CNJ_EQ_CX]);;
1051
1052 let COMPLEX_ADD_CNJ = prove
1053  (`(!z. z + cnj z = Cx(&2 * Re z)) /\ (!z. cnj z + z = Cx(&2 * Re z))`,
1054   REWRITE_TAC[COMPLEX_EQ; RE_CX; IM_CX; RE_ADD; IM_ADD; RE_CNJ; IM_CNJ] THEN
1055   REAL_ARITH_TAC);;
1056
1057 let CNJ_II = prove
1058  (`cnj ii = --ii`,
1059   REWRITE_TAC[cnj; ii; RE; IM; complex_neg; REAL_NEG_0]);;
1060
1061 let CX_RE_CNJ = prove
1062  (`!z. Cx(Re z) = (z + cnj z) / Cx(&2)`,
1063   REWRITE_TAC[COMPLEX_EQ; RE_DIV_CX; IM_DIV_CX; RE_CX; IM_CX] THEN
1064   REWRITE_TAC[RE_ADD; IM_ADD; RE_CNJ; IM_CNJ] THEN REAL_ARITH_TAC);;
1065
1066 let CX_IM_CNJ = prove
1067  (`!z. Cx(Im z) = --ii * (z - cnj z) / Cx(&2)`,
1068   REWRITE_TAC[COMPLEX_EQ; RE_DIV_CX; IM_DIV_CX; RE_CX; IM_CX;
1069               COMPLEX_MUL_LNEG; RE_NEG; IM_NEG; RE_MUL_II; IM_MUL_II] THEN
1070   REWRITE_TAC[RE_SUB; IM_SUB; RE_CNJ; IM_CNJ] THEN REAL_ARITH_TAC);;
1071
1072 let FORALL_CNJ = prove
1073  (`(!z. P(cnj z)) <=> (!z. P z)`,
1074   MESON_TAC[CNJ_CNJ]);;
1075
1076 let EXISTS_CNJ = prove
1077  (`(?z. P(cnj z)) <=> (?z. P z)`,
1078   MESON_TAC[CNJ_CNJ]);;
1079
1080 (* ------------------------------------------------------------------------- *)
1081 (* Slightly ad hoc theorems relating multiplication, inverse and conjugation *)
1082 (* ------------------------------------------------------------------------- *)
1083
1084 let COMPLEX_NORM_POW_2 = prove
1085  (`!z. Cx(norm z) pow 2 = z * cnj z`,
1086   GEN_TAC THEN REWRITE_TAC [GSYM CX_POW; COMPLEX_SQNORM] THEN
1087   REWRITE_TAC [cnj; complex_mul; CX_DEF; RE; IM; COMPLEX_EQ] THEN
1088   CONV_TAC REAL_RING);;
1089
1090 let COMPLEX_MUL_CNJ = prove
1091  (`!z. cnj z * z = Cx(norm(z)) pow 2 /\ z * cnj z = Cx(norm(z)) pow 2`,
1092   GEN_TAC THEN REWRITE_TAC[COMPLEX_MUL_SYM] THEN
1093   REWRITE_TAC[cnj; complex_mul; RE; IM; GSYM CX_POW; COMPLEX_SQNORM] THEN
1094   REWRITE_TAC[CX_DEF] THEN AP_TERM_TAC THEN BINOP_TAC THEN
1095   CONV_TAC REAL_RING);;
1096
1097 let COMPLEX_INV_CNJ = prove
1098  (`!z. inv z = cnj z / Cx(norm z) pow 2`,
1099   GEN_TAC THEN ASM_CASES_TAC `z = Cx(&0)` THENL
1100    [ASM_REWRITE_TAC[CNJ_CX; complex_div; COMPLEX_INV_0; COMPLEX_MUL_LZERO];
1101     MATCH_MP_TAC(COMPLEX_FIELD
1102      `x * y = z /\ ~(x = Cx(&0)) /\ ~(z = Cx(&0)) ==> inv x = y / z`) THEN
1103     ASM_REWRITE_TAC[COMPLEX_MUL_CNJ; GSYM CX_POW; CX_INJ; REAL_POW_EQ_0] THEN
1104     ASM_REWRITE_TAC[COMPLEX_NORM_ZERO; ARITH]]);;
1105
1106 let COMPLEX_DIV_CNJ = prove
1107  (`!a b. a / b = (a * cnj b) / Cx(norm b) pow 2`,
1108   REPEAT GEN_TAC THEN REWRITE_TAC[complex_div; GSYM COMPLEX_MUL_ASSOC] THEN
1109   AP_TERM_TAC THEN GEN_REWRITE_TAC LAND_CONV [COMPLEX_INV_CNJ] THEN
1110   REWRITE_TAC[complex_div]);;
1111
1112 let RE_COMPLEX_DIV_EQ_0 = prove
1113  (`!a b. Re(a / b) = &0 <=> Re(a * cnj b) = &0`,
1114   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[COMPLEX_DIV_CNJ] THEN
1115   REWRITE_TAC[complex_div; GSYM CX_POW; GSYM CX_INV] THEN
1116   REWRITE_TAC[RE_MUL_CX; REAL_INV_EQ_0; REAL_POW_EQ_0; ARITH;
1117               REAL_ENTIRE; COMPLEX_NORM_ZERO] THEN
1118   ASM_CASES_TAC `b = Cx(&0)` THEN ASM_REWRITE_TAC[] THEN
1119   REWRITE_TAC[CNJ_CX; COMPLEX_MUL_RZERO; RE_CX]);;
1120
1121 let IM_COMPLEX_DIV_EQ_0 = prove
1122  (`!a b. Im(a / b) = &0 <=> Im(a * cnj b) = &0`,
1123   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[COMPLEX_DIV_CNJ] THEN
1124   REWRITE_TAC[complex_div; GSYM CX_POW; GSYM CX_INV] THEN
1125   REWRITE_TAC[IM_MUL_CX; REAL_INV_EQ_0; REAL_POW_EQ_0; ARITH;
1126               REAL_ENTIRE; COMPLEX_NORM_ZERO] THEN
1127   ASM_CASES_TAC `b = Cx(&0)` THEN ASM_REWRITE_TAC[] THEN
1128   REWRITE_TAC[CNJ_CX; COMPLEX_MUL_RZERO; IM_CX]);;
1129
1130 let RE_COMPLEX_DIV_GT_0 = prove
1131  (`!a b. &0 < Re(a / b) <=> &0 < Re(a * cnj b)`,
1132   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[COMPLEX_DIV_CNJ] THEN
1133   REWRITE_TAC[complex_div; GSYM CX_POW; GSYM CX_INV] THEN
1134   REWRITE_TAC[RE_MUL_CX; REAL_INV_EQ_0; REAL_POW_EQ_0; ARITH;
1135               REAL_ENTIRE; COMPLEX_NORM_ZERO] THEN
1136   ASM_CASES_TAC `b = Cx(&0)` THEN
1137   ASM_REWRITE_TAC[CNJ_CX; COMPLEX_MUL_RZERO; RE_CX; REAL_MUL_LZERO] THEN
1138   REWRITE_TAC[REAL_ARITH `&0 < a * x <=> &0 * x < a * x`] THEN
1139   ASM_SIMP_TAC[REAL_LT_RMUL_EQ; REAL_LT_INV_EQ; REAL_POW_LT; ARITH;
1140                COMPLEX_NORM_NZ]);;
1141
1142 let IM_COMPLEX_DIV_GT_0 = prove
1143  (`!a b. &0 < Im(a / b) <=> &0 < Im(a * cnj b)`,
1144   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[COMPLEX_DIV_CNJ] THEN
1145   REWRITE_TAC[complex_div; GSYM CX_POW; GSYM CX_INV] THEN
1146   REWRITE_TAC[IM_MUL_CX; REAL_INV_EQ_0; REAL_POW_EQ_0; ARITH;
1147               REAL_ENTIRE; COMPLEX_NORM_ZERO] THEN
1148   ASM_CASES_TAC `b = Cx(&0)` THEN
1149   ASM_REWRITE_TAC[CNJ_CX; COMPLEX_MUL_RZERO; IM_CX; REAL_MUL_LZERO] THEN
1150   REWRITE_TAC[REAL_ARITH `&0 < a * x <=> &0 * x < a * x`] THEN
1151   ASM_SIMP_TAC[REAL_LT_RMUL_EQ; REAL_LT_INV_EQ; REAL_POW_LT; ARITH;
1152                COMPLEX_NORM_NZ]);;
1153
1154 let RE_COMPLEX_DIV_GE_0 = prove
1155  (`!a b. &0 <= Re(a / b) <=> &0 <= Re(a * cnj b)`,
1156   REWRITE_TAC[REAL_ARITH `&0 <= x <=> &0 < x \/ x = &0`] THEN
1157   REWRITE_TAC[RE_COMPLEX_DIV_GT_0; RE_COMPLEX_DIV_EQ_0]);;
1158
1159 let IM_COMPLEX_DIV_GE_0 = prove
1160  (`!a b. &0 <= Im(a / b) <=> &0 <= Im(a * cnj b)`,
1161   REWRITE_TAC[REAL_ARITH `&0 <= x <=> &0 < x \/ x = &0`] THEN
1162   REWRITE_TAC[IM_COMPLEX_DIV_GT_0; IM_COMPLEX_DIV_EQ_0]);;
1163
1164 let RE_COMPLEX_DIV_LE_0 = prove
1165  (`!a b. Re(a / b) <= &0 <=> Re(a * cnj b) <= &0`,
1166   REWRITE_TAC[GSYM REAL_NOT_LT; RE_COMPLEX_DIV_GT_0]);;
1167
1168 let IM_COMPLEX_DIV_LE_0 = prove
1169  (`!a b. Im(a / b) <= &0 <=> Im(a * cnj b) <= &0`,
1170   REWRITE_TAC[GSYM REAL_NOT_LT; IM_COMPLEX_DIV_GT_0]);;
1171
1172 let RE_COMPLEX_DIV_LT_0 = prove
1173  (`!a b. Re(a / b) < &0 <=> Re(a * cnj b) < &0`,
1174   REWRITE_TAC[GSYM REAL_NOT_LE; RE_COMPLEX_DIV_GE_0]);;
1175
1176 let IM_COMPLEX_DIV_LT_0 = prove
1177  (`!a b. Im(a / b) < &0 <=> Im(a * cnj b) < &0`,
1178   REWRITE_TAC[GSYM REAL_NOT_LE; IM_COMPLEX_DIV_GE_0]);;
1179
1180 let IM_COMPLEX_INV_GE_0 = prove
1181  (`!z. &0 <= Im(inv z) <=> Im(z) <= &0`,
1182   GEN_TAC THEN MP_TAC(ISPECL [`Cx(&1)`; `z:complex`] IM_COMPLEX_DIV_GE_0) THEN
1183   REWRITE_TAC[complex_div; COMPLEX_MUL_LID; IM_CNJ] THEN REAL_ARITH_TAC);;
1184
1185 let IM_COMPLEX_INV_LE_0 = prove
1186  (`!z. Im(inv z) <= &0 <=> &0 <= Im(z)`,
1187   MESON_TAC[IM_COMPLEX_INV_GE_0; COMPLEX_INV_INV]);;
1188
1189 let IM_COMPLEX_INV_GT_0 = prove
1190  (`!z. &0 < Im(inv z) <=> Im(z) < &0`,
1191   REWRITE_TAC[REAL_ARITH `&0 < a <=> ~(a <= &0)`; IM_COMPLEX_INV_LE_0] THEN
1192   REAL_ARITH_TAC);;
1193
1194 let IM_COMPLEX_INV_LT_0 = prove
1195  (`!z. Im(inv z) < &0 <=> &0 < Im(z)`,
1196   REWRITE_TAC[REAL_ARITH `a < &0 <=> ~(&0 <= a)`; IM_COMPLEX_INV_GE_0] THEN
1197   REAL_ARITH_TAC);;
1198
1199 let IM_COMPLEX_INV_EQ_0 = prove
1200  (`!z. Im(inv z) = &0 <=> Im(z) = &0`,
1201   SIMP_TAC[GSYM REAL_LE_ANTISYM; IM_COMPLEX_INV_LE_0; IM_COMPLEX_INV_GE_0] THEN
1202   REAL_ARITH_TAC);;
1203
1204 let REAL_SGN_RE_COMPLEX_DIV = prove
1205  (`!w z. real_sgn(Re(w / z)) = real_sgn(Re(w * cnj z))`,
1206   REWRITE_TAC[real_sgn; RE_COMPLEX_DIV_GT_0; RE_COMPLEX_DIV_GE_0;
1207               REAL_ARITH `x < &0 <=> ~(&0 <= x)`]);;
1208
1209 let REAL_SGN_IM_COMPLEX_DIV = prove
1210  (`!w z. real_sgn(Im(w / z)) = real_sgn(Im(w * cnj z))`,
1211   REWRITE_TAC[real_sgn; IM_COMPLEX_DIV_GT_0; IM_COMPLEX_DIV_GE_0;
1212               REAL_ARITH `x < &0 <=> ~(&0 <= x)`]);;
1213
1214 (* ------------------------------------------------------------------------- *)
1215 (* Norm versus components for complex numbers.                               *)
1216 (* ------------------------------------------------------------------------- *)
1217
1218 let COMPLEX_NORM_GE_RE_IM = prove
1219  (`!z. abs(Re(z)) <= norm(z) /\ abs(Im(z)) <= norm(z)`,
1220   GEN_TAC THEN ONCE_REWRITE_TAC[GSYM POW_2_SQRT_ABS] THEN
1221   REWRITE_TAC[complex_norm] THEN
1222   CONJ_TAC THEN
1223   MATCH_MP_TAC SQRT_MONO_LE THEN
1224   ASM_SIMP_TAC[REAL_LE_ADDR; REAL_LE_ADDL; REAL_POW_2; REAL_LE_SQUARE]);;
1225
1226 let COMPLEX_NORM_LE_RE_IM = prove
1227  (`!z. norm(z) <= abs(Re z) + abs(Im z)`,
1228   GEN_TAC THEN MP_TAC(ISPEC `z:complex` NORM_LE_L1) THEN
1229   REWRITE_TAC[DIMINDEX_2; SUM_2; RE_DEF; IM_DEF]);;
1230
1231 let COMPLEX_L1_LE_NORM = prove
1232  (`!z. sqrt(&2) / &2 * (abs(Re z) + abs(Im z)) <= norm z`,
1233   GEN_TAC THEN MATCH_MP_TAC REAL_LE_LCANCEL_IMP THEN EXISTS_TAC `sqrt(&2)` THEN
1234   SIMP_TAC[REAL_ARITH `x * x / &2 * y = (x pow 2) / &2 * y`;
1235            SQRT_POW_2; REAL_POS; SQRT_POS_LT; REAL_OF_NUM_LT; ARITH] THEN
1236   MP_TAC(ISPEC `z:complex` L1_LE_NORM) THEN
1237   REWRITE_TAC[DIMINDEX_2; SUM_2; RE_DEF; IM_DEF] THEN REAL_ARITH_TAC);;
1238
1239 (* ------------------------------------------------------------------------- *)
1240 (* Complex square roots.                                                     *)
1241 (* ------------------------------------------------------------------------- *)
1242
1243 let csqrt = new_definition
1244   `csqrt(z) = if Im(z) = &0 then
1245                 if &0 <= Re(z) then complex(sqrt(Re(z)),&0)
1246                 else complex(&0,sqrt(--Re(z)))
1247               else complex(sqrt((norm(z) + Re(z)) / &2),
1248                            (Im(z) / abs(Im(z))) *
1249                            sqrt((norm(z) - Re(z)) / &2))`;;
1250
1251
1252 let CSQRT = prove
1253  (`!z. csqrt(z) pow 2 = z`,
1254   GEN_TAC THEN REWRITE_TAC[COMPLEX_POW_2; csqrt] THEN COND_CASES_TAC THENL
1255    [COND_CASES_TAC THEN
1256     ASM_REWRITE_TAC[CX_DEF; complex_mul; RE; IM; REAL_MUL_RZERO; REAL_MUL_LZERO;
1257       REAL_SUB_LZERO; REAL_SUB_RZERO; REAL_ADD_LID; COMPLEX_EQ] THEN
1258     REWRITE_TAC[REAL_NEG_EQ; GSYM REAL_POW_2] THEN
1259     ASM_SIMP_TAC[SQRT_POW_2; REAL_ARITH `~(&0 <= x) ==> &0 <= --x`];
1260     ALL_TAC] THEN
1261   REWRITE_TAC[complex_mul; RE; IM] THEN
1262   ONCE_REWRITE_TAC[REAL_ARITH
1263    `(s * s - (i * s') * (i * s') = s * s - (i * i) * (s' * s')) /\
1264     (s * i * s' + (i * s')* s = &2 * i * s * s')`] THEN
1265   REWRITE_TAC[GSYM REAL_POW_2] THEN
1266   SUBGOAL_THEN `&0 <= norm(z) + Re(z) /\ &0 <= norm(z) - Re(z)`
1267   STRIP_ASSUME_TAC THENL
1268    [MP_TAC(SPEC `z:complex` COMPLEX_NORM_GE_RE_IM) THEN REAL_ARITH_TAC;
1269     ALL_TAC] THEN
1270   ASM_SIMP_TAC[REAL_LE_DIV; REAL_POS; GSYM SQRT_MUL; SQRT_POW_2] THEN
1271   REWRITE_TAC[COMPLEX_EQ; RE; IM] THEN CONJ_TAC THENL
1272    [ASM_SIMP_TAC[REAL_POW_DIV; REAL_POW2_ABS;
1273                  REAL_POW_EQ_0; REAL_DIV_REFL] THEN
1274     REWRITE_TAC[real_div; REAL_MUL_LID; GSYM REAL_SUB_RDISTRIB] THEN
1275     REWRITE_TAC[REAL_ARITH `(m + r) - (m - r) = r * &2`] THEN
1276     REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
1277     REWRITE_TAC[REAL_MUL_RID]; ALL_TAC] THEN
1278   REWRITE_TAC[real_div] THEN
1279   ONCE_REWRITE_TAC[AC REAL_MUL_AC
1280     `(a * b) * a' * b = (a * a') * (b * b:real)`] THEN
1281   REWRITE_TAC[REAL_DIFFSQ] THEN
1282   REWRITE_TAC[complex_norm; GSYM REAL_POW_2] THEN
1283   SIMP_TAC[SQRT_POW_2; REAL_LE_ADD;
1284            REWRITE_RULE[GSYM REAL_POW_2] REAL_LE_SQUARE] THEN
1285   REWRITE_TAC[REAL_ADD_SUB; GSYM REAL_POW_MUL] THEN
1286   REWRITE_TAC[POW_2_SQRT_ABS] THEN
1287   REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_INV; REAL_ABS_NUM] THEN
1288   ONCE_REWRITE_TAC[AC REAL_MUL_AC
1289     `&2 * (i * a') * a * h = i * (&2 * h) * a * a'`] THEN
1290   CONV_TAC REAL_RAT_REDUCE_CONV THEN
1291   REWRITE_TAC[REAL_MUL_LID; GSYM real_div] THEN
1292   ASM_SIMP_TAC[REAL_DIV_REFL; REAL_ABS_ZERO; REAL_MUL_RID]);;
1293
1294 let CX_SQRT = prove
1295  (`!x. &0 <= x ==> Cx(sqrt x) = csqrt(Cx x)`,
1296   SIMP_TAC[csqrt; IM_CX; RE_CX; COMPLEX_EQ; RE; IM]);;
1297
1298 let CSQRT_CX = prove
1299  (`!x. &0 <= x ==> csqrt(Cx x) = Cx(sqrt x)`,
1300   SIMP_TAC[CX_SQRT]);;
1301
1302 let CSQRT_0 = prove
1303  (`csqrt(Cx(&0)) = Cx(&0)`,
1304   SIMP_TAC[CSQRT_CX; REAL_POS; SQRT_0]);;
1305
1306 let CSQRT_1 = prove
1307  (`csqrt(Cx(&1)) = Cx(&1)`,
1308   SIMP_TAC[CSQRT_CX; REAL_POS; SQRT_1]);;
1309
1310 let CSQRT_PRINCIPAL = prove
1311  (`!z. &0 < Re(csqrt(z)) \/ Re(csqrt(z)) = &0 /\ &0 <= Im(csqrt(z))`,
1312   GEN_TAC THEN REWRITE_TAC[csqrt] THEN
1313   REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[RE; IM]) THENL
1314    [FIRST_ASSUM(MP_TAC o MATCH_MP SQRT_POS_LE) THEN REAL_ARITH_TAC;
1315     DISJ2_TAC THEN REWRITE_TAC[real_ge] THEN MATCH_MP_TAC SQRT_POS_LE THEN
1316     ASM_REAL_ARITH_TAC;
1317     DISJ1_TAC THEN MATCH_MP_TAC SQRT_POS_LT THEN
1318     MATCH_MP_TAC(REAL_ARITH `abs(y) < x ==> &0 < (x + y) / &2`) THEN
1319     REWRITE_TAC[complex_norm] THEN REWRITE_TAC[GSYM POW_2_SQRT_ABS] THEN
1320     MATCH_MP_TAC SQRT_MONO_LT THEN
1321     REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE; REAL_LT_ADDR] THEN
1322     REWRITE_TAC[REAL_ARITH `&0 < x <=> &0 <= x /\ ~(x = &0)`] THEN
1323     ASM_REWRITE_TAC[REAL_LE_SQUARE; REAL_ENTIRE]]);;
1324
1325 let RE_CSQRT = prove
1326  (`!z. &0 <= Re(csqrt z)`,
1327   MP_TAC CSQRT_PRINCIPAL THEN MATCH_MP_TAC MONO_FORALL THEN REAL_ARITH_TAC);;
1328
1329 let CSQRT_UNIQUE = prove
1330  (`!s z. s pow 2 = z /\ (&0 < Re s \/ Re s = &0 /\ &0 <= Im s)
1331          ==> csqrt z = s`,
1332   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
1333   FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
1334   MP_TAC(SPEC `(s:complex) pow 2` CSQRT) THEN
1335   SIMP_TAC[COMPLEX_RING `a pow 2 = b pow 2 <=> a = b \/ a = --b:complex`] THEN
1336   STRIP_TAC THEN ASM_REWRITE_TAC[COMPLEX_RING `--z = z <=> z = Cx(&0)`] THEN
1337   FIRST_ASSUM(MP_TAC o AP_TERM `Re`) THEN
1338   FIRST_X_ASSUM(MP_TAC o AP_TERM `Im`) THEN
1339   REWRITE_TAC[RE_NEG; IM_NEG; COMPLEX_EQ; RE_CX; IM_CX] THEN
1340   MP_TAC(SPEC `(s:complex) pow 2` CSQRT_PRINCIPAL) THEN
1341   POP_ASSUM MP_TAC THEN REAL_ARITH_TAC);;
1342
1343 let POW_2_CSQRT = prove
1344  (`!z. &0 < Re z \/ Re(z) = &0 /\ &0 <= Im(z) ==> csqrt(z pow 2) = z`,
1345   MESON_TAC[CSQRT_UNIQUE]);;
1346
1347 let CSQRT_EQ_0 = prove
1348  (`!z. csqrt z = Cx(&0) <=> z = Cx(&0)`,
1349   GEN_TAC THEN MP_TAC (SPEC `z:complex` CSQRT) THEN CONV_TAC COMPLEX_RING);;
1350
1351 (* ------------------------------------------------------------------------- *)
1352 (* A few more complex-specific cases of vector notions.                      *)
1353 (* ------------------------------------------------------------------------- *)
1354
1355 let COMPLEX_CMUL = prove
1356  (`!c x. c % x = Cx(c) * x`,
1357   SIMP_TAC[CART_EQ; VECTOR_MUL_COMPONENT; CX_DEF; complex;
1358            complex_mul; DIMINDEX_2; FORALL_2; IM_DEF; RE_DEF; VECTOR_2] THEN
1359   REAL_ARITH_TAC);;
1360
1361 let LINEAR_COMPLEX_MUL = prove
1362  (`!c. linear (\x. c * x)`,
1363    REWRITE_TAC[linear; COMPLEX_CMUL] THEN CONV_TAC COMPLEX_RING);;
1364
1365 let BILINEAR_COMPLEX_MUL = prove
1366  (`bilinear( * )`,
1367   REWRITE_TAC[bilinear; linear; COMPLEX_CMUL] THEN  CONV_TAC COMPLEX_RING);;
1368
1369 let LINEAR_CNJ = prove
1370  (`linear cnj`,
1371   REWRITE_TAC[linear; COMPLEX_CMUL; CNJ_ADD; CNJ_MUL; CNJ_CX]);;
1372
1373 (* ------------------------------------------------------------------------- *)
1374 (* Complex-specific theorems about sums.                                     *)
1375 (* ------------------------------------------------------------------------- *)
1376
1377 let RE_VSUM = prove
1378  (`!f s. FINITE s ==> Re(vsum s f) = sum s (\x. Re(f x))`,
1379   SIMP_TAC[RE_DEF; VSUM_COMPONENT; DIMINDEX_2; ARITH]);;
1380
1381 let IM_VSUM = prove
1382  (`!f s. FINITE s ==> Im(vsum s f) = sum s (\x. Im(f x))`,
1383   SIMP_TAC[IM_DEF; VSUM_COMPONENT; DIMINDEX_2; ARITH]);;
1384
1385 let VSUM_COMPLEX_LMUL = prove
1386  (`!c f s. FINITE(s) ==> vsum s (\x. c * f x) = c * vsum s f`,
1387   GEN_TAC THEN GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1388   SIMP_TAC[VSUM_CLAUSES; COMPLEX_VEC_0; COMPLEX_MUL_RZERO] THEN
1389   SIMPLE_COMPLEX_ARITH_TAC);;
1390
1391 let VSUM_COMPLEX_RMUL = prove
1392  (`!c f s. FINITE(s) ==> vsum s (\x. f x * c) = vsum s f * c`,
1393   ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN REWRITE_TAC[VSUM_COMPLEX_LMUL]);;
1394
1395 let VSUM_CX = prove
1396  (`!f:A->real s. FINITE s ==> vsum s (\a. Cx(f a)) = Cx(sum s f)`,
1397   GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1398   SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; COMPLEX_VEC_0; CX_ADD]);;
1399
1400 let CNJ_VSUM = prove
1401  (`!f s. FINITE s ==> cnj(vsum s f) = vsum s (\x. cnj(f x))`,
1402   GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1403   SIMP_TAC[VSUM_CLAUSES; CNJ_ADD; CNJ_CX; COMPLEX_VEC_0]);;
1404
1405 let VSUM_CX_NUMSEG = prove
1406  (`!f m n. vsum (m..n) (\a. Cx(f a)) = Cx(sum (m..n) f)`,
1407   SIMP_TAC[VSUM_CX; FINITE_NUMSEG]);;
1408
1409 let COMPLEX_SUB_POW = prove
1410  (`!x y n.
1411         1 <= n ==> x pow n - y pow n =
1412                    (x - y) * vsum(0..n-1) (\i. x pow i * y pow (n - 1 - i))`,
1413   SIMP_TAC[GSYM VSUM_COMPLEX_LMUL; FINITE_NUMSEG] THEN
1414   REWRITE_TAC[COMPLEX_RING
1415    `(x - y) * (a * b):complex = (x * a) * b - a * (y * b)`] THEN
1416   SIMP_TAC[GSYM complex_pow; ADD1; ARITH_RULE
1417     `1 <= n /\ x <= n - 1
1418      ==> n - 1 - x = n - (x + 1) /\ SUC(n - 1 - x) = n - x`] THEN
1419   REWRITE_TAC[VSUM_DIFFS_ALT; LE_0] THEN
1420   SIMP_TAC[SUB_0; SUB_ADD; SUB_REFL;
1421            complex_pow; COMPLEX_MUL_LID; COMPLEX_MUL_RID]);;
1422
1423 let COMPLEX_SUB_POW_R1 = prove
1424  (`!x n. 1 <= n
1425          ==> x pow n - Cx(&1) = (x - Cx(&1)) * vsum(0..n-1) (\i. x pow i)`,
1426   REPEAT GEN_TAC THEN
1427   DISCH_THEN(MP_TAC o SPECL [`x:complex`; `Cx(&1)`] o
1428     MATCH_MP COMPLEX_SUB_POW) THEN
1429   REWRITE_TAC[COMPLEX_POW_ONE; COMPLEX_MUL_RID]);;
1430
1431 let COMPLEX_SUB_POW_L1 = prove
1432  (`!x n. 1 <= n
1433          ==> Cx(&1) - x pow n = (Cx(&1) - x) * vsum(0..n-1) (\i. x pow i)`,
1434   ONCE_REWRITE_TAC[GSYM COMPLEX_NEG_SUB] THEN
1435   SIMP_TAC[COMPLEX_SUB_POW_R1] THEN REWRITE_TAC[COMPLEX_MUL_LNEG]);;
1436
1437 (* ------------------------------------------------------------------------- *)
1438 (* The complex numbers that are real (zero imaginary part).                  *)
1439 (* ------------------------------------------------------------------------- *)
1440
1441 let real = new_definition
1442  `real z <=> Im z = &0`;;
1443
1444 let REAL = prove
1445  (`!z. real z <=> Cx(Re z) = z`,
1446   REWRITE_TAC[COMPLEX_EQ; real; CX_DEF; RE; IM] THEN REAL_ARITH_TAC);;
1447
1448 let REAL_CNJ = prove
1449  (`!z. real z <=> cnj z = z`,
1450   REWRITE_TAC[real; cnj; COMPLEX_EQ; RE; IM] THEN REAL_ARITH_TAC);;
1451
1452 let REAL_IMP_CNJ = prove
1453  (`!z. real z ==> cnj z = z`,
1454   REWRITE_TAC[REAL_CNJ]);;
1455
1456 let REAL_EXISTS = prove
1457  (`!z. real z <=> ?x. z = Cx x`,
1458   MESON_TAC[REAL; real; IM_CX]);;
1459
1460 let FORALL_REAL = prove
1461  (`(!z. real z ==> P z) <=> (!x. P(Cx x))`,
1462   MESON_TAC[REAL_EXISTS]);;
1463
1464 let EXISTS_REAL = prove
1465  (`(?z. real z /\ P z) <=> (?x. P(Cx x))`,
1466   MESON_TAC[REAL_EXISTS]);;
1467
1468 let REAL_CX = prove
1469  (`!x. real(Cx x)`,
1470   REWRITE_TAC[REAL_CNJ; CNJ_CX]);;
1471
1472 let REAL_MUL_CX = prove
1473  (`!x z. real(Cx x * z) <=> x = &0 \/ real z`,
1474   REWRITE_TAC[real; IM_MUL_CX; REAL_ENTIRE]);;
1475
1476 let REAL_ADD = prove
1477  (`!w z. real w /\ real z ==> real(w + z)`,
1478   SIMP_TAC[REAL_CNJ; CNJ_ADD]);;
1479
1480 let REAL_NEG = prove
1481  (`!z. real z ==> real(--z)`,
1482   SIMP_TAC[REAL_CNJ; CNJ_NEG]);;
1483
1484 let REAL_SUB = prove
1485  (`!w z. real w /\ real z ==> real(w - z)`,
1486   SIMP_TAC[REAL_CNJ; CNJ_SUB]);;
1487
1488 let REAL_MUL = prove
1489  (`!w z. real w /\ real z ==> real(w * z)`,
1490   SIMP_TAC[REAL_CNJ; CNJ_MUL]);;
1491
1492 let REAL_POW = prove
1493  (`!z n. real z ==> real(z pow n)`,
1494   SIMP_TAC[REAL_CNJ; CNJ_POW]);;
1495
1496 let REAL_INV = prove
1497  (`!z. real z ==> real(inv z)`,
1498   SIMP_TAC[REAL_CNJ; CNJ_INV]);;
1499
1500 let REAL_INV_EQ = prove
1501  (`!z. real(inv z) = real z`,
1502   MESON_TAC[REAL_INV; COMPLEX_INV_INV]);;
1503
1504 let REAL_DIV = prove
1505  (`!w z. real w /\ real z ==> real(w / z)`,
1506   SIMP_TAC[REAL_CNJ; CNJ_DIV]);;
1507
1508 let REAL_VSUM = prove
1509  (`!f s. FINITE s /\ (!a. a IN s ==> real(f a)) ==> real(vsum s f)`,
1510   SIMP_TAC[CNJ_VSUM; REAL_CNJ]);;
1511
1512 let REAL_SEGMENT = prove
1513  (`!a b x. x IN segment[a,b] /\ real a /\ real b ==> real x`,
1514   SIMP_TAC[segment; IN_ELIM_THM; real; COMPLEX_EQ; LEFT_AND_EXISTS_THM;
1515            LEFT_IMP_EXISTS_THM; IM_ADD; IM_CMUL] THEN
1516   REAL_ARITH_TAC);;
1517
1518 let IN_SEGMENT_CX = prove
1519  (`!a b x. Cx(x) IN segment[Cx(a),Cx(b)] <=>
1520                 a <= x /\ x <= b \/ b <= x /\ x <= a`,
1521   REPEAT STRIP_TAC THEN REWRITE_TAC[segment; IN_ELIM_THM] THEN
1522   REWRITE_TAC[COMPLEX_CMUL; GSYM CX_ADD; CX_INJ; GSYM CX_MUL] THEN
1523   ASM_CASES_TAC `a:real = b` THENL
1524    [ASM_REWRITE_TAC[REAL_ARITH `(&1 - u) * b + u * b = b`] THEN
1525     ASM_CASES_TAC `x:real = b` THEN ASM_REWRITE_TAC[REAL_LE_ANTISYM] THEN
1526     EXISTS_TAC `&0` THEN REWRITE_TAC[REAL_POS];
1527     ALL_TAC] THEN
1528   EQ_TAC THENL
1529    [DISCH_THEN(X_CHOOSE_THEN `u:real`
1530      (CONJUNCTS_THEN2 STRIP_ASSUME_TAC SUBST1_TAC)) THEN
1531     REWRITE_TAC[REAL_ARITH `a <= (&1 - u) * a + u * b <=> &0 <= u * (b - a)`;
1532       REAL_ARITH `b <= (&1 - u) * a + u * b <=> &0 <= (&1 - u) * (a - b)`;
1533       REAL_ARITH `(&1 - u) * a + u * b <= a <=> &0 <= u * (a - b)`;
1534       REAL_ARITH `(&1 - u) * a + u * b <= b <=> &0 <= (&1 - u) * (b - a)`] THEN
1535     DISJ_CASES_TAC(REAL_ARITH `a <= b \/ b <= a`) THENL
1536      [DISJ1_TAC; DISJ2_TAC] THEN
1537     CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN
1538     ASM_REAL_ARITH_TAC;
1539     ALL_TAC] THEN
1540   STRIP_TAC THENL
1541    [SUBGOAL_THEN `&0 < b - a` ASSUME_TAC THENL
1542      [ASM_REAL_ARITH_TAC;
1543       EXISTS_TAC `(x - a:real) / (b - a)`];
1544     SUBGOAL_THEN `&0 < a - b` ASSUME_TAC THENL
1545      [ASM_REAL_ARITH_TAC;
1546       EXISTS_TAC `(a - x:real) / (a - b)`]] THEN
1547   (CONJ_TAC THENL
1548     [ALL_TAC; UNDISCH_TAC `~(a:real = b)` THEN CONV_TAC REAL_FIELD]) THEN
1549   ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ] THEN
1550   ASM_REAL_ARITH_TAC);;
1551
1552 let IN_SEGMENT_CX_GEN = prove
1553  (`!a b x.
1554         x IN segment[Cx a,Cx b] <=>
1555         Im(x) = &0 /\ (a <= Re x /\ Re x <= b \/ b <= Re x /\ Re x <= a)`,
1556   REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM real] THEN
1557   ASM_CASES_TAC `real x` THENL
1558    [FIRST_X_ASSUM(SUBST1_TAC o SYM o REWRITE_RULE[REAL]) THEN
1559     REWRITE_TAC[IN_SEGMENT_CX; REAL_CX; RE_CX] THEN REAL_ARITH_TAC;
1560     ASM_MESON_TAC[REAL_SEGMENT; REAL_CX]]);;
1561
1562 let RE_POS_SEGMENT = prove
1563  (`!a b x. x IN segment[a,b] /\ &0 < Re a /\ &0 < Re b ==> &0 < Re x`,
1564   SIMP_TAC[segment; IN_ELIM_THM; real; COMPLEX_EQ; LEFT_AND_EXISTS_THM;
1565            LEFT_IMP_EXISTS_THM; RE_ADD; RE_CMUL] THEN
1566   REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH
1567     `&0 <= x /\ &0 <= y /\ ~(x = &0 /\ y = &0) ==> &0 < x + y`) THEN
1568   ASM_SIMP_TAC[REAL_LE_MUL; REAL_SUB_LE; REAL_LT_IMP_LE; REAL_ENTIRE] THEN
1569   ASM_REAL_ARITH_TAC);;
1570
1571 let CONVEX_REAL = prove
1572  (`convex real`,
1573   REWRITE_TAC[convex; IN; COMPLEX_CMUL] THEN
1574   SIMP_TAC[REAL_ADD; REAL_MUL; REAL_CX]);;
1575
1576 let IMAGE_CX = prove
1577  (`!s. IMAGE Cx s = {z | real z /\ Re(z) IN s}`,
1578   REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE] THEN MESON_TAC[RE_CX; REAL]);;
1579
1580 (* ------------------------------------------------------------------------- *)
1581 (* Useful bound-type theorems for real quantities.                           *)
1582 (* ------------------------------------------------------------------------- *)
1583
1584 let REAL_NORM = prove
1585  (`!z. real z ==> norm(z) = abs(Re z)`,
1586   SIMP_TAC[real; complex_norm] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
1587   REWRITE_TAC[POW_2_SQRT_ABS; REAL_ADD_RID]);;
1588
1589 let REAL_NORM_POS = prove
1590  (`!z. real z /\ &0 <= Re z ==> norm(z) = Re(z)`,
1591   SIMP_TAC[REAL_NORM] THEN REAL_ARITH_TAC);;
1592
1593 let COMPLEX_NORM_VSUM_SUM_RE = prove
1594  (`!f s. FINITE s /\ (!x. x IN s ==> real(f x) /\ &0 <= Re(f x))
1595          ==> norm(vsum s f) = sum s (\x. Re(f x))`,
1596   SIMP_TAC[GSYM RE_VSUM] THEN REPEAT STRIP_TAC THEN
1597   MATCH_MP_TAC REAL_NORM_POS THEN
1598   ASM_SIMP_TAC[REAL_VSUM; RE_VSUM; SUM_POS_LE]);;
1599
1600 let COMPLEX_NORM_VSUM_BOUND = prove
1601  (`!s f:A->complex g:A->complex.
1602         FINITE s /\ (!x. x IN s ==> real(g x) /\ norm(f x) <= Re(g x))
1603         ==> norm(vsum s f) <= norm(vsum s g)`,
1604   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
1605   EXISTS_TAC `sum s (\x. norm((f:A->complex) x))` THEN
1606   ASM_SIMP_TAC[VSUM_NORM] THEN
1607   MATCH_MP_TAC REAL_LE_TRANS THEN
1608   EXISTS_TAC `sum s (\x. Re((g:A->complex) x))` THEN
1609   ASM_SIMP_TAC[SUM_LE] THEN
1610   MATCH_MP_TAC(REAL_ARITH `x:real = y ==> y <= x`) THEN
1611   MATCH_MP_TAC COMPLEX_NORM_VSUM_SUM_RE THEN
1612   ASM_MESON_TAC[REAL_LE_TRANS; NORM_POS_LE]);;
1613
1614 let COMPLEX_NORM_VSUM_BOUND_SUBSET = prove
1615  (`!f:A->complex g:A->complex s t.
1616         FINITE s /\ t SUBSET s /\
1617         (!x. x IN s ==> real(g x) /\ norm(f x) <= Re(g x))
1618         ==> norm(vsum t f) <= norm(vsum s g)`,
1619   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
1620   EXISTS_TAC `norm(vsum t (g:A->complex))` THEN CONJ_TAC THENL
1621    [ASM_MESON_TAC[COMPLEX_NORM_VSUM_BOUND; SUBSET; FINITE_SUBSET];ALL_TAC] THEN
1622   SUBGOAL_THEN
1623    `norm(vsum t (g:A->complex)) = sum t (\x. Re(g x)) /\
1624     norm(vsum s g) = sum s (\x. Re(g x))`
1625    (CONJUNCTS_THEN SUBST1_TAC)
1626   THENL
1627    [CONJ_TAC THEN MATCH_MP_TAC COMPLEX_NORM_VSUM_SUM_RE;
1628     MATCH_MP_TAC SUM_SUBSET THEN REWRITE_TAC[IN_DIFF]] THEN
1629   ASM_MESON_TAC[REAL_LE_TRANS; NORM_POS_LE; FINITE_SUBSET; SUBSET]);;
1630
1631 (* ------------------------------------------------------------------------- *)
1632 (* Geometric progression.                                                    *)
1633 (* ------------------------------------------------------------------------- *)
1634
1635 let VSUM_GP_BASIC = prove
1636  (`!x n. (Cx(&1) - x) * vsum(0..n) (\i. x pow i) = Cx(&1) - x pow (SUC n)`,
1637   GEN_TAC THEN INDUCT_TAC THEN REWRITE_TAC[VSUM_CLAUSES_NUMSEG] THEN
1638   REWRITE_TAC[complex_pow; COMPLEX_MUL_RID; LE_0] THEN
1639   ASM_REWRITE_TAC[COMPLEX_ADD_LDISTRIB; complex_pow] THEN
1640   SIMPLE_COMPLEX_ARITH_TAC);;
1641
1642 let VSUM_GP_MULTIPLIED = prove
1643  (`!x m n. m <= n
1644            ==> ((Cx(&1) - x) * vsum(m..n) (\i. x pow i) =
1645                 x pow m - x pow (SUC n))`,
1646   REPEAT STRIP_TAC THEN
1647   ASM_SIMP_TAC[VSUM_OFFSET_0; COMPLEX_POW_ADD; FINITE_NUMSEG;
1648                COMPLEX_MUL_ASSOC; VSUM_GP_BASIC; VSUM_COMPLEX_RMUL] THEN
1649   REWRITE_TAC[COMPLEX_SUB_RDISTRIB; GSYM COMPLEX_POW_ADD; COMPLEX_MUL_LID] THEN
1650   ASM_SIMP_TAC[ARITH_RULE `m <= n ==> (SUC(n - m) + m = SUC n)`]);;
1651
1652 let VSUM_GP = prove
1653  (`!x m n.
1654         vsum(m..n) (\i. x pow i) =
1655                 if n < m then Cx(&0)
1656                 else if x = Cx(&1) then Cx(&((n + 1) - m))
1657                 else (x pow m - x pow (SUC n)) / (Cx(&1) - x)`,
1658   REPEAT GEN_TAC THEN
1659   DISJ_CASES_TAC(ARITH_RULE `n < m \/ ~(n < m) /\ m <= n:num`) THEN
1660   ASM_SIMP_TAC[VSUM_TRIV_NUMSEG; COMPLEX_VEC_0] THEN COND_CASES_TAC THENL
1661    [ASM_REWRITE_TAC[COMPLEX_POW_ONE; VSUM_CONST_NUMSEG; COMPLEX_MUL_RID];
1662     ALL_TAC] THEN
1663   REWRITE_TAC[COMPLEX_CMUL; COMPLEX_MUL_RID] THEN
1664   MATCH_MP_TAC(COMPLEX_FIELD
1665    `~(z = Cx(&1)) /\ (Cx(&1) - z) * x = y ==> x = y / (Cx(&1) - z)`) THEN
1666   ASM_SIMP_TAC[COMPLEX_DIV_LMUL; COMPLEX_SUB_0; VSUM_GP_MULTIPLIED]);;
1667
1668 let VSUM_GP_OFFSET = prove
1669  (`!x m n. vsum(m..m+n) (\i. x pow i) =
1670                 if x = Cx(&1) then Cx(&n) + Cx(&1)
1671                 else x pow m * (Cx(&1) - x pow (SUC n)) / (Cx(&1) - x)`,
1672   REPEAT GEN_TAC THEN REWRITE_TAC[VSUM_GP; ARITH_RULE `~(m + n < m:num)`] THEN
1673   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
1674    [REWRITE_TAC[REAL_OF_NUM_ADD; GSYM CX_ADD] THEN
1675     AP_TERM_TAC THEN AP_TERM_TAC THEN ARITH_TAC;
1676     REWRITE_TAC[complex_div; complex_pow; COMPLEX_POW_ADD] THEN
1677     SIMPLE_COMPLEX_ARITH_TAC]);;
1678
1679 (* ------------------------------------------------------------------------- *)
1680 (* Basics about polynomial functions: extremal behaviour and root counts.    *)
1681 (* ------------------------------------------------------------------------- *)
1682
1683 let COMPLEX_SUB_POLYFUN = prove
1684  (`!a x y n.
1685    1 <= n
1686    ==> vsum(0..n) (\i. a i * x pow i) - vsum(0..n) (\i. a i * y pow i) =
1687        (x - y) *
1688        vsum(0..n-1) (\j. vsum(j+1..n) (\i. a i * y pow (i - j - 1)) * x pow j)`,
1689   REPEAT STRIP_TAC THEN
1690   REWRITE_TAC[GSYM VSUM_SUB_NUMSEG; GSYM COMPLEX_SUB_LDISTRIB] THEN
1691   GEN_REWRITE_TAC LAND_CONV [MATCH_MP VSUM_CLAUSES_LEFT (SPEC_ALL LE_0)] THEN
1692   REWRITE_TAC[COMPLEX_SUB_REFL; complex_pow; COMPLEX_MUL_RZERO;
1693       COMPLEX_ADD_LID] THEN
1694   SIMP_TAC[COMPLEX_SUB_POW; ADD_CLAUSES] THEN
1695   ONCE_REWRITE_TAC[COMPLEX_RING `a * x * s:complex = x * a * s`] THEN
1696   SIMP_TAC[VSUM_COMPLEX_LMUL; FINITE_NUMSEG] THEN AP_TERM_TAC THEN
1697   SIMP_TAC[GSYM VSUM_COMPLEX_LMUL; GSYM VSUM_COMPLEX_RMUL; FINITE_NUMSEG;
1698            VSUM_VSUM_PRODUCT; FINITE_NUMSEG] THEN
1699   MATCH_MP_TAC VSUM_EQ_GENERAL_INVERSES THEN
1700   REPEAT(EXISTS_TAC `\(x:num,y:num). (y,x)`) THEN
1701   REWRITE_TAC[FORALL_IN_GSPEC; IN_ELIM_PAIR_THM; IN_NUMSEG] THEN
1702   REWRITE_TAC[ARITH_RULE `a - b - c:num = a - (b + c)`; ADD_SYM] THEN
1703   REWRITE_TAC[COMPLEX_MUL_AC] THEN ARITH_TAC);;
1704
1705 let COMPLEX_SUB_POLYFUN_ALT = prove
1706  (`!a x y n.
1707     1 <= n
1708     ==> vsum(0..n) (\i. a i * x pow i) - vsum(0..n) (\i. a i * y pow i) =
1709         (x - y) *
1710         vsum(0..n-1) (\j. vsum(0..n-j-1) (\k. a(j+k+1) * y pow k) * x pow j)`,
1711   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[COMPLEX_SUB_POLYFUN] THEN AP_TERM_TAC THEN
1712   MATCH_MP_TAC VSUM_EQ_NUMSEG THEN X_GEN_TAC `j:num` THEN REPEAT STRIP_TAC THEN
1713   REWRITE_TAC[] THEN AP_THM_TAC THEN AP_TERM_TAC THEN
1714   MATCH_MP_TAC VSUM_EQ_GENERAL_INVERSES THEN
1715   MAP_EVERY EXISTS_TAC
1716    [`\i. i - (j + 1)`; `\k. j + k + 1`] THEN
1717   REWRITE_TAC[IN_NUMSEG] THEN REPEAT STRIP_TAC THEN
1718   TRY(BINOP_TAC THEN AP_TERM_TAC) THEN ASM_ARITH_TAC);;
1719
1720 let COMPLEX_POLYFUN_LINEAR_FACTOR = prove
1721  (`!a c n. ?b. !z. vsum(0..n) (\i. c(i) * z pow i) =
1722                    (z - a) * vsum(0..n-1) (\i. b(i) * z pow i) +
1723                     vsum(0..n) (\i. c(i) * a pow i)`,
1724   REPEAT GEN_TAC THEN REWRITE_TAC[GSYM COMPLEX_EQ_SUB_RADD] THEN
1725   ASM_CASES_TAC `n = 0` THENL
1726    [EXISTS_TAC `\i:num. Cx(&0)` THEN
1727     ASM_SIMP_TAC[VSUM_SING; NUMSEG_SING; complex_pow; COMPLEX_MUL_LZERO] THEN
1728     REWRITE_TAC[COMPLEX_SUB_REFL; GSYM COMPLEX_VEC_0; VSUM_0] THEN
1729     REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_MUL_RZERO];
1730     ASM_SIMP_TAC[COMPLEX_SUB_POLYFUN; LE_1] THEN
1731     EXISTS_TAC `\j. vsum (j + 1..n) (\i. c i * a pow (i - j - 1))` THEN
1732     REWRITE_TAC[]]);;
1733
1734 let COMPLEX_POLYFUN_LINEAR_FACTOR_ROOT = prove
1735  (`!a c n. vsum(0..n) (\i. c(i) * a pow i) = Cx(&0)
1736            ==> ?b. !z. vsum(0..n) (\i. c(i) * z pow i) =
1737                       (z - a) * vsum(0..n-1) (\i. b(i) * z pow i)`,
1738   MESON_TAC[COMPLEX_POLYFUN_LINEAR_FACTOR; COMPLEX_ADD_RID]);;
1739
1740 let COMPLEX_POLYFUN_EXTREMAL_LEMMA = prove
1741  (`!c n e. &0 < e
1742            ==> ?M. !z. M <= norm(z)
1743                        ==> norm(vsum(0..n) (\i. c(i) * z pow i))
1744                                <= e * norm(z) pow (n + 1)`,
1745   GEN_TAC THEN INDUCT_TAC THEN SIMP_TAC[VSUM_CLAUSES_NUMSEG; LE_0] THEN
1746   REPEAT STRIP_TAC THENL
1747    [REWRITE_TAC[ADD_CLAUSES; complex_pow; REAL_POW_1; COMPLEX_MUL_RID] THEN
1748     EXISTS_TAC `norm(c 0:complex) / e` THEN ASM_SIMP_TAC[REAL_LE_LDIV_EQ] THEN
1749     REWRITE_TAC[REAL_MUL_AC];
1750     ALL_TAC] THEN
1751   FIRST_X_ASSUM(MP_TAC o C MATCH_MP (REAL_ARITH `&0 < &1 / &2`)) THEN
1752   DISCH_THEN(X_CHOOSE_TAC `M:real`) THEN
1753   EXISTS_TAC `max M ((&1 / &2 + norm(c(n+1):complex)) / e)` THEN
1754   X_GEN_TAC `z:complex` THEN REWRITE_TAC[REAL_MAX_LE] THEN STRIP_TAC THEN
1755   FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN
1756   MATCH_MP_TAC(NORM_ARITH
1757    `a + norm(y) <= b ==> norm(x) <= a ==> norm(x + y) <= b`) THEN
1758   SIMP_TAC[ADD1; COMPLEX_NORM_MUL; COMPLEX_NORM_POW;
1759            GSYM REAL_ADD_RDISTRIB; ARITH_RULE `(n + 1) + 1 = 1 + n + 1`] THEN
1760   GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [REAL_POW_ADD] THEN
1761   REWRITE_TAC[REAL_MUL_ASSOC] THEN MATCH_MP_TAC REAL_LE_RMUL THEN
1762   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
1763   ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_POW_LE; NORM_POS_LE; REAL_POW_1]);;
1764
1765 let COMPLEX_POLYFUN_EXTREMAL = prove
1766  (`!c n. (!k. k IN 1..n ==> c(k) = Cx(&0)) \/
1767          !B. eventually (\z. norm(vsum(0..n) (\i. c(i) * z pow i)) >= B)
1768                         at_infinity`,
1769   GEN_TAC THEN MATCH_MP_TAC num_WF THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
1770   ASM_CASES_TAC `n = 0` THEN
1771   ASM_REWRITE_TAC[NUMSEG_CLAUSES; ARITH; NOT_IN_EMPTY] THEN
1772   MP_TAC(ARITH_RULE `0 <= n`) THEN SIMP_TAC[GSYM NUMSEG_RREC] THEN
1773   DISCH_THEN(K ALL_TAC) THEN ASM_CASES_TAC `c(n:num) = Cx(&0)` THENL
1774    [FIRST_X_ASSUM(MP_TAC o SPEC `n - 1`) THEN
1775     ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
1776     ASM_SIMP_TAC[GSYM NUMSEG_RREC; LE_1] THEN
1777     SIMP_TAC[IN_INSERT; VSUM_CLAUSES; FINITE_NUMSEG; IN_NUMSEG] THEN
1778     ASM_REWRITE_TAC[COMPLEX_MUL_LZERO; COMPLEX_ADD_LID; COND_ID] THEN
1779     ASM_MESON_TAC[];
1780     DISJ2_TAC THEN MP_TAC(ISPECL
1781       [`c:num->complex`; `n - 1`; `norm(c(n:num):complex) / &2`]
1782       COMPLEX_POLYFUN_EXTREMAL_LEMMA) THEN ASM_SIMP_TAC[SUB_ADD; LE_1] THEN
1783     ASM_SIMP_TAC[COMPLEX_NORM_NZ; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
1784     SIMP_TAC[IN_INSERT; VSUM_CLAUSES; FINITE_NUMSEG; IN_NUMSEG] THEN
1785     ASM_SIMP_TAC[ARITH_RULE `~(n = 0) ==> ~(n <= n - 1)`] THEN
1786     DISCH_THEN(X_CHOOSE_TAC `M:real`) THEN X_GEN_TAC `B:real` THEN
1787     REWRITE_TAC[EVENTUALLY_AT_INFINITY] THEN EXISTS_TAC
1788      `max M (max (&1) ((abs B + &1) / (norm(c(n:num):complex) / &2)))` THEN
1789     X_GEN_TAC `z:complex` THEN REWRITE_TAC[real_ge; REAL_MAX_LE] THEN
1790     STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN
1791     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(NORM_ARITH
1792      `abs b + &1 <= norm(y) - a ==> norm(x) <= a ==> b <= norm(y + x)`) THEN
1793     REWRITE_TAC[COMPLEX_NORM_MUL; COMPLEX_NORM_POW] THEN
1794     REWRITE_TAC[REAL_ARITH `c * x - c / &2 * x = x * c / &2`] THEN
1795     ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; COMPLEX_NORM_NZ; REAL_LT_DIV;
1796                  REAL_OF_NUM_LT; ARITH] THEN
1797     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(z:complex) pow 1` THEN
1798     CONJ_TAC THENL [ASM_REWRITE_TAC[REAL_POW_1]; ALL_TAC] THEN
1799     MATCH_MP_TAC REAL_POW_MONO THEN ASM_SIMP_TAC[LE_1]]);;
1800
1801 let COMPLEX_POLYFUN_ROOTBOUND = prove
1802  (`!n c. ~(!i. i IN 0..n ==> c(i) = Cx(&0))
1803          ==> FINITE {z | vsum(0..n) (\i. c(i) * z pow i) = Cx(&0)} /\
1804              CARD {z | vsum(0..n) (\i. c(i) * z pow i) = Cx(&0)} <= n`,
1805   REWRITE_TAC[TAUT `~a ==> b <=> a \/ b`] THEN INDUCT_TAC THEN GEN_TAC THENL
1806    [SIMP_TAC[NUMSEG_SING; VSUM_SING; IN_SING; complex_pow] THEN
1807     ASM_CASES_TAC `c 0 = Cx(&0)` THEN ASM_REWRITE_TAC[COMPLEX_MUL_RID] THEN
1808     REWRITE_TAC[EMPTY_GSPEC; FINITE_RULES; CARD_CLAUSES; LE_REFL];
1809     ALL_TAC] THEN
1810   ASM_CASES_TAC `{z | vsum(0..SUC n) (\i. c(i) * z pow i) = Cx(&0)} = {}` THEN
1811   ASM_REWRITE_TAC[FINITE_RULES; CARD_CLAUSES; LE_0] THEN
1812   FIRST_X_ASSUM(X_CHOOSE_THEN `a:complex` MP_TAC o
1813     GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
1814   REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN
1815   FIRST_ASSUM(MP_TAC o MATCH_MP COMPLEX_POLYFUN_LINEAR_FACTOR_ROOT) THEN
1816   DISCH_THEN(X_CHOOSE_TAC `b:num->complex`) THEN
1817   ASM_REWRITE_TAC[COMPLEX_ENTIRE; COMPLEX_SUB_0; SUC_SUB1; SET_RULE
1818    `{z | z = a \/ P z} = a INSERT {z | P z}`] THEN
1819   FIRST_X_ASSUM(MP_TAC o SPEC `b:num->complex`) THEN
1820   STRIP_TAC THEN ASM_SIMP_TAC[CARD_CLAUSES; FINITE_RULES] THENL
1821    [DISJ1_TAC; ASM_ARITH_TAC] THEN
1822   MP_TAC(SPECL [`c:num->complex`; `SUC n`] COMPLEX_POLYFUN_EXTREMAL) THEN
1823   ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MP_TAC o SPEC `Cx(&0)`) THEN
1824   ASM_SIMP_TAC[SUC_SUB1; COMPLEX_MUL_LZERO] THEN
1825   SIMP_TAC[COMPLEX_POW_ZERO; COND_RAND; COMPLEX_MUL_RZERO] THEN
1826   ASM_SIMP_TAC[VSUM_0; GSYM COMPLEX_VEC_0; VSUM_DELTA; IN_NUMSEG; LE_0] THEN
1827   REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_MUL_RZERO; COMPLEX_NORM_NUM] THEN
1828   REWRITE_TAC[COMPLEX_MUL_RID; real_ge; EVENTUALLY_AT_INFINITY] THEN
1829   REPEAT STRIP_TAC THENL [ASM_MESON_TAC[LE_1]; ALL_TAC] THEN
1830   FIRST_X_ASSUM(MP_TAC o SPEC `&1`) THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
1831   MATCH_MP_TAC(TAUT `~a ==> a ==> b`) THEN
1832   REWRITE_TAC[NOT_EXISTS_THM; NOT_FORALL_THM] THEN X_GEN_TAC `b:real` THEN
1833   MP_TAC(SPEC `b:real` (INST_TYPE [`:2`,`:N`] VECTOR_CHOOSE_SIZE)) THEN
1834   ASM_MESON_TAC[NORM_POS_LE; REAL_LE_TOTAL; REAL_LE_TRANS]);;
1835
1836 let COMPLEX_POLYFUN_FINITE_ROOTS = prove
1837  (`!n c. FINITE {x | vsum(0..n) (\i. c i * x pow i) = Cx(&0)} <=>
1838          ?i. i IN 0..n /\ ~(c i = Cx(&0))`,
1839   REPEAT GEN_TAC THEN REWRITE_TAC[TAUT `a /\ ~b <=> ~(a ==> b)`] THEN
1840   REWRITE_TAC[GSYM NOT_FORALL_THM] THEN EQ_TAC THEN
1841   SIMP_TAC[COMPLEX_POLYFUN_ROOTBOUND] THEN
1842   ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
1843   SIMP_TAC[COMPLEX_MUL_LZERO] THEN SIMP_TAC[GSYM COMPLEX_VEC_0; VSUM_0] THEN
1844   REWRITE_TAC[SET_RULE `{x | T} = (:complex)`; GSYM INFINITE;
1845               EUCLIDEAN_SPACE_INFINITE]);;
1846
1847 let COMPLEX_POLYFUN_EQ_0 = prove
1848  (`!n c. (!z. vsum(0..n) (\i. c i * z pow i) = Cx(&0)) <=>
1849          (!i. i IN 0..n ==> c i = Cx(&0))`,
1850   REPEAT GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL
1851    [GEN_REWRITE_TAC I [TAUT `p <=> ~ ~p`] THEN DISCH_THEN(MP_TAC o MATCH_MP
1852      COMPLEX_POLYFUN_ROOTBOUND) THEN
1853     ASM_REWRITE_TAC[EUCLIDEAN_SPACE_INFINITE; GSYM INFINITE; DE_MORGAN_THM;
1854                     SET_RULE `{x | T} = (:complex)`];
1855     ASM_SIMP_TAC[IN_NUMSEG; LE_0; COMPLEX_MUL_LZERO] THEN
1856     REWRITE_TAC[GSYM COMPLEX_VEC_0; VSUM_0]]);;
1857
1858 let COMPLEX_POLYFUN_EQ_CONST = prove
1859  (`!n c k. (!z. vsum(0..n) (\i. c i * z pow i) = k) <=>
1860            c 0 = k /\ (!i. i IN 1..n ==> c i = Cx(&0))`,
1861   REPEAT GEN_TAC THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC
1862    `!x. vsum(0..n) (\i. (if i = 0 then c 0 - k else c i) * x pow i) =
1863         Cx(&0)` THEN
1864   CONJ_TAC THENL
1865    [SIMP_TAC[VSUM_CLAUSES_LEFT; LE_0; complex_pow; COMPLEX_MUL_RID] THEN
1866     REWRITE_TAC[COMPLEX_RING `(c - k) + s = Cx(&0) <=> c + s = k`] THEN
1867     AP_TERM_TAC THEN ABS_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
1868     AP_TERM_TAC THEN MATCH_MP_TAC VSUM_EQ THEN GEN_TAC THEN
1869     REWRITE_TAC[IN_NUMSEG] THEN
1870     COND_CASES_TAC THEN ASM_REWRITE_TAC[ARITH];
1871     REWRITE_TAC[COMPLEX_POLYFUN_EQ_0; IN_NUMSEG; LE_0] THEN
1872     GEN_REWRITE_TAC LAND_CONV [MESON[]
1873      `(!n. P n) <=> P 0 /\ (!n. ~(n = 0) ==> P n)`] THEN
1874     SIMP_TAC[LE_0; COMPLEX_SUB_0] THEN MESON_TAC[LE_1]]);;
1875
1876 (* ------------------------------------------------------------------------- *)
1877 (* Complex products.                                                         *)
1878 (* ------------------------------------------------------------------------- *)
1879
1880 let cproduct = new_definition
1881   `cproduct = iterate (( * ):complex->complex->complex)`;;
1882
1883 let NEUTRAL_COMPLEX_MUL = prove
1884  (`neutral(( * ):complex->complex->complex) = Cx(&1)`,
1885   REWRITE_TAC[neutral] THEN MATCH_MP_TAC SELECT_UNIQUE THEN
1886   MESON_TAC[COMPLEX_MUL_LID; COMPLEX_MUL_RID]);;
1887
1888 let MONOIDAL_COMPLEX_MUL = prove
1889  (`monoidal(( * ):complex->complex->complex)`,
1890   REWRITE_TAC[monoidal; NEUTRAL_COMPLEX_MUL] THEN SIMPLE_COMPLEX_ARITH_TAC);;
1891
1892 let CPRODUCT_CLAUSES = prove
1893  (`(!f. cproduct {} f = Cx(&1)) /\
1894    (!x f s. FINITE(s)
1895             ==> (cproduct (x INSERT s) f =
1896                  if x IN s then cproduct s f else f(x) * cproduct s f))`,
1897   REWRITE_TAC[cproduct; GSYM NEUTRAL_COMPLEX_MUL] THEN
1898   ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
1899   MATCH_MP_TAC ITERATE_CLAUSES THEN REWRITE_TAC[MONOIDAL_COMPLEX_MUL]);;
1900
1901 let CPRODUCT_EQ_0 = prove
1902  (`!f s. FINITE s ==> (cproduct s f = Cx(&0) <=> ?x. x IN s /\ f(x) = Cx(&0))`,
1903   GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1904   SIMP_TAC[CPRODUCT_CLAUSES; COMPLEX_ENTIRE; IN_INSERT; CX_INJ; REAL_OF_NUM_EQ;
1905            ARITH; NOT_IN_EMPTY] THEN
1906   MESON_TAC[]);;
1907
1908 let CPRODUCT_INV = prove
1909  (`!f s. FINITE s ==> cproduct s (\x. inv(f x)) = inv(cproduct s f)`,
1910   GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1911   SIMP_TAC[CPRODUCT_CLAUSES; COMPLEX_INV_1; COMPLEX_INV_MUL]);;
1912
1913 let CPRODUCT_MUL = prove
1914  (`!f g s. FINITE s
1915            ==> cproduct s (\x. f x * g x) = cproduct s f * cproduct s g`,
1916   GEN_TAC THEN GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1917   SIMP_TAC[CPRODUCT_CLAUSES; COMPLEX_MUL_AC; COMPLEX_MUL_LID]);;
1918
1919 let CPRODUCT_EQ_1 = prove
1920  (`!f s. (!x:A. x IN s ==> (f(x) = Cx(&1))) ==> (cproduct s f = Cx(&1))`,
1921   REWRITE_TAC[cproduct; GSYM NEUTRAL_COMPLEX_MUL] THEN
1922   SIMP_TAC[ITERATE_EQ_NEUTRAL; MONOIDAL_COMPLEX_MUL]);;
1923
1924 let CPRODUCT_1 = prove
1925  (`!s. cproduct s (\n. Cx(&1)) = Cx(&1)`,
1926   SIMP_TAC[CPRODUCT_EQ_1]);;
1927
1928 let CPRODUCT_POW = prove
1929  (`!f s n. FINITE s
1930            ==> cproduct s (\x. f x pow n) = (cproduct s f) pow n`,
1931   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
1932   DISCH_TAC THEN INDUCT_TAC THEN
1933   ASM_SIMP_TAC[complex_pow; CPRODUCT_MUL; CPRODUCT_1]);;
1934
1935 let NORM_CPRODUCT = prove
1936  (`!f s. FINITE s ==> norm(cproduct s f) = product s (\x. norm(f x))`,
1937   GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1938   SIMP_TAC[CPRODUCT_CLAUSES; COMPLEX_NORM_CX; REAL_ABS_NUM;
1939            CPRODUCT_MUL; PRODUCT_CLAUSES; COMPLEX_NORM_MUL]);;
1940
1941 let CPRODUCT_EQ = prove
1942  (`!f g s. (!x. x IN s ==> (f x = g x)) ==> cproduct s f = cproduct s g`,
1943   REWRITE_TAC[cproduct] THEN MATCH_MP_TAC ITERATE_EQ THEN
1944   REWRITE_TAC[MONOIDAL_COMPLEX_MUL]);;