Update from HH
[hl193./.git] / Multivariate / gamma.ml
1 (* ========================================================================= *)
2 (* The real and complex gamma functions and Euler-Mascheroni constant.       *)
3 (* ========================================================================= *)
4
5 needs "Multivariate/cauchy.ml";;
6
7 (* ------------------------------------------------------------------------- *)
8 (* Euler-Macheroni constant.                                                 *)
9 (* ------------------------------------------------------------------------- *)
10
11 let euler_mascheroni = new_definition
12   `euler_mascheroni =
13    reallim sequentially (\n. sum(1..n) (\k. inv(&k)) - log(&n))`;;
14
15 let EULER_MASCHERONI = prove
16  (`((\n. sum(1..n) (\k. inv(&k)) - log(&n)) ---> euler_mascheroni)
17    sequentially`,
18   REWRITE_TAC[euler_mascheroni; reallim] THEN CONV_TAC SELECT_CONV THEN
19   SUBGOAL_THEN
20    `real_summable (from 1) (\k. inv(&k) + (log(&k) - log(&(k + 1))))`
21   MP_TAC THENL
22    [MATCH_MP_TAC REAL_SUMMABLE_COMPARISON THEN
23     EXISTS_TAC `\k. &2 / &k pow 2` THEN CONJ_TAC THENL
24      [REWRITE_TAC[real_div] THEN MATCH_MP_TAC REAL_SUMMABLE_LMUL THEN
25       MATCH_MP_TAC REAL_SUMMABLE_ZETA_INTEGER THEN REWRITE_TAC[LE_REFL];
26       EXISTS_TAC `2` THEN REWRITE_TAC[GE; IN_FROM] THEN
27       X_GEN_TAC `n:num` THEN STRIP_TAC THEN
28       ONCE_REWRITE_TAC[REAL_ARITH `a + (b - c):real = a - (c - b)`] THEN
29       ASM_SIMP_TAC[GSYM LOG_DIV; REAL_OF_NUM_LT; LE_1;
30                    ARITH_RULE `0 < n + 1`] THEN
31       ASM_SIMP_TAC[GSYM REAL_OF_NUM_ADD; REAL_OF_NUM_LT; LE_1; REAL_FIELD
32        `&0 < n ==> (n + &1) / n = &1 + inv(n)`] THEN
33       MP_TAC(ISPECL [`1`; `Cx(inv(&n))`] TAYLOR_CLOG)];
34     REWRITE_TAC[real_summable; real_sums; FROM_INTER_NUMSEG] THEN
35     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real` THEN
36     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REALLIM_TRANSFORM) THEN
37     REWRITE_TAC[SUM_ADD_NUMSEG; REAL_ARITH
38      `(x + y) - (x - z):real = y + z`] THEN
39     REWRITE_TAC[SUM_DIFFS; LOG_1; COND_RAND; COND_RATOR] THEN
40     REWRITE_TAC[REAL_ARITH `&0 - x + y = --(x - y)`] THEN
41     MATCH_MP_TAC REALLIM_NULL_COMPARISON THEN
42     EXISTS_TAC `\n. &2 / &n` THEN CONJ_TAC THENL
43      [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `2` THEN
44       X_GEN_TAC `n:num` THEN DISCH_TAC THEN
45       COND_CASES_TAC THENL [ALL_TAC; ASM_ARITH_TAC] THEN
46       ASM_SIMP_TAC[REAL_ABS_NEG; GSYM LOG_DIV; REAL_OF_NUM_LT; LE_1;
47                    ARITH_RULE `0 < n + 1`] THEN
48       ASM_SIMP_TAC[GSYM REAL_OF_NUM_ADD; REAL_OF_NUM_LT; LE_1; REAL_FIELD
49        `&0 < n ==> (n + &1) / n = &1 + inv(n)`] THEN
50       MP_TAC(ISPECL [`0`; `Cx(inv(&n))`] TAYLOR_CLOG);
51       REWRITE_TAC[real_div] THEN MATCH_MP_TAC REALLIM_NULL_LMUL THEN
52       REWRITE_TAC[REALLIM_1_OVER_N]]] THEN
53   REWRITE_TAC[GSYM CX_ADD; VSUM_SING_NUMSEG; COMPLEX_NORM_CX] THEN
54   REWRITE_TAC[VSUM_CLAUSES_NUMSEG] THEN CONV_TAC NUM_REDUCE_CONV THEN
55   REWRITE_TAC[REAL_ABS_INV; REAL_ABS_NUM; COMPLEX_DIV_1] THEN
56   ASM_SIMP_TAC[COMPLEX_POW_1; REAL_INV_LT_1; REAL_OF_NUM_LT;
57                ARITH_RULE `1 < n <=> 2 <= n`] THEN
58   REWRITE_TAC[COMPLEX_POW_2; COMPLEX_MUL_LNEG; COMPLEX_MUL_LID] THEN
59   ASM_SIMP_TAC[COMPLEX_NEG_NEG; GSYM CX_LOG; REAL_LT_ADD; REAL_OF_NUM_LT;
60                LE_1; ARITH; REAL_LT_INV_EQ; GSYM CX_SUB] THEN
61   REWRITE_TAC[REAL_POW_1; VECTOR_SUB_RZERO] THEN
62   REWRITE_TAC[COMPLEX_NORM_CX] THEN REWRITE_TAC[REAL_ABS_SUB] THEN
63   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
64   REWRITE_TAC[real_div; REAL_POW_INV] THEN
65   GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN
66   MATCH_MP_TAC REAL_LE_LMUL THEN
67   SIMP_TAC[REAL_LE_INV_EQ; REAL_POW_LE; REAL_POS] THEN
68   GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN
69   MATCH_MP_TAC REAL_LE_INV2 THEN
70   CONV_TAC REAL_RAT_REDUCE_CONV THEN
71   REWRITE_TAC[REAL_ARITH `&1 / &2 <= &1 - &1 / n <=> inv(n) <= inv(&2)`] THEN
72   MATCH_MP_TAC REAL_LE_INV2 THEN
73   REWRITE_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN ASM_ARITH_TAC);;
74
75 (* ------------------------------------------------------------------------- *)
76 (* Simple-minded estimation of gamma using Euler-Maclaurin summation.        *)
77 (* ------------------------------------------------------------------------- *)
78
79 let LOG2_APPROX_40 = prove
80  (`abs(log(&2) - &381061692393 / &549755813888) <= inv(&2 pow 40)`,
81   MP_TAC(SPECL [`41`; `Cx(--inv(&2))`] TAYLOR_CLOG) THEN
82   SIMP_TAC[GSYM CX_DIV; GSYM CX_POW; GSYM CX_NEG; GSYM CX_ADD; GSYM CX_MUL;
83            VSUM_CX; COMPLEX_NORM_CX; GSYM CX_LOG; GSYM CX_SUB;
84             REAL_ARITH `&0 < &1 + --inv(&2)`] THEN
85   CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
86   REWRITE_TAC[REAL_ARITH `a * b / c:real = a / c * b`] THEN
87   CONV_TAC(ONCE_DEPTH_CONV EXPAND_SUM_CONV) THEN
88   CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
89   REWRITE_TAC[real_div; REAL_MUL_LID] THEN
90   SIMP_TAC[LOG_INV; REAL_ARITH `&0 < &2`] THEN REAL_ARITH_TAC);;
91
92 let EULER_MASCHERONI_APPROX_32 = prove
93  (`abs(euler_mascheroni - &2479122403 / &4294967296) <= inv(&2 pow 32)`,
94   let lemma1 = prove
95    (`!m n. 1 <= m /\ m <= n
96            ==> abs((sum (1..n) (\k. inv(&k)) - log(&n)) -
97                    ((sum (1..m - 1) (\k. inv(&k)) - log(&m)) +
98                     (inv(&m) + inv(&n)) / &2 +
99                     &1 / &12 * (inv(&m pow 2) - inv(&n pow 2)) +
100                     -- &1 / &120 * (inv(&m pow 4) - inv(&n pow 4))))
101                 <= inv(&60 * &m pow 5)`,
102     REPEAT STRIP_TAC THEN
103     MP_TAC(SPECL [`\k. inv(&k)`; `1:num`; `m - 1`; `n:num`] SUM_COMBINE_R) THEN
104     ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN(SUBST1_TAC o SYM)] THEN
105     ASM_SIMP_TAC[ARITH_RULE `1 <= m ==> m - 1 + 1 = m`] THEN
106     MP_TAC(ISPECL
107      [`\n x. --(&1) pow n * &(FACT n) / x pow (n + 1)`;
108       `m:num`; `n:num`; `2`] REAL_EULER_MACLAURIN) THEN
109     ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV THEN ANTS_TAC THENL
110      [REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT
111       STRIP_TAC THEN REAL_DIFF_TAC THEN
112       REWRITE_TAC[REAL_MUL_LZERO; ADD_SUB; REAL_MUL_RID; REAL_SUB_LZERO] THEN
113       REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC; REAL_POW_EQ_0;
114                   REAL_MUL_LNEG; REAL_MUL_RNEG] THEN
115       RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN
116       ASM_CASES_TAC `x = &0` THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
117       REWRITE_TAC[GSYM real_div; REAL_POW_POW] THEN
118       ASM_SIMP_TAC[REAL_DIV_POW2_ALT; ARITH_RULE `~((k + 1) * 2 < k)`] THEN
119       REWRITE_TAC[ARITH_RULE `(k + 1) * 2 - k = SUC(SUC k)`;
120                   ARITH_RULE `(k + 1) + 1 = SUC(SUC k)`] THEN
121       REWRITE_TAC[REAL_POW_ADD; REAL_POW_1] THEN
122       REWRITE_TAC[REAL_MUL_RNEG; REAL_MUL_LNEG; REAL_MUL_RID] THEN
123       AP_TERM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[real_div] THEN
124       REWRITE_TAC[REAL_MUL_ASSOC] THEN AP_THM_TAC THEN AP_TERM_TAC THEN
125       REWRITE_TAC[GSYM ADD1; FACT; REAL_OF_NUM_MUL; MULT_AC];
126       DISCH_THEN(MP_TAC o CONJUNCT2) THEN
127       REWRITE_TAC[real_div; REAL_MUL_LID; real_pow] THEN
128       CONV_TAC(ONCE_DEPTH_CONV EXPAND_SUM_CONV) THEN
129       CONV_TAC NUM_REDUCE_CONV THEN
130       CONV_TAC(ONCE_DEPTH_CONV BERNOULLI_CONV) THEN
131       REWRITE_TAC[GSYM(BERNOULLI_CONV `bernoulli 5 x`)] THEN
132       CONV_TAC REAL_RAT_REDUCE_CONV THEN
133       REWRITE_TAC[REAL_MUL_LNEG; REAL_MUL_LID; REAL_POW_1] THEN
134       REWRITE_TAC[real_div; REAL_MUL_LID] THEN DISCH_THEN SUBST1_TAC] THEN
135     MP_TAC(ISPECL [`\x. log x`; `\x:real. inv x`; `&m`; `&n`]
136           REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN
137     ASM_REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE] THEN
138     ANTS_TAC THENL
139      [REWRITE_TAC[IN_REAL_INTERVAL; GSYM REAL_OF_NUM_ADD] THEN
140       REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN
141       RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN
142       ASM_REAL_ARITH_TAC;
143       DISCH_THEN(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE)] THEN
144     MATCH_MP_TAC REAL_LE_TRANS THEN
145     EXISTS_TAC
146      `&1 / &120 *
147       abs(real_integral (real_interval[&m,&n])
148                         (\x. bernoulli 5 (frac x) *
149                              --(&120 * inv(x pow 6))))` THEN
150     CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN
151     REWRITE_TAC[REAL_ARITH `b * --(n * inv x):real = --n * b / x`] THEN
152     SUBGOAL_THEN
153      `(\x. bernoulli 5 (frac x) / x pow 6)
154       real_measurable_on real_interval[&m,&n]`
155     ASSUME_TAC THENL
156      [MATCH_MP_TAC
157        REAL_CONTINUOUS_AE_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET THEN
158       EXISTS_TAC `integer` THEN
159       REWRITE_TAC[REAL_LEBESGUE_MEASURABLE_INTERVAL] THEN
160       SIMP_TAC[REAL_NEGLIGIBLE_COUNTABLE; COUNTABLE_INTEGER] THEN
161       REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
162       REWRITE_TAC[IN_DIFF; IN_REAL_INTERVAL] THEN REWRITE_TAC[IN] THEN
163       X_GEN_TAC `x:real` THEN STRIP_TAC THEN
164       MATCH_MP_TAC REAL_CONTINUOUS_ATREAL_WITHINREAL THEN
165       MATCH_MP_TAC REAL_DIFFERENTIABLE_IMP_CONTINUOUS_ATREAL THEN
166       REAL_DIFFERENTIABLE_TAC THEN ASM_REWRITE_TAC[REAL_POW_EQ_0] THEN
167       RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN
168       ASM_REAL_ARITH_TAC;
169       ALL_TAC] THEN
170     MP_TAC(ISPECL
171      [`\x. inv(-- &60 * x pow 5)`; `\x. inv(&12 * x pow 6)`;
172       `&m`; `&n`] REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN
173     ASM_REWRITE_TAC[REAL_OF_NUM_LE] THEN ANTS_TAC THENL
174      [REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
175       REAL_DIFF_TAC THEN CONV_TAC NUM_REDUCE_CONV THEN
176       SUBGOAL_THEN `~(x = &0)` MP_TAC THENL
177        [RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN
178         ASM_REAL_ARITH_TAC;
179         CONV_TAC REAL_FIELD];
180       REWRITE_TAC[REAL_INV_MUL; REAL_ARITH
181        `inv(-- &60) * x - inv(-- &60) * y = (y - x) / &60`] THEN
182       REWRITE_TAC[GSYM REAL_INV_MUL] THEN DISCH_TAC] THEN
183     SUBGOAL_THEN
184      `!x. x IN real_interval[&m,&n]
185           ==> abs(bernoulli 5 (frac x) / x pow 6) <= inv(&12 * x pow 6)`
186     ASSUME_TAC THENL
187      [REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
188       REWRITE_TAC[REAL_INV_MUL; real_div; REAL_ABS_MUL] THEN
189       MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[REAL_ABS_POS] THEN
190       CONJ_TAC THENL
191        [MP_TAC(ISPECL [`5`; `frac x`] BERNOULLI_BOUND) THEN
192         SIMP_TAC[IN_REAL_INTERVAL; FLOOR_FRAC; REAL_LT_IMP_LE] THEN
193         CONV_TAC NUM_REDUCE_CONV THEN
194         REWRITE_TAC[BERNOULLI_CONV `bernoulli 4 (&0)`] THEN
195         REAL_ARITH_TAC;
196         REWRITE_TAC[REAL_ARITH `abs x <= x <=> &0 <= x`] THEN
197         REWRITE_TAC[REAL_LE_INV_EQ] THEN MATCH_MP_TAC REAL_POW_LE THEN
198         RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN
199         ASM_REAL_ARITH_TAC];
200       ALL_TAC] THEN
201     SUBGOAL_THEN
202      `(\x. bernoulli 5 (frac x) / x pow 6)
203       real_integrable_on real_interval[&m,&n]`
204     ASSUME_TAC THENL
205      [MATCH_MP_TAC REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE THEN
206       EXISTS_TAC `\x:real. inv(&12 * x pow 6)` THEN
207       ASM_REWRITE_TAC[REAL_INTEGRABLE_CONST] THEN
208       ASM_MESON_TAC[real_integrable_on];
209       ASM_SIMP_TAC[REAL_INTEGRAL_LMUL; REAL_ABS_MUL; REAL_MUL_ASSOC]] THEN
210     CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[REAL_MUL_LID] THEN
211     TRANS_TAC REAL_LE_TRANS
212      `real_integral (real_interval [&m,&n]) (\x. inv(&12 * x pow 6))` THEN
213     CONJ_TAC THENL
214      [MATCH_MP_TAC REAL_INTEGRAL_ABS_BOUND_INTEGRAL THEN
215       ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[real_integrable_on];
216       FIRST_ASSUM(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN
217       REWRITE_TAC[REAL_INV_MUL] THEN
218       REWRITE_TAC[REAL_LE_INV_EQ; REAL_ARITH
219        `(x - y) / &60 <= inv(&60) * x <=> &0 <= y`] THEN
220       SIMP_TAC[REAL_POW_LE; REAL_POS]])
221   and lemma2 = prove
222    (`!f g l m d e k.
223           (f ---> l) sequentially
224           ==> (g ---> m) sequentially /\
225               eventually (\n. abs(f n - g n) <= d) sequentially /\
226               abs(m - k) <= e - d
227               ==> abs(l - k) <= e`,
228     REPEAT GEN_TAC THEN DISCH_TAC THEN
229     REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
230     MATCH_MP_TAC(REAL_ARITH
231      `abs(l - m) <= d ==> abs (m - k) <= e - d ==> abs (l - k) <= e`) THEN
232     REWRITE_TAC[REAL_ABS_BOUNDS] THEN CONJ_TAC THENL
233      [MATCH_MP_TAC(ISPEC `sequentially` REALLIM_LBOUND);
234       MATCH_MP_TAC(ISPEC `sequentially` REALLIM_UBOUND)] THEN
235     EXISTS_TAC `(\n. f n - g n):num->real` THEN
236     ASM_SIMP_TAC[REALLIM_SUB; TRIVIAL_LIMIT_SEQUENTIALLY] THEN
237     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT]
238        EVENTUALLY_MONO)) THEN
239     REAL_ARITH_TAC) in
240   MATCH_MP_TAC(MATCH_MP lemma2 EULER_MASCHERONI) THEN
241   MATCH_MP_TAC(MESON[]
242    `(?a b c m:num. P (a m) (b m) (c m)) ==> ?a b c. P a b c`) THEN
243   EXISTS_TAC
244     `\m n. (sum(1..m - 1) (\k. inv(&k)) - log(&m)) +
245            (inv(&m) + inv(&n)) / &2 +
246            &1 / &12 * (inv(&m pow 2) - inv(&n pow 2)) +
247            -- &1 / &120 * (inv(&m pow 4) - inv(&n pow 4))` THEN
248   EXISTS_TAC
249    `\m. (sum(1..m - 1) (\k. inv(&k)) - log(&m)) +
250          inv(&m) / &2 +
251          &1 / &12 * inv(&m pow 2) +
252          -- &1 / &120 * inv(&m pow 4)` THEN
253   EXISTS_TAC `\m. inv (&60 * &m pow 5)` THEN REWRITE_TAC[GSYM CONJ_ASSOC] THEN
254   MATCH_MP_TAC(MESON[] `(!n. P n) /\ (?n. Q n) ==> (?n. P n /\ Q n)`) THEN
255   REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
256    [GEN_TAC THEN
257     REPEAT(MATCH_MP_TAC REALLIM_ADD THEN CONJ_TAC) THEN
258     REWRITE_TAC[REALLIM_CONST] THEN
259     REWRITE_TAC[REAL_ARITH `x / &2 = inv(&2) * x`] THEN
260     MATCH_MP_TAC REALLIM_LMUL THEN REWRITE_TAC[real_sub] THEN
261     GEN_REWRITE_TAC LAND_CONV [GSYM REAL_ADD_RID] THEN
262     MATCH_MP_TAC REALLIM_ADD THEN REWRITE_TAC[REALLIM_CONST] THEN
263     REWRITE_TAC[REALLIM_NULL_NEG] THEN
264     REWRITE_TAC[REALLIM_1_OVER_N] THEN
265     MATCH_MP_TAC REALLIM_1_OVER_POW THEN CONV_TAC NUM_REDUCE_CONV;
266     ALL_TAC] THEN
267   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
268   MATCH_MP_TAC(MESON[] `(?a. P a a /\ Q a) ==> ?a. (?b. P a b) /\ Q a`) THEN
269   EXISTS_TAC `64` THEN CONJ_TAC THENL
270    [REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma1 THEN ASM_ARITH_TAC; ALL_TAC] THEN
271   SUBGOAL_THEN `log(&64) = &6 * log(&2)` SUBST1_TAC THENL
272    [SIMP_TAC[GSYM LOG_POW; REAL_ARITH `&0 < &2`] THEN
273     AP_TERM_TAC THEN CONV_TAC REAL_RAT_REDUCE_CONV;
274     CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
275     CONV_TAC(ONCE_DEPTH_CONV EXPAND_SUM_CONV) THEN
276     CONV_TAC REAL_RAT_REDUCE_CONV THEN
277     MP_TAC LOG2_APPROX_40 THEN REAL_ARITH_TAC]);;
278
279 (* ------------------------------------------------------------------------- *)
280 (* Start with the log-gamma function. It's otherwise quite tedious to repeat *)
281 (* essentially the same argument when we want the logarithm of the gamma     *)
282 (* function, since we can't just take the usual principal value of log.      *)
283 (* ------------------------------------------------------------------------- *)
284
285 let lgamma = new_definition
286  `lgamma z = lim sequentially
287                (\n. z * clog(Cx(&n)) - clog z -
288                     vsum(1..n) (\m. clog((Cx(&m) + z) / Cx(&m))))`;;
289
290 let LGAMMA,COMPLEX_DIFFERENTIABLE_AT_LGAMMA = (CONJ_PAIR o prove)
291  (`(!z. (!n. ~(z + Cx(&n) = Cx(&0)))
292         ==> ((\n. z * clog(Cx(&n)) - clog z -
293                   vsum(1..n) (\m. clog((Cx(&m) + z) / Cx(&m))))
294              --> lgamma(z)) sequentially) /\
295    (!z. (Im z = &0 ==> &0 < Re z) ==> lgamma complex_differentiable at z)`,
296   SUBGOAL_THEN `open {z | !n. ~(z + Cx(&n) = Cx(&0))}` ASSUME_TAC THENL
297    [REWRITE_TAC[SET_RULE `{z | !n. P n z} = UNIV DIFF {z | ?n. ~P n z}`] THEN
298     REWRITE_TAC[GSYM closed] THEN MATCH_MP_TAC DISCRETE_IMP_CLOSED THEN
299     EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01; IMP_CONJ] THEN
300     REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
301     SIMP_TAC[COMPLEX_RING `x + y = Cx(&0) <=> x = --y`] THEN
302     REWRITE_TAC[COMPLEX_RING `--x - --y:complex = y - x`] THEN
303     REWRITE_TAC[COMPLEX_EQ_NEG2; CX_INJ; GSYM CX_SUB; COMPLEX_NORM_CX] THEN
304     SIMP_TAC[GSYM REAL_EQ_INTEGERS; INTEGER_CLOSED];
305     ALL_TAC] THEN
306   SUBGOAL_THEN
307    `!y.  (!n. ~(y + Cx(&n) = Cx(&0)))
308          ==> ?d l. &0 < d /\
309                    !e. &0 < e
310                        ==> ?N. !n z. N <= n /\ z IN cball(y,d)
311                                    ==> dist(z * clog(Cx(&n)) -
312                                             vsum(1..n)
313                                              (\m. clog((Cx(&m) + z) / Cx(&m))),
314                                             l z) < e`
315   MP_TAC THENL
316    [REPEAT STRIP_TAC THEN
317     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN
318     REWRITE_TAC[OPEN_CONTAINS_CBALL] THEN
319     DISCH_THEN(MP_TAC o SPEC `y:complex`) THEN
320     ASM_REWRITE_TAC[IN_ELIM_THM] THEN
321     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN
322     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
323     REWRITE_TAC[UNIFORMLY_CONVERGENT_EQ_CAUCHY_ALT] THEN
324     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
325     SUBGOAL_THEN
326      `summable (from 1)
327          (\m. Cx(&2 * ((norm(y:complex) + d) +
328                       (norm(y) + d) pow 2)) / Cx(&m) pow 2)`
329     MP_TAC THENL
330      [REWRITE_TAC[complex_div; COMPLEX_MUL_ASSOC] THEN
331       MATCH_MP_TAC SUMMABLE_COMPLEX_LMUL THEN
332       MATCH_MP_TAC SUMMABLE_ZETA_INTEGER THEN REWRITE_TAC[LE_REFL];
333       ALL_TAC] THEN
334     REWRITE_TAC[summable; SERIES_CAUCHY; GE] THEN
335     DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
336     DISCH_THEN(X_CHOOSE_THEN `M:num` (LABEL_TAC "M")) THEN
337     MP_TAC(SPEC `&2 * (norm(y:complex) + d) + &1` REAL_ARCH_SIMPLE) THEN
338     DISCH_THEN(X_CHOOSE_THEN `N:num` (LABEL_TAC "N")) THEN
339     EXISTS_TAC `MAX (MAX 1 2) (MAX M N)` THEN
340     MAP_EVERY X_GEN_TAC [`m:num`; `n:num`; `z:complex`] THEN
341     REWRITE_TAC[GE; ARITH_RULE `MAX a b <= c <=> a <= c /\ b <= c`] THEN
342     STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL [`m + 1`; `n:num`]) THEN
343     ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
344     REWRITE_TAC[FROM_INTER_NUMSEG_MAX; ARITH_RULE `MAX 1 (m + 1) = m + 1`] THEN
345     REWRITE_TAC[dist] THEN
346     SUBGOAL_THEN
347      `!n. 1 <= n
348           ==> z * clog(Cx(&n)) - vsum(1..n) (\m. clog((Cx(&m) + z) / Cx(&m))) =
349               vsum(1..n) (\m. z * (clog(Cx(&(m + 1) - &1)) -
350                                    clog(Cx(&m - &1))) -
351                               clog((Cx(&m) + z) / Cx(&m))) +
352               z * clog(Cx(&0))`
353      (fun th -> ASM_SIMP_TAC[th])
354     THENL
355      [REWRITE_TAC[VSUM_SUB_NUMSEG] THEN
356       ASM_SIMP_TAC[VSUM_COMPLEX_LMUL; FINITE_NUMSEG; VSUM_DIFFS_ALT] THEN
357       REWRITE_TAC[GSYM REAL_OF_NUM_ADD; REAL_ARITH `(x + &1) - &1 = x`;
358                   REAL_SUB_REFL] THEN
359       REPEAT STRIP_TAC THEN CONV_TAC COMPLEX_RING;
360       ALL_TAC] THEN
361     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN
362     SUBGOAL_THEN `1 <= m + 1 /\ m <= n` MP_TAC THENL
363      [ASM_ARITH_TAC;
364       DISCH_THEN(fun th -> REWRITE_TAC[GSYM(MATCH_MP VSUM_COMBINE_R th)])] THEN
365     REWRITE_TAC[COMPLEX_RING `(x + a) - ((x + y) + a):complex = --y`] THEN
366     REWRITE_TAC[NORM_NEG] THEN MATCH_MP_TAC COMPLEX_NORM_VSUM_BOUND THEN
367     REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN X_GEN_TAC `k:num` THEN
368     STRIP_TAC THEN REWRITE_TAC[GSYM CX_POW; GSYM CX_DIV; REAL_CX; RE_CX] THEN
369     REWRITE_TAC[COMPLEX_RING `z * (a - b) - c:complex = --(z * (b - a) + c)`;
370       NORM_NEG; GSYM REAL_OF_NUM_ADD; REAL_ARITH `(x + &1) - &1 = x`] THEN
371     SUBGOAL_THEN `1 <= k /\ 1 < k /\ 2 <= k` STRIP_ASSUME_TAC THENL
372      [ASM_ARITH_TAC; ALL_TAC] THEN
373     SUBGOAL_THEN
374      `clog(Cx(&k - &1)) - clog(Cx(&k)) = clog(Cx(&1) - inv(Cx(&k)))`
375     SUBST1_TAC THENL
376      [ASM_SIMP_TAC[GSYM CX_LOG; REAL_OF_NUM_LE; REAL_SUB_LT; REAL_INV_LT_1;
377                    REAL_ARITH `&2 <= x ==> &0 < x /\ &1 < x /\ &0 < x - &1`;
378                    GSYM CX_SUB; GSYM CX_INV; GSYM LOG_DIV] THEN
379       AP_TERM_TAC THEN AP_TERM_TAC THEN UNDISCH_TAC `2 <= k` THEN
380       REWRITE_TAC[GSYM REAL_OF_NUM_LE] THEN CONV_TAC REAL_FIELD;
381       ALL_TAC] THEN
382     MP_TAC(ISPECL [`1`; `z / Cx(&k)`] TAYLOR_CLOG) THEN
383     MP_TAC(ISPECL [`1`; `--inv(Cx(&k))`] TAYLOR_CLOG) THEN
384     REWRITE_TAC[VSUM_SING_NUMSEG] THEN CONV_TAC NUM_REDUCE_CONV THEN
385     REWRITE_TAC[GSYM VECTOR_SUB; NORM_NEG] THEN
386     REWRITE_TAC[COMPLEX_NORM_INV; COMPLEX_NORM_DIV; COMPLEX_NORM_CX] THEN
387     REWRITE_TAC[COMPLEX_POW_NEG; ARITH; REAL_ABS_NUM; COMPLEX_POW_ONE] THEN
388     ASM_SIMP_TAC[REAL_INV_LT_1; REAL_OF_NUM_LT; COMPLEX_DIV_1] THEN
389     ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; LE_1; COMPLEX_POW_1] THEN
390     REWRITE_TAC[REAL_MUL_LID; COMPLEX_MUL_LID] THEN
391     DISCH_THEN(MP_TAC o SPEC `norm(z:complex)` o MATCH_MP
392       (REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_LMUL)) THEN
393     REWRITE_TAC[NORM_POS_LE; GSYM COMPLEX_NORM_MUL] THEN
394     SUBGOAL_THEN `norm(z:complex) < &k` ASSUME_TAC THENL
395      [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_CBALL]) THEN
396       FIRST_X_ASSUM(K ALL_TAC o check (is_forall o concl)) THEN
397       REPEAT(POP_ASSUM MP_TAC) THEN
398       REWRITE_TAC[GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_ADD] THEN
399       CONV_TAC NORM_ARITH;
400       ASM_REWRITE_TAC[COMPLEX_SUB_LDISTRIB]] THEN
401     ASM_SIMP_TAC[CX_INJ; REAL_OF_NUM_EQ; LE_1; COMPLEX_FIELD
402       `~(k = Cx(&0)) ==> (k + z) / k = Cx(&1) + z / k`] THEN
403     MATCH_MP_TAC(NORM_ARITH
404      `x' = --y' /\ d + e <= f
405       ==> norm(x - x') <= d ==> norm(y - y') <= e
406           ==> norm(x + y) <= f`) THEN
407     REWRITE_TAC[complex_div; COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG] THEN
408     REWRITE_TAC[REAL_POW_DIV; REAL_POW_INV; REAL_ARITH
409      `n * inv k / d + n pow 2 / k / e <= (&2 * (x + x pow 2)) / k <=>
410       (n * (&1 / d + n / e)) / k <= (x * (&2 + &2 * x)) / k`] THEN
411     ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_OF_NUM_LT; LE_1; REAL_POW_LT] THEN
412     MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[NORM_POS_LE] THEN
413     SUBGOAL_THEN `norm(z:complex) <= norm(y:complex) + d` ASSUME_TAC THENL
414      [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_CBALL]) THEN
415       CONV_TAC NORM_ARITH;
416       ALL_TAC] THEN
417     REPEAT CONJ_TAC THENL
418      [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_CBALL]) THEN
419       CONV_TAC NORM_ARITH;
420       MATCH_MP_TAC REAL_LE_ADD THEN CONJ_TAC THEN
421       MATCH_MP_TAC REAL_LE_DIV THEN
422       REWRITE_TAC[REAL_SUB_LE; NORM_POS_LE; REAL_POS] THEN
423       REWRITE_TAC[REAL_ARITH `inv x = &1 / x`] THEN
424       ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1];
425       REWRITE_TAC[REAL_ARITH `&2 + &2 * x = &1 * &2 + x * &2`] THEN
426       ONCE_REWRITE_TAC[real_div] THEN MATCH_MP_TAC REAL_LE_ADD2 THEN
427       CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
428       ASM_REWRITE_TAC[NORM_POS_LE; REAL_POS; REAL_LE_REFL; REAL_LE_INV_EQ] THEN
429       REWRITE_TAC[REAL_SUB_LE] THEN
430       REWRITE_TAC[REAL_ARITH `inv x = &1 / x`] THEN
431       ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN
432       ASM_REWRITE_TAC[REAL_MUL_LID; REAL_OF_NUM_LE] THEN
433       TRY(CONJ_TAC THENL
434       [RULE_ASSUM_TAC(REWRITE_RULE
435           [GSYM REAL_OF_NUM_LT; GSYM REAL_OF_NUM_ADD]) THEN
436        ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
437       REWRITE_TAC[real_div; REAL_MUL_LID] THEN
438       GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN
439       MATCH_MP_TAC REAL_LE_INV2 THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
440       REWRITE_TAC[REAL_ARITH `&1 / &2 <= &1 - x <=> x <= &1 / &2`] THEN
441       REWRITE_TAC[real_div; REAL_MUL_LID] THEN REWRITE_TAC[GSYM real_div] THEN
442       REWRITE_TAC[REAL_ARITH `inv x = &1 / x`] THEN
443       ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1]] THEN
444     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_CBALL]) THEN
445     FIRST_X_ASSUM(K ALL_TAC o check (is_forall o concl)) THEN
446     REPEAT(POP_ASSUM MP_TAC) THEN
447     REWRITE_TAC[GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_ADD] THEN
448     CONV_TAC NORM_ARITH;
449     GEN_REWRITE_TAC (LAND_CONV o REDEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
450     REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC
451      [`dd:complex->real`; `ll:complex->complex->complex`] THEN
452     DISCH_THEN(LABEL_TAC "*")] THEN
453   SUBGOAL_THEN
454    `!z. (!n. ~(z + Cx(&n) = Cx(&0)))
455         ==> ((\n. z * clog(Cx(&n)) -
456                   vsum (1..n) (\m. clog((Cx(&m) + z) / Cx(&m)))) --> ll z z)
457             sequentially`
458   ASSUME_TAC THENL
459    [X_GEN_TAC `z:complex` THEN DISCH_TAC THEN
460     FIRST_X_ASSUM(MP_TAC o SPEC `z:complex`) THEN
461     ASM_REWRITE_TAC[LIM_SEQUENTIALLY; GSYM SKOLEM_THM] THEN
462     MESON_TAC[CENTRE_IN_CBALL; REAL_LT_IMP_LE];
463     ALL_TAC] THEN
464   MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
465    [REPEAT STRIP_TAC THEN
466     REWRITE_TAC[lgamma; lim] THEN CONV_TAC SELECT_CONV THEN
467     EXISTS_TAC `(ll:complex->complex->complex) z z - clog z` THEN
468     ONCE_REWRITE_TAC[COMPLEX_RING `w - z - v:complex = (w - v) - z`] THEN
469     MATCH_MP_TAC LIM_SUB THEN REWRITE_TAC[LIM_CONST] THEN ASM_MESON_TAC[];
470     DISCH_TAC] THEN
471   X_GEN_TAC `z:complex` THEN DISCH_TAC THEN
472   SUBGOAL_THEN `!n. ~(z + Cx(&n) = Cx(&0))` ASSUME_TAC THENL
473    [GEN_TAC THEN
474     REWRITE_TAC[COMPLEX_RING `z + x = Cx(&0) <=> z = --x`] THEN
475     DISCH_THEN SUBST_ALL_TAC THEN
476     FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN
477     REWRITE_TAC[IM_NEG; RE_NEG; IM_CX; RE_CX] THEN REAL_ARITH_TAC;
478     ALL_TAC] THEN
479   MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_AT THEN
480   EXISTS_TAC `\z. (ll:complex->complex->complex) z z - clog z` THEN
481   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN
482   REWRITE_TAC[OPEN_CONTAINS_BALL] THEN
483   DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN
484   ASM_REWRITE_TAC[IN_ELIM_THM; SUBSET; IN_BALL] THEN
485   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN STRIP_TAC THEN
486   ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
487    [X_GEN_TAC `w:complex` THEN ONCE_REWRITE_TAC[DIST_SYM] THEN DISCH_TAC THEN
488     MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
489     REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
490     EXISTS_TAC `\n. w * clog(Cx(&n)) - clog w -
491                     vsum(1..n) (\m. clog((Cx(&m) + w) / Cx(&m)))` THEN
492     ASM_SIMP_TAC[] THEN
493     ONCE_REWRITE_TAC[COMPLEX_RING `w - z - v:complex = (w - v) - z`] THEN
494     MATCH_MP_TAC LIM_SUB THEN REWRITE_TAC[LIM_CONST] THEN ASM_MESON_TAC[];
495     ALL_TAC] THEN
496   MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_SUB THEN
497   ASM_SIMP_TAC[COMPLEX_DIFFERENTIABLE_AT_CLOG] THEN
498   MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_AT THEN
499   EXISTS_TAC `(ll:complex->complex->complex) z` THEN
500   EXISTS_TAC `min e (dd(z:complex))` THEN
501   ASM_SIMP_TAC[REAL_LT_MIN] THEN CONJ_TAC THENL
502    [X_GEN_TAC `w:complex` THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
503     STRIP_TAC THEN
504     MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
505     EXISTS_TAC `\n. w * clog(Cx(&n)) -
506                     vsum(1..n) (\m. clog((Cx(&m) + w) / Cx(&m)))` THEN
507     REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; LIM_SEQUENTIALLY] THEN
508     CONJ_TAC THEN X_GEN_TAC `r:real` THEN STRIP_TAC THENL
509      [REMOVE_THEN "*" (MP_TAC o SPEC `z:complex`);
510       REMOVE_THEN "*" (MP_TAC o SPEC `w:complex`)] THEN
511     ASM_SIMP_TAC[] THEN
512     REWRITE_TAC[GSYM SKOLEM_THM; RIGHT_EXISTS_IMP_THM] THEN
513     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `r:real`)) THEN
514     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
515     REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
516     ASM_SIMP_TAC[CENTRE_IN_CBALL; REAL_LT_IMP_LE] THEN
517     ASM_SIMP_TAC[IN_CBALL; REAL_LT_IMP_LE];
518     ALL_TAC] THEN
519   SUBGOAL_THEN `open {z | Im z = &0 ==> &0 < Re z}` MP_TAC THENL
520    [SUBGOAL_THEN
521      `{z | Im z = &0 ==> &0 < Re z} =
522       (:complex) DIFF ({z | Im z = &0} INTER {z | Re z <= &0})`
523      (fun th -> SIMP_TAC[th; CLOSED_HALFSPACE_RE_LE; GSYM closed;
524                       CLOSED_HALFSPACE_IM_EQ; CLOSED_INTER]) THEN
525     REWRITE_TAC[IN_ELIM_THM; IN_UNIV; IN_DIFF; IN_INTER; EXTENSION] THEN
526     REAL_ARITH_TAC;
527     REWRITE_TAC[OPEN_CONTAINS_CBALL; IN_ELIM_THM; SUBSET] THEN
528     DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN
529     DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC)] THEN
530   SUBGOAL_THEN
531    `(ll:complex->complex->complex) z continuous_on cball(z,min r (dd z)) /\
532     ll z holomorphic_on ball(z,min r (dd z))`
533   MP_TAC THENL
534    [MATCH_MP_TAC(ISPEC `sequentially` HOLOMORPHIC_UNIFORM_LIMIT) THEN
535     EXISTS_TAC `\n z. z * clog(Cx(&n)) -
536                       vsum(1..n) (\m. clog((Cx(&m) + z) / Cx(&m)))` THEN
537     ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
538     REWRITE_TAC[CBALL_MIN_INTER; IN_INTER] THEN
539     CONJ_TAC THENL [ALL_TAC; SIMP_TAC[GSYM dist] THEN ASM_MESON_TAC[]] THEN
540     EXISTS_TAC `1` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
541     MATCH_MP_TAC(MESON[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON;
542                        HOLOMORPHIC_ON_SUBSET]
543      `t SUBSET s /\ f holomorphic_on s
544       ==> f continuous_on s /\ f holomorphic_on t`) THEN
545     REWRITE_TAC[BALL_SUBSET_CBALL; GSYM CBALL_MIN_INTER] THEN
546     MATCH_MP_TAC HOLOMORPHIC_ON_SUB THEN
547     SIMP_TAC[HOLOMORPHIC_ON_MUL; HOLOMORPHIC_ON_ID;
548              HOLOMORPHIC_ON_CONST] THEN
549     MATCH_MP_TAC HOLOMORPHIC_ON_VSUM THEN
550     REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
551     X_GEN_TAC `m:num` THEN STRIP_TAC THEN
552     GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
553     MATCH_MP_TAC HOLOMORPHIC_ON_COMPOSE THEN
554     SIMP_TAC[HOLOMORPHIC_ON_ADD; HOLOMORPHIC_ON_ID;
555              HOLOMORPHIC_ON_CONST; complex_div; HOLOMORPHIC_ON_MUL] THEN
556     MATCH_MP_TAC HOLOMORPHIC_ON_CLOG THEN
557     REWRITE_TAC[FORALL_IN_IMAGE; GSYM complex_div; IMP_CONJ] THEN
558     ASM_SIMP_TAC[RE_DIV_CX; IM_DIV_CX; REAL_DIV_EQ_0; RE_ADD; IM_ADD] THEN
559     X_GEN_TAC `w:complex` THEN DISCH_TAC THEN
560     ASM_SIMP_TAC[REAL_LT_IMP_NZ; REAL_OF_NUM_LT; LE_1] THEN
561     REWRITE_TAC[IM_CX; RE_CX; REAL_ADD_LID] THEN DISCH_TAC THEN
562     MATCH_MP_TAC REAL_LT_DIV THEN
563     ASM_SIMP_TAC[REAL_LT_IMP_NZ; REAL_OF_NUM_LT; LE_1] THEN
564     MATCH_MP_TAC(REAL_ARITH `&0 < x ==> &0 < &m + x`) THEN
565     RULE_ASSUM_TAC(REWRITE_RULE[CBALL_MIN_INTER; IN_INTER]) THEN
566     ASM_MESON_TAC[];
567     SIMP_TAC[HOLOMORPHIC_ON_OPEN; OPEN_BALL; complex_differentiable] THEN
568     DISCH_THEN(MATCH_MP_TAC o CONJUNCT2) THEN
569     ASM_SIMP_TAC[CENTRE_IN_BALL; REAL_LT_MIN]]);;
570
571 let LGAMMA_ALT = prove
572  (`!z. (!n. ~(z + Cx(&n) = Cx(&0)))
573         ==> ((\n. (z * clog(Cx(&n)) + clog(Cx(&(FACT n)))) -
574                   vsum(0..n) (\m. clog(Cx(&m) + z)))
575              --> lgamma(z)) sequentially`,
576   REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP LGAMMA) THEN
577   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM) THEN
578   MATCH_MP_TAC LIM_EVENTUALLY THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
579   EXISTS_TAC `1` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
580   SIMP_TAC[VECTOR_SUB_EQ; VSUM_CLAUSES_LEFT; LE_0; COMPLEX_ADD_LID] THEN
581   MATCH_MP_TAC(COMPLEX_RING
582    `a:complex = d - c ==> x - y - a = (x + c) - (y + d)`) THEN
583   REWRITE_TAC[GSYM NPRODUCT_FACT; ADD_CLAUSES] THEN
584   SIMP_TAC[REAL_OF_NUM_NPRODUCT; FINITE_NUMSEG; GSYM CX_LOG; LOG_PRODUCT;
585            PRODUCT_POS_LT; IN_NUMSEG; REAL_OF_NUM_LT; LE_1; GSYM VSUM_CX] THEN
586   REWRITE_TAC[GSYM VSUM_SUB_NUMSEG] THEN MATCH_MP_TAC VSUM_EQ_NUMSEG THEN
587   REWRITE_TAC[complex_div] THEN ONCE_REWRITE_TAC[COMPLEX_ADD_SYM] THEN
588   ASM_SIMP_TAC[CLOG_MUL_CX; REAL_LT_INV_EQ; REAL_OF_NUM_LT; LE_1;
589                GSYM CX_INV; LOG_INV; CX_NEG; GSYM complex_sub]);;
590
591 let LGAMMA_ALT2 = prove
592  (`!z. (!n. ~(z + Cx(&n) = Cx(&0)))
593         ==> ((\n. vsum(1..n) (\m. z * clog(Cx(&1) + Cx(&1) / Cx(&m)) -
594                                   clog(Cx(&1) + z / Cx(&m))) -
595                   clog(z))
596              --> lgamma(z)) sequentially`,
597   REPEAT STRIP_TAC THEN
598   SIMP_TAC[CX_INJ; REAL_OF_NUM_EQ; LE_1;
599    COMPLEX_FIELD `~(m = Cx(&0)) ==> Cx(&1) + z / m = (z + m) / m`] THEN
600   REWRITE_TAC[GSYM CX_ADD; GSYM CX_DIV] THEN
601   SIMP_TAC[GSYM CX_LOG; LOG_DIV; REAL_LT_DIV; REAL_ARITH `&0 < &1 + &m`;
602            REAL_OF_NUM_LT; LE_1] THEN
603   SIMP_TAC[VSUM_SUB_NUMSEG; VSUM_COMPLEX_LMUL; FINITE_NUMSEG] THEN
604   REWRITE_TAC[CX_SUB; REAL_OF_NUM_ADD; ARITH_RULE `1 + m = m + 1`] THEN
605   REWRITE_TAC[VSUM_DIFFS_ALT; LOG_1; COMPLEX_SUB_RZERO] THEN
606   FIRST_ASSUM(MP_TAC o MATCH_MP LGAMMA) THEN
607   DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
608     LIM_SUBSEQUENCE)) THEN
609   DISCH_THEN(MP_TAC o SPEC `\r. r + 1`) THEN
610   REWRITE_TAC[] THEN ANTS_TAC THENL [ARITH_TAC; ALL_TAC] THEN
611   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM) THEN
612   REWRITE_TAC[o_DEF] THEN
613   MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
614   EXISTS_TAC `\n. --clog((Cx(&(n + 1)) + z) / Cx(&(n + 1)))` THEN
615   CONJ_TAC THENL
616    [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
617     X_GEN_TAC `n:num` THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
618     REWRITE_TAC[GSYM ADD1; VSUM_CLAUSES_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN
619     REWRITE_TAC[COMPLEX_RING `Cx(&n) + z = z + Cx(&n)`] THEN
620     SIMP_TAC[CX_LOG; REAL_OF_NUM_LT; LT_0] THEN
621     CONV_TAC COMPLEX_RING;
622     REWRITE_TAC[COMPLEX_VEC_0] THEN MATCH_MP_TAC LIM_NULL_COMPLEX_NEG THEN
623     SIMP_TAC[REAL_OF_NUM_EQ; CX_INJ; ARITH_EQ; ADD_EQ_0;
624       COMPLEX_FIELD `~(y = Cx(&0)) ==> (y + z) / y = Cx(&1) + z / y`] THEN
625     SUBGOAL_THEN `Cx(&0) = clog (Cx (&1) + Cx(&0))` SUBST1_TAC THENL
626      [REWRITE_TAC[COMPLEX_ADD_RID; CLOG_1]; ALL_TAC] THEN
627     MP_TAC(ISPECL [`\z. clog(Cx(&1) + z)`; `sequentially`]
628         LIM_CONTINUOUS_FUNCTION) THEN
629     REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL
630      [MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_AT THEN
631       COMPLEX_DIFFERENTIABLE_TAC THEN REWRITE_TAC[RE_ADD; RE_CX] THEN
632       REWRITE_TAC[REAL_ADD_RID; REAL_LT_01];
633       REWRITE_TAC[complex_div] THEN MATCH_MP_TAC LIM_NULL_COMPLEX_LMUL THEN
634       MATCH_MP_TAC(REWRITE_RULE[o_DEF]
635         (ISPECL [`f:num->complex`; `\n. n + 1`] LIM_SUBSEQUENCE)) THEN
636       CONJ_TAC THENL [ARITH_TAC; ALL_TAC] THEN
637       REWRITE_TAC[GSYM CX_INV; REWRITE_RULE[o_DEF] (GSYM REALLIM_COMPLEX)] THEN
638       REWRITE_TAC[REALLIM_1_OVER_N]]]);;
639
640 (* ------------------------------------------------------------------------- *)
641 (* The complex gamma function (defined using the Gauss/Euler product).       *)
642 (* Note that this totalizes it with the value zero at the poles.             *)
643 (* ------------------------------------------------------------------------- *)
644
645 let cgamma = new_definition
646  `cgamma(z) = lim sequentially (\n. (Cx(&n) cpow z * Cx(&(FACT n))) /
647                                     cproduct(0..n) (\m. z + Cx(&m)))`;;
648
649 let [CGAMMA;CGAMMA_EQ_0;CGAMMA_LGAMMA] = (CONJUNCTS o prove)
650  (`(!z. ((\n. (Cx(&n) cpow z * Cx(&(FACT n))) / cproduct(0..n) (\m. z + Cx(&m)))
651          --> cgamma(z)) sequentially) /\
652    (!z. cgamma(z) = Cx(&0) <=> ?n. z + Cx(&n) = Cx(&0)) /\
653    (!z. cgamma(z) = if ?n. z + Cx(&n) = Cx(&0) then Cx(&0)
654                     else cexp(lgamma z))`,
655   REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `y:complex` THEN
656   ASM_CASES_TAC `?n. y + Cx(&n) = Cx(&0)` THENL
657    [ASM_REWRITE_TAC[GSYM NOT_EXISTS_THM] THEN
658     FIRST_X_ASSUM(X_CHOOSE_TAC `N:num`) THEN
659     REWRITE_TAC[cgamma; lim] THEN MATCH_MP_TAC(MESON[LIM_UNIQUE]
660      `~trivial_limit net /\ (f --> a) net
661       ==> (f --> @a. (f --> a) net) net /\ (@a. (f --> a) net) = a`) THEN
662     REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
663     MATCH_MP_TAC LIM_EVENTUALLY THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
664     EXISTS_TAC `N:num` THEN X_GEN_TAC `n:num` THEN REWRITE_TAC[GE] THEN
665     DISCH_TAC THEN
666     SIMP_TAC[COMPLEX_ENTIRE; COMPLEX_DIV_EQ_0; CPRODUCT_EQ_0; FINITE_NUMSEG;
667              IN_NUMSEG; LE_0] THEN
668     ASM_MESON_TAC[LE_REFL];
669     ASM_REWRITE_TAC[] THEN RULE_ASSUM_TAC(REWRITE_RULE[NOT_EXISTS_THM])] THEN
670   SUBGOAL_THEN
671    `((\n. (Cx(&n) cpow y * Cx(&(FACT n))) / cproduct(0..n) (\m. y + Cx(&m)))
672      --> cexp(lgamma y)) sequentially`
673   ASSUME_TAC THENL
674    [MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
675     EXISTS_TAC `\n. cexp(y * clog(Cx(&n)) - clog y -
676                          vsum(1..n) (\m. clog((Cx(&m) + y) / Cx(&m))))` THEN
677     CONJ_TAC THENL
678      [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
679       X_GEN_TAC `n:num` THEN DISCH_TAC THEN
680       ASM_SIMP_TAC[CEXP_SUB; cpow; CX_INJ; REAL_OF_NUM_EQ; LE_1] THEN
681       REWRITE_TAC[complex_div; GSYM COMPLEX_MUL_ASSOC] THEN AP_TERM_TAC THEN
682       SIMP_TAC[GSYM NPRODUCT_FACT; REAL_OF_NUM_NPRODUCT; FINITE_NUMSEG] THEN
683       SIMP_TAC[CX_PRODUCT; FINITE_NUMSEG; GSYM CPRODUCT_INV] THEN
684       SIMP_TAC[CPRODUCT_CLAUSES_LEFT; LE_0] THEN
685       GEN_REWRITE_TAC RAND_CONV [COMPLEX_RING
686        `a * b * c:complex = b * a * c`] THEN
687       REWRITE_TAC[COMPLEX_ADD_RID] THEN BINOP_TAC THENL
688        [ASM_MESON_TAC[COMPLEX_ADD_RID; CEXP_CLOG]; ALL_TAC] THEN
689       SIMP_TAC[ADD_CLAUSES; GSYM CPRODUCT_MUL; FINITE_NUMSEG] THEN
690       REWRITE_TAC[GSYM CEXP_NEG; GSYM VSUM_NEG] THEN
691       SIMP_TAC[CEXP_VSUM; FINITE_NUMSEG] THEN MATCH_MP_TAC CPRODUCT_EQ THEN
692       REWRITE_TAC[IN_NUMSEG] THEN X_GEN_TAC `m:num` THEN STRIP_TAC THEN
693       REWRITE_TAC[CEXP_NEG] THEN
694       GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [GSYM COMPLEX_INV_INV] THEN
695       REWRITE_TAC[GSYM COMPLEX_INV_MUL] THEN AP_TERM_TAC THEN
696       GEN_REWRITE_TAC RAND_CONV [COMPLEX_MUL_SYM] THEN
697       GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [COMPLEX_ADD_SYM] THEN
698       MATCH_MP_TAC CEXP_CLOG THEN
699       ONCE_REWRITE_TAC[COMPLEX_ADD_SYM] THEN
700       ASM_REWRITE_TAC[COMPLEX_ENTIRE; COMPLEX_INV_EQ_0] THEN
701       REWRITE_TAC[CX_INJ; REAL_OF_NUM_EQ] THEN ASM_ARITH_TAC;
702       MATCH_MP_TAC(ISPEC `cexp` LIM_CONTINUOUS_FUNCTION) THEN
703       ASM_SIMP_TAC[LGAMMA; CONTINUOUS_AT_CEXP]];
704     MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
705      [REWRITE_TAC[cgamma; lim] THEN CONV_TAC SELECT_CONV THEN ASM_MESON_TAC[];
706       DISCH_TAC] THEN
707     MATCH_MP_TAC(TAUT `q /\ (q ==> p) ==> p /\ q`) THEN CONJ_TAC THENL
708      [MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
709       ASM_MESON_TAC[TRIVIAL_LIMIT_SEQUENTIALLY];
710       SIMP_TAC[CEXP_NZ]]]);;
711
712 let CGAMMA_RECURRENCE_ALT = prove
713  (`!z. cgamma(z) = cgamma(z + Cx(&1)) / z`,
714   GEN_TAC THEN ASM_CASES_TAC `?n.  z + Cx(&n) = Cx(&0)` THENL
715    [FIRST_ASSUM(fun th -> REWRITE_TAC[REWRITE_RULE[GSYM CGAMMA_EQ_0] th]) THEN
716     CONV_TAC SYM_CONV THEN REWRITE_TAC[COMPLEX_DIV_EQ_0] THEN
717     ASM_CASES_TAC `z = Cx(&0)` THEN ASM_REWRITE_TAC[] THEN
718     FIRST_X_ASSUM(MP_TAC o check (is_exists o concl)) THEN
719     REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN INDUCT_TAC THEN
720     ASM_REWRITE_TAC[COMPLEX_ADD_RID; CGAMMA_EQ_0] THEN
721     REWRITE_TAC[GSYM COMPLEX_ADD_ASSOC; GSYM CX_ADD; REAL_OF_NUM_ADD] THEN
722     MESON_TAC[ADD1; ADD_SYM];
723     RULE_ASSUM_TAC(REWRITE_RULE[NOT_EXISTS_THM])] THEN
724   SUBGOAL_THEN `!n. ~((z + Cx(&1)) + Cx(&n) = Cx(&0))` ASSUME_TAC THENL
725    [REWRITE_TAC[GSYM COMPLEX_ADD_ASSOC; GSYM CX_ADD; REAL_OF_NUM_ADD] THEN
726     ASM_MESON_TAC[];
727     ALL_TAC] THEN
728   SUBGOAL_THEN `~(z = Cx(&0))` ASSUME_TAC THENL
729    [ASM_MESON_TAC[COMPLEX_ADD_LID]; ALL_TAC] THEN
730   MATCH_MP_TAC(COMPLEX_FIELD
731    `(a * b) / c = Cx(&1) /\ ~(a = Cx(&0)) /\ ~(c = Cx(&0)) ==> b = c / a`) THEN
732   ASM_REWRITE_TAC[CGAMMA_EQ_0] THEN
733   MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
734   EXISTS_TAC
735    `\n. (z * (Cx(&(n + 1)) cpow z * Cx(&(FACT(n + 1)))) /
736              cproduct(0..n+1) (\m. z + Cx(&m))) /
737         ((Cx(&n) cpow (z + Cx(&1)) * Cx(&(FACT n))) /
738          cproduct(0..n) (\m. (z + Cx(&1)) + Cx(&m)))` THEN
739   REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN CONJ_TAC THENL
740    [MATCH_MP_TAC LIM_COMPLEX_DIV THEN
741     ASM_REWRITE_TAC[CGAMMA; CGAMMA_EQ_0] THEN
742     MATCH_MP_TAC LIM_COMPLEX_LMUL THEN
743     MP_TAC(SPEC `z:complex` CGAMMA) THEN
744     DISCH_THEN(MP_TAC o SPEC `1` o MATCH_MP SEQ_OFFSET) THEN
745     REWRITE_TAC[];
746     ALL_TAC] THEN
747   REWRITE_TAC[GSYM COMPLEX_ADD_ASSOC; GSYM CX_ADD; REAL_OF_NUM_ADD] THEN
748   REWRITE_TAC[ARITH_RULE `1 + n = n + 1`] THEN
749   SIMP_TAC[SYM(ISPECL [`f:num->complex`; `m:num`; `1`] CPRODUCT_OFFSET)] THEN
750   SIMP_TAC[CPRODUCT_CLAUSES_LEFT; LE_0; ADD_CLAUSES] THEN
751   REWRITE_TAC[GSYM ADD1; FACT; CX_MUL; COMPLEX_MUL_ASSOC; GSYM REAL_OF_NUM_MUL;
752           ONCE_REWRITE_RULE[COMPLEX_MUL_SYM] (GSYM CPOW_SUC)] THEN
753   REWRITE_TAC[complex_div; COMPLEX_INV_MUL; COMPLEX_INV_INV] THEN
754   REWRITE_TAC[COMPLEX_ADD_RID; GSYM COMPLEX_MUL_ASSOC] THEN
755   REWRITE_TAC[COMPLEX_RING
756    `a * b * c * d * e * f * g * h:complex =
757     (a * d) * (c * g) * (h * e) * (b * f)`] THEN
758   ASM_SIMP_TAC[GSYM complex_div; COMPLEX_DIV_REFL; CX_INJ;
759                REAL_OF_NUM_EQ; FACT_NZ; COMPLEX_MUL_LID] THEN
760   GEN_REWRITE_TAC LAND_CONV [GSYM COMPLEX_MUL_LID] THEN
761   MATCH_MP_TAC LIM_COMPLEX_MUL THEN CONJ_TAC THENL
762    [MATCH_MP_TAC LIM_EVENTUALLY THEN MATCH_MP_TAC ALWAYS_EVENTUALLY THEN
763     X_GEN_TAC `n:num` THEN REWRITE_TAC[] THEN
764     MATCH_MP_TAC COMPLEX_DIV_REFL THEN
765     SIMP_TAC[CPRODUCT_EQ_0; FINITE_NUMSEG] THEN ASM_MESON_TAC[];
766     ALL_TAC] THEN
767   MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
768   EXISTS_TAC `\n. cexp((z + Cx(&1)) * clog(Cx(&1) + inv(Cx(&n))))` THEN
769   CONJ_TAC THENL
770    [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
771     SIMP_TAC[cpow; CX_INJ; REAL_OF_NUM_EQ; NOT_SUC; LE_1] THEN
772     REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CEXP_SUB] THEN AP_TERM_TAC THEN
773     REWRITE_TAC[GSYM COMPLEX_SUB_LDISTRIB] THEN AP_TERM_TAC THEN
774     ASM_SIMP_TAC[CX_INJ; REAL_OF_NUM_EQ; LE_1; COMPLEX_FIELD
775      `~(n = Cx(&0)) ==> Cx(&1) + inv n = (n + Cx(&1)) / n`] THEN
776     REWRITE_TAC[GSYM REAL_OF_NUM_SUC; GSYM CX_ADD] THEN
777     ASM_SIMP_TAC[REAL_OF_NUM_ADD; GSYM CX_DIV; GSYM CX_LOG; LE_1; LOG_DIV;
778                  REAL_OF_NUM_LT; REAL_LT_DIV; ARITH_RULE `0 < n + 1`] THEN
779     REWRITE_TAC[CX_SUB];
780     ALL_TAC] THEN
781   GEN_REWRITE_TAC LAND_CONV [GSYM CEXP_0] THEN
782   MATCH_MP_TAC(ISPEC `cexp` LIM_CONTINUOUS_FUNCTION) THEN
783   REWRITE_TAC[CONTINUOUS_AT_CEXP] THEN
784   MATCH_MP_TAC LIM_NULL_COMPLEX_LMUL THEN
785   MATCH_MP_TAC LIM_NULL_COMPARISON_COMPLEX THEN
786   EXISTS_TAC `\n. Cx(&2) * inv(Cx(&n))` THEN
787   SIMP_TAC[LIM_INV_N; LIM_NULL_COMPLEX_LMUL] THEN
788   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `2` THEN
789   REWRITE_TAC[GE; IN_FROM] THEN X_GEN_TAC `n:num` THEN STRIP_TAC THEN
790   MP_TAC(ISPECL [`0`; `Cx(inv(&n))`] TAYLOR_CLOG) THEN
791   SIMP_TAC[VSUM_CLAUSES_NUMSEG; ARITH; VECTOR_SUB_RZERO] THEN
792   REWRITE_TAC[REAL_POW_1; GSYM CX_ADD; COMPLEX_NORM_CX] THEN
793   REWRITE_TAC[REAL_ABS_INV; REAL_ABS_NUM] THEN ANTS_TAC THENL
794    [MATCH_MP_TAC REAL_INV_LT_1 THEN REWRITE_TAC[REAL_OF_NUM_LT] THEN
795     ASM_ARITH_TAC;
796     REWRITE_TAC[CX_ADD; CX_INV]] THEN
797   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
798   ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN
799   REWRITE_TAC[real_div; COMPLEX_NORM_MUL] THEN
800   REWRITE_TAC[COMPLEX_NORM_INV; COMPLEX_NORM_CX; REAL_ABS_NUM] THEN
801   MATCH_MP_TAC REAL_LE_LMUL THEN
802   REWRITE_TAC[REAL_LE_INV_EQ; REAL_POS] THEN
803   GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN
804   MATCH_MP_TAC REAL_LE_INV2 THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
805   REWRITE_TAC[REAL_ARITH `&1 / &2 <= &1 - x <=> x <= inv(&2)`] THEN
806   REWRITE_TAC[real_div; REAL_MUL_LID] THEN
807   MATCH_MP_TAC REAL_LE_INV2 THEN
808   REWRITE_TAC[REAL_OF_NUM_LT; REAL_OF_NUM_LE] THEN ASM_ARITH_TAC);;
809
810 let CGAMMA_1 = prove
811  (`cgamma(Cx(&1)) = Cx(&1)`,
812   MP_TAC(SPEC `Cx(&1)` CGAMMA) THEN
813   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT; TRIVIAL_LIMIT_SEQUENTIALLY]
814      (ISPEC `sequentially` LIM_UNIQUE)) THEN
815   REWRITE_TAC[GSYM CX_ADD; REAL_OF_NUM_ADD; ARITH_RULE `1 + n = n + 1`] THEN
816   SIMP_TAC[SYM(ISPECL [`f:num->complex`; `m:num`; `1`] CPRODUCT_OFFSET)] THEN
817   MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
818   EXISTS_TAC `\n. Cx(&n / (&n + &1))` THEN CONJ_TAC THENL
819    [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
820     X_GEN_TAC `n:num` THEN DISCH_TAC THEN REWRITE_TAC[CX_DIV] THEN
821     ASM_SIMP_TAC[CPOW_N; CX_INJ; REAL_OF_NUM_EQ; LE_1; COMPLEX_POW_1] THEN
822     REWRITE_TAC[complex_div; GSYM COMPLEX_MUL_ASSOC] THEN AP_TERM_TAC THEN
823     ONCE_REWRITE_TAC [GSYM COMPLEX_INV_INV] THEN
824     AP_TERM_TAC THEN REWRITE_TAC[COMPLEX_INV_INV; COMPLEX_INV_MUL] THEN
825     MATCH_MP_TAC(COMPLEX_FIELD
826      `a * b = c /\ ~(b = Cx(&0)) ==> a = inv b * c`) THEN
827     REWRITE_TAC[GSYM CX_MUL; CX_INJ; REAL_OF_NUM_EQ; FACT_NZ] THEN
828     REWRITE_TAC[REAL_OF_NUM_SUC; REAL_OF_NUM_MUL; GSYM(CONJUNCT2 FACT)] THEN
829     REWRITE_TAC[ADD_CLAUSES; ADD1] THEN SPEC_TAC(`n + 1`,`m:num`) THEN
830     INDUCT_TAC THEN REWRITE_TAC[FACT; CPRODUCT_CLAUSES_NUMSEG; ARITH] THEN
831     ASM_REWRITE_TAC[CX_MUL; GSYM REAL_OF_NUM_MUL] THEN
832     REWRITE_TAC[ARITH_RULE `1 <= SUC n`; COMPLEX_MUL_SYM];
833     ALL_TAC] THEN
834   SIMP_TAC[REAL_FIELD `&n / (&n + &1) = &1 - inv(&n + &1)`] THEN
835   SUBST1_TAC(COMPLEX_RING `Cx(&1) = Cx(&1) - Cx(&0)`) THEN
836   REWRITE_TAC[CX_SUB] THEN MATCH_MP_TAC LIM_SUB THEN
837   REWRITE_TAC[LIM_CONST; REAL_OF_NUM_ADD] THEN
838   MATCH_MP_TAC(ISPECL [`f:num->complex`; `l:complex`; `1`] SEQ_OFFSET) THEN
839   REWRITE_TAC[CX_INV; LIM_INV_N]);;
840
841 let CGAMMA_RECURRENCE = prove
842  (`!z. cgamma(z + Cx(&1)) = if z = Cx(&0) then Cx(&1) else z * cgamma(z)`,
843   GEN_TAC THEN COND_CASES_TAC THEN
844   ASM_REWRITE_TAC[COMPLEX_ADD_LID; CGAMMA_1] THEN
845   MATCH_MP_TAC(COMPLEX_FIELD `a = b / c /\ ~(c = Cx(&0)) ==> b = c * a`) THEN
846   ASM_MESON_TAC[CGAMMA_RECURRENCE_ALT]);;
847
848 let CGAMMA_FACT = prove
849  (`!n. cgamma(Cx(&(n + 1))) = Cx(&(FACT n))`,
850   INDUCT_TAC THEN REWRITE_TAC[FACT; ADD_CLAUSES; CGAMMA_1] THEN
851   REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN REWRITE_TAC[CX_ADD] THEN
852   REWRITE_TAC[CGAMMA_RECURRENCE; CX_INJ; REAL_OF_NUM_EQ; ADD_EQ_0; ARITH] THEN
853   ASM_REWRITE_TAC[ADD1; GSYM REAL_OF_NUM_MUL; CX_MUL]);;
854
855 let CGAMMA_POLES = prove
856  (`!n. cgamma(--(Cx(&n))) = Cx(&0)`,
857   REWRITE_TAC[CGAMMA_EQ_0] THEN MESON_TAC[COMPLEX_ADD_LINV]);;
858
859 let COMPLEX_DIFFERENTIABLE_AT_CGAMMA = prove
860  (`!z. (!n. ~(z + Cx(&n) = Cx(&0))) ==> cgamma complex_differentiable at z`,
861   let lemma = prove
862    (`!z. (!n. ~(z + Cx(&n) = Cx(&0))) /\
863          cgamma complex_differentiable at (z + Cx(&1))
864          ==> cgamma complex_differentiable at z`,
865     REPEAT STRIP_TAC THEN
866     MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_AT THEN
867     MAP_EVERY EXISTS_TAC [`\z. cgamma(z + Cx(&1)) / z`; `&1`] THEN
868     REWRITE_TAC[REAL_LT_01] THEN
869     CONJ_TAC THENL [REWRITE_TAC[GSYM CGAMMA_RECURRENCE_ALT]; ALL_TAC] THEN
870     MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_DIV_AT THEN
871     REWRITE_TAC[COMPLEX_DIFFERENTIABLE_ID] THEN
872     CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[COMPLEX_ADD_RID]] THEN
873     GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
874     MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_COMPOSE_AT THEN
875     ASM_REWRITE_TAC[] THEN COMPLEX_DIFFERENTIABLE_TAC) in
876   REPEAT STRIP_TAC THEN MP_TAC(SPEC `abs(Re z) + &1` REAL_ARCH_SIMPLE) THEN
877   DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
878   SUBGOAL_THEN
879    `!n. n <= N ==> cgamma complex_differentiable (at (z + Cx(&N) - Cx(&n)))`
880   MP_TAC THENL
881    [ALL_TAC; MESON_TAC[LE_REFL; COMPLEX_SUB_REFL; COMPLEX_ADD_RID]] THEN
882   INDUCT_TAC THENL
883    [DISCH_TAC THEN REWRITE_TAC[COMPLEX_SUB_RZERO] THEN
884     MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_AT THEN
885     EXISTS_TAC `\z. cexp(lgamma z)` THEN
886     SUBGOAL_THEN `open {z | !n. ~(z + Cx(&n) = Cx(&0))}` MP_TAC THENL
887      [REWRITE_TAC[SET_RULE `{z | !n. P n z} = UNIV DIFF {z | ?n. ~P n z}`] THEN
888       REWRITE_TAC[GSYM closed] THEN MATCH_MP_TAC DISCRETE_IMP_CLOSED THEN
889       EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01; IMP_CONJ] THEN
890       REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
891       SIMP_TAC[COMPLEX_RING `x + y = Cx(&0) <=> x = --y`] THEN
892       REWRITE_TAC[COMPLEX_RING `--x - --y:complex = y - x`] THEN
893       REWRITE_TAC[COMPLEX_EQ_NEG2; CX_INJ; GSYM CX_SUB; COMPLEX_NORM_CX] THEN
894       SIMP_TAC[GSYM REAL_EQ_INTEGERS; INTEGER_CLOSED];
895       REWRITE_TAC[open_def; IN_ELIM_THM] THEN
896       DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN ASM_REWRITE_TAC[] THEN
897       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN
898       STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
899        [X_GEN_TAC `w:complex` THEN REWRITE_TAC[dist] THEN DISCH_TAC THEN
900         FIRST_X_ASSUM(MP_TAC o SPEC `w - Cx(&N)`) THEN
901         ASM_SIMP_TAC[dist; COMPLEX_RING `w - n - z:complex = w - (z + n)`] THEN
902         REWRITE_TAC[CGAMMA_LGAMMA] THEN COND_CASES_TAC THEN REWRITE_TAC[] THEN
903         FIRST_X_ASSUM(X_CHOOSE_TAC `n:num`) THEN
904         DISCH_THEN(MP_TAC o SPEC `n + N:num`) THEN
905         REWRITE_TAC[GSYM REAL_OF_NUM_ADD; CX_ADD] THEN
906         ASM_REWRITE_TAC[COMPLEX_RING `w - N + n + N:complex = w + n`];
907         GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
908         MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_COMPOSE_AT THEN
909         REWRITE_TAC[COMPLEX_DIFFERENTIABLE_AT_CEXP] THEN
910         MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_AT_LGAMMA THEN
911         REWRITE_TAC[RE_ADD; RE_CX] THEN ASM_REAL_ARITH_TAC]];
912     DISCH_TAC THEN REWRITE_TAC[GSYM REAL_OF_NUM_SUC; CX_ADD] THEN
913     MATCH_MP_TAC lemma THEN
914     REWRITE_TAC[COMPLEX_RING `(z + N - (n + w)) + w:complex = z + N - n`] THEN
915     CONJ_TAC THENL
916      [ALL_TAC; FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC] THEN
917     X_GEN_TAC `m:num` THEN
918     FIRST_X_ASSUM(MP_TAC o SPEC `(N + m) - (n + 1)`) THEN
919     SUBGOAL_THEN `n + 1 <= N + m`
920       (fun th -> SIMP_TAC[th; GSYM REAL_OF_NUM_SUB])
921     THENL [ASM_ARITH_TAC; ALL_TAC] THEN
922     REWRITE_TAC[GSYM REAL_OF_NUM_ADD; CX_ADD; CX_SUB] THEN
923     CONV_TAC COMPLEX_RING]);;
924
925 let COMPLEX_DIFFERENTIABLE_WITHIN_CGAMMA = prove
926  (`!z s. (!n. ~(z + Cx(&n) = Cx(&0)))
927          ==> cgamma complex_differentiable at z within s`,
928   SIMP_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN;
929            COMPLEX_DIFFERENTIABLE_AT_CGAMMA]);;
930
931 let HOLOMORPHIC_ON_CGAMMA = prove
932  (`!s. s SUBSET {z | !n. ~(z + Cx(&n) = Cx(&0))}
933        ==> cgamma holomorphic_on s`,
934   REPEAT STRIP_TAC THEN REWRITE_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE] THEN
935   REPEAT STRIP_TAC THEN MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_WITHIN_CGAMMA THEN
936   ASM SET_TAC[]);;
937
938 let CONTINUOUS_AT_CGAMMA = prove
939  (`!z. (!n. ~(z + Cx(&n) = Cx(&0))) ==> cgamma continuous at z`,
940   SIMP_TAC[COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_AT;
941            COMPLEX_DIFFERENTIABLE_AT_CGAMMA]);;
942
943 let CONTINUOUS_WITHIN_CGAMMA = prove
944  (`!z s. (!n. ~(z + Cx(&n) = Cx(&0)))
945          ==> cgamma continuous at z within s`,
946   SIMP_TAC[COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN;
947            COMPLEX_DIFFERENTIABLE_WITHIN_CGAMMA]);;
948
949 let CONTINUOUS_ON_CGAMMA = prove
950  (`!s. s SUBSET {z | !n. ~(z + Cx(&n) = Cx(&0))}
951        ==> cgamma continuous_on s`,
952   SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; HOLOMORPHIC_ON_CGAMMA]);;
953
954 let CGAMMA_SIMPLE_POLES = prove
955  (`!n. ((\z. (z + Cx(&n)) * cgamma z) --> --Cx(&1) pow n / Cx(&(FACT n)))
956        (at(--Cx(&n)))`,
957   INDUCT_TAC THENL
958    [REWRITE_TAC[COMPLEX_ADD_RID; COMPLEX_NEG_0; FACT; complex_pow;
959                 COMPLEX_DIV_1] THEN
960     ONCE_REWRITE_TAC[CGAMMA_RECURRENCE_ALT] THEN
961     MATCH_MP_TAC LIM_TRANSFORM_AWAY_AT THEN
962     MAP_EVERY EXISTS_TAC [`\z. cgamma(z + Cx(&1))`; `Cx(&1)`] THEN
963     REWRITE_TAC[CONJ_ASSOC] THEN
964     CONJ_TAC THENL [CONV_TAC COMPLEX_FIELD; ALL_TAC] THEN
965     SUBGOAL_THEN `(\z. cgamma (z + Cx(&1))) continuous at (Cx(&0))`
966     MP_TAC THENL
967      [GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
968       MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN
969       CONJ_TAC THENL [CONTINUOUS_TAC; ALL_TAC] THEN
970       MATCH_MP_TAC CONTINUOUS_AT_CGAMMA THEN
971       REWRITE_TAC[GSYM CX_ADD; CX_INJ] THEN REAL_ARITH_TAC;
972       REWRITE_TAC[CONTINUOUS_AT; COMPLEX_ADD_LID; CGAMMA_1]];
973     REWRITE_TAC[FACT; CX_MUL; GSYM REAL_OF_NUM_MUL] THEN
974     ONCE_REWRITE_TAC[CGAMMA_RECURRENCE_ALT] THEN
975     REWRITE_TAC[complex_div; complex_pow; COMPLEX_INV_MUL] THEN
976     REWRITE_TAC[SIMPLE_COMPLEX_ARITH
977      `(--Cx(&1) * p) * is * i = (p * i) * --is`] THEN
978     REWRITE_TAC[COMPLEX_MUL_ASSOC] THEN MATCH_MP_TAC LIM_COMPLEX_MUL THEN
979     CONJ_TAC THENL
980      [FIRST_X_ASSUM(MP_TAC o
981         ISPECL [`at (--Cx(&(SUC n)))`; `\z.  z + Cx(&1)`] o
982         MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT]
983          (REWRITE_RULE[CONJ_ASSOC] LIM_COMPOSE_AT))) THEN
984       REWRITE_TAC[o_DEF; GSYM REAL_OF_NUM_SUC; CX_ADD] THEN
985       REWRITE_TAC[COMPLEX_RING `(z + Cx(&1)) + w = z + (w + Cx(&1))`] THEN
986       REWRITE_TAC[GSYM complex_div] THEN DISCH_THEN MATCH_MP_TAC THEN
987       CONJ_TAC THENL
988        [LIM_TAC THEN CONV_TAC COMPLEX_RING;
989         REWRITE_TAC[EVENTUALLY_AT; GSYM DIST_NZ] THEN
990         EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
991         CONV_TAC COMPLEX_RING];
992       REWRITE_TAC[COMPLEX_NEG_INV; GSYM CONTINUOUS_AT] THEN
993       GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN
994       MATCH_MP_TAC CONTINUOUS_COMPLEX_INV_AT THEN
995       REWRITE_TAC[GSYM CX_NEG; CX_INJ; GSYM REAL_OF_NUM_SUC] THEN
996       REWRITE_TAC[CONTINUOUS_AT_ID] THEN REAL_ARITH_TAC]]);;
997
998 let CNJ_CGAMMA = prove
999  (`!z. cnj(cgamma z) = cgamma(cnj z)`,
1000   GEN_TAC THEN MP_TAC(SPEC `cnj z` CGAMMA) THEN
1001   MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
1002         LIM_UNIQUE) THEN
1003   REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
1004   GEN_REWRITE_TAC I [GSYM LIM_CNJ] THEN REWRITE_TAC[CNJ_CNJ] THEN
1005   MP_TAC(SPEC `z:complex` CGAMMA) THEN
1006   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
1007   SIMP_TAC[CNJ_DIV; CNJ_MUL; CNJ_CX; CNJ_CPRODUCT; FINITE_NUMSEG] THEN
1008   REWRITE_TAC[CNJ_ADD; CNJ_CNJ; CNJ_CX] THEN
1009   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
1010   X_GEN_TAC `n:num` THEN REWRITE_TAC[cpow; CNJ_EQ_0] THEN
1011   DISCH_TAC THEN COND_CASES_TAC THEN REWRITE_TAC[CNJ_CX; CNJ_CEXP] THEN
1012   REWRITE_TAC[CNJ_MUL; CNJ_CNJ] THEN
1013   ASM_SIMP_TAC[CNJ_CLOG; RE_CX; REAL_OF_NUM_LT; LE_1; CNJ_CX]);;
1014
1015 let REAL_GAMMA = prove
1016  (`!z. real z ==> real(cgamma z)`,
1017   SIMP_TAC[REAL_CNJ; CNJ_CGAMMA]);;
1018
1019 let RE_POS_CGAMMA_REAL = prove
1020  (`!z. real z /\ &0 <= Re z ==> &0 <= Re(cgamma z)`,
1021   REWRITE_TAC[REAL_EXISTS; LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN
1022   GEN_TAC THEN X_GEN_TAC `x:real` THEN DISCH_THEN SUBST1_TAC THEN
1023   REWRITE_TAC[RE_CX] THEN DISCH_TAC THEN MP_TAC(SPEC `Cx x` CGAMMA) THEN
1024   MATCH_MP_TAC(REWRITE_RULE[TAUT `p /\ q /\ r ==> s <=> p /\ r ==> q ==> s`]
1025         LIM_RE_LBOUND) THEN
1026   REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
1027   EXISTS_TAC `1` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
1028   ASM_SIMP_TAC[cpow; CX_INJ; REAL_OF_NUM_EQ; LE_1; GSYM CX_LOG; GSYM CX_INV;
1029                REAL_OF_NUM_LT; GSYM CX_MUL; GSYM CX_EXP; RE_MUL_CX; RE_CX;
1030                complex_div; GSYM CX_ADD; GSYM CX_PRODUCT; FINITE_NUMSEG] THEN
1031   MATCH_MP_TAC REAL_LE_MUL THEN
1032   SIMP_TAC[REAL_LE_MUL; REAL_EXP_POS_LE; REAL_POS; REAL_LE_INV_EQ] THEN
1033   MATCH_MP_TAC PRODUCT_POS_LE_NUMSEG THEN ASM_REAL_ARITH_TAC);;
1034
1035 let CGAMMA_LEGENDRE_ALT = prove
1036  (`!z. cgamma(z) * cgamma(z + Cx(&1) / Cx(&2)) =
1037        Cx(&2) cpow (Cx(&1) - Cx(&2) * z) *
1038        cgamma(Cx(&1) / Cx(&2)) * cgamma(Cx(&2) * z)`,
1039   REWRITE_TAC[GSYM CX_DIV] THEN
1040   SUBGOAL_THEN
1041    `?f. !z. (!n. ~(Cx(&2) * z + Cx(&n) = Cx(&0)))
1042             ==> (f --> (cgamma(z) * cgamma(z + Cx(&1 / &2))) /
1043                      (Cx(&2) cpow (Cx(&1) - Cx(&2) * z) * cgamma(Cx(&2) * z)))
1044                 sequentially`
1045   CHOOSE_TAC THENL
1046    [EXISTS_TAC
1047      `\n. (Cx(&n) cpow Cx(&1 / &2) * inv (Cx(&2))) *
1048           (Cx(&(FACT n)) pow 2 * inv (Cx(&(FACT (2 * n))))) *
1049           Cx(&4) pow (n + 1) *
1050           inv(Cx(&(2 * n + 1)))` THEN
1051     REPEAT STRIP_TAC THEN MP_TAC(SPEC `Cx(&2) * z` CGAMMA) THEN
1052     DISCH_THEN(MP_TAC o SPEC `\n. 2 * n` o MATCH_MP
1053      (REWRITE_RULE[IMP_CONJ_ALT] LIM_SUBSEQUENCE)) THEN
1054     REWRITE_TAC[o_DEF] THEN ANTS_TAC THENL [ARITH_TAC; ALL_TAC] THEN
1055     DISCH_THEN(MP_TAC o SPEC `Cx(&2) cpow (Cx(&1) - Cx(&2) * z)` o
1056           MATCH_MP LIM_COMPLEX_LMUL) THEN
1057     MP_TAC(CONJ (SPEC `z:complex` CGAMMA) (SPEC `z + Cx(&1 / &2)` CGAMMA)) THEN
1058     DISCH_THEN(MP_TAC o MATCH_MP LIM_COMPLEX_MUL) THEN
1059     REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP
1060      (ONCE_REWRITE_RULE[IMP_CONJ]
1061          (REWRITE_RULE[CONJ_ASSOC] LIM_COMPLEX_DIV))) THEN
1062     ASM_REWRITE_TAC[COMPLEX_ENTIRE; CPOW_EQ_0; CGAMMA_EQ_0] THEN
1063     REWRITE_TAC[CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ] THEN
1064     SUBGOAL_THEN `((\n. (Cx(&2) * z + Cx(&(2 * n + 1))) / Cx(&(2 * n + 1)))
1065                    --> Cx(&1)) sequentially`
1066     MP_TAC THENL
1067      [SIMP_TAC[complex_div; COMPLEX_MUL_RINV; CX_INJ; REAL_OF_NUM_EQ;
1068                COMPLEX_ADD_RDISTRIB; ARITH_RULE `~(2 * n + 1 = 0)`] THEN
1069       ONCE_REWRITE_TAC[LIM_NULL_COMPLEX] THEN
1070       REWRITE_TAC[COMPLEX_RING `(a + b) - b:complex = a`] THEN
1071       MATCH_MP_TAC LIM_NULL_COMPLEX_LMUL THEN
1072       MP_TAC(SPEC `\n. 2 * n + 1`
1073        (MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] LIM_SUBSEQUENCE) LIM_INV_N)) THEN
1074       REWRITE_TAC[o_DEF] THEN DISCH_THEN MATCH_MP_TAC THEN ARITH_TAC;
1075       REWRITE_TAC[IMP_IMP] THEN
1076       DISCH_THEN(MP_TAC o MATCH_MP LIM_COMPLEX_MUL)] THEN
1077     REWRITE_TAC[COMPLEX_MUL_LID] THEN
1078     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
1079     REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
1080     EXISTS_TAC `1` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
1081     REWRITE_TAC[CPOW_ADD; complex_div; COMPLEX_INV_MUL; COMPLEX_INV_INV] THEN
1082     REWRITE_TAC[GSYM REAL_OF_NUM_MUL; CX_MUL] THEN
1083     SIMP_TAC[CPOW_MUL_REAL; REAL_CX; RE_CX; REAL_POS] THEN
1084     REWRITE_TAC[CPOW_SUB; CPOW_N; CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ] THEN
1085     SIMP_TAC[COMPLEX_POW_1; complex_div; COMPLEX_INV_INV; COMPLEX_INV_MUL] THEN
1086     REWRITE_TAC[GSYM COMPLEX_MUL_ASSOC] THEN REWRITE_TAC[COMPLEX_RING
1087       `x * y * a * b * c * d * e * f * g * h * i * j * k * l * m:complex =
1088        (x * y) * (e * h) * ((a * d) * k) *
1089        ((b * f) * l) * (i * j) * (m * c * g)`] THEN
1090     REWRITE_TAC[GSYM COMPLEX_POW_2; COMPLEX_MUL_2; CPOW_ADD] THEN
1091     ASM_SIMP_TAC[COMPLEX_MUL_RINV; COMPLEX_POW_EQ_0; CPOW_EQ_0;
1092                  CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ; LE_1; COMPLEX_MUL_LID] THEN
1093     REWRITE_TAC[GSYM COMPLEX_MUL_2; GSYM COMPLEX_INV_MUL] THEN
1094     SIMP_TAC[GSYM CPRODUCT_MUL; FINITE_NUMSEG] THEN
1095     REWRITE_TAC[COMPLEX_RING
1096      `(z + m) * ((z + Cx(&1 / &2)) + m) =
1097       inv(Cx(&4)) *
1098       (Cx(&2) * z + Cx(&2) * m) * (Cx(&2) * z + Cx(&2) * m + Cx(&1))`] THEN
1099     SIMP_TAC[CPRODUCT_MUL; FINITE_NUMSEG; CPRODUCT_CONST_NUMSEG] THEN
1100     SIMP_TAC[GSYM CPRODUCT_MUL; SUB_0; FINITE_NUMSEG] THEN
1101     REWRITE_TAC[GSYM CX_ADD; GSYM CX_MUL;
1102                 REAL_OF_NUM_ADD; REAL_OF_NUM_MUL] THEN
1103     REWRITE_TAC[GSYM CPRODUCT_PAIR] THEN
1104     SIMP_TAC[GSYM ADD1; CPRODUCT_CLAUSES_NUMSEG] THEN
1105     REWRITE_TAC[ADD1] THEN CONV_TAC NUM_REDUCE_CONV THEN
1106     SIMP_TAC[LE_0; COMPLEX_INV_MUL; COMPLEX_INV_INV; GSYM COMPLEX_POW_INV] THEN
1107     ONCE_REWRITE_TAC[COMPLEX_RING
1108      `x * a * b * c * d * e * f:complex = (c * e) * a * b * d * f * x`] THEN
1109     ASM_SIMP_TAC[COMPLEX_MUL_RINV; CPRODUCT_EQ_0; FINITE_NUMSEG] THEN
1110     REWRITE_TAC[COMPLEX_MUL_LID; COMPLEX_MUL_ASSOC] THEN
1111     AP_THM_TAC THEN AP_TERM_TAC THEN
1112     ASM_SIMP_TAC[GSYM COMPLEX_MUL_ASSOC; COMPLEX_MUL_LINV] THEN
1113     CONV_TAC COMPLEX_RING;
1114     ALL_TAC] THEN
1115   X_GEN_TAC `z:complex` THEN
1116   ASM_CASES_TAC `!n. ~(Cx(&2) * z + Cx(&n) = Cx(&0))` THENL
1117    [FIRST_X_ASSUM(fun th ->
1118       MP_TAC(SPEC `z:complex` th) THEN MP_TAC(SPEC `Cx(&1 / &2)` th)) THEN
1119     ASM_REWRITE_TAC[GSYM CX_ADD; GSYM CX_MUL; GSYM CX_SUB; CX_INJ] THEN
1120     ANTS_TAC THENL [REAL_ARITH_TAC; CONV_TAC REAL_RAT_REDUCE_CONV] THEN
1121     REWRITE_TAC[CGAMMA_1; CPOW_N; CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ] THEN
1122     REWRITE_TAC[complex_pow; COMPLEX_MUL_RID; COMPLEX_DIV_1; IMP_IMP] THEN
1123     DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT]
1124         LIM_UNIQUE)) THEN
1125     REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN MATCH_MP_TAC(COMPLEX_FIELD
1126      `~(p = Cx(&0)) /\ ~(z2 = Cx(&0))
1127       ==> a = (z * z') / (p * z2) ==> z * z' = p * a * z2`) THEN
1128     ASM_REWRITE_TAC[CGAMMA_EQ_0; CPOW_EQ_0; CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ];
1129     MATCH_MP_TAC(COMPLEX_RING
1130      `z = Cx(&0) /\ ((w = Cx(&0)) \/ (y = Cx(&0)))
1131       ==> w * y = p * q * z`) THEN
1132     REWRITE_TAC[CGAMMA_EQ_0] THEN
1133     CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
1134     REWRITE_TAC[OR_EXISTS_THM; GSYM COMPLEX_ADD_ASSOC] THEN
1135     ONCE_REWRITE_TAC[COMPLEX_RING
1136      `z + n = Cx(&0) <=> Cx(&2) * z + Cx(&2) * n = Cx(&0)`] THEN
1137     REWRITE_TAC[GSYM CX_ADD; GSYM CX_MUL] THEN
1138     REWRITE_TAC[REAL_ARITH `&2 * (&1 / &2 + n) = &2 * n + &1`] THEN
1139     REWRITE_TAC[REAL_OF_NUM_SUC; REAL_OF_NUM_MUL] THEN
1140     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN
1141     DISCH_THEN(X_CHOOSE_THEN `n:num` MP_TAC) THEN
1142     MP_TAC(SPEC `n:num` EVEN_OR_ODD) THEN
1143     MESON_TAC[ODD_EXISTS; EVEN_EXISTS]]);;
1144
1145 let CGAMMA_REFLECTION = prove
1146  (`!z. cgamma(z) * cgamma(Cx(&1) - z) = Cx pi / csin(Cx pi * z)`,
1147   let lemma = prove
1148    (`!w z. (?n. integer n /\ w = Cx n) /\ (?n. integer n /\ z = Cx n) /\
1149            dist(w,z) < &1
1150            ==> w = z`,
1151     REPEAT GEN_TAC THEN
1152     REPEAT(DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC)) THEN
1153     ASM_REWRITE_TAC[DIST_CX] THEN ASM_MESON_TAC[REAL_EQ_INTEGERS_IMP]) in
1154   ABBREV_TAC
1155    `g = \z. if ?n. integer n /\ z = Cx n then Cx pi
1156             else cgamma(z) * cgamma(Cx(&1) - z) * csin(Cx pi * z)` THEN
1157   SUBGOAL_THEN `!z. g(z + Cx(&1)):complex = g(z)` ASSUME_TAC THENL
1158    [GEN_TAC THEN EXPAND_TAC "g" THEN
1159     MATCH_MP_TAC(MESON[] `(p <=> p') /\ a = a' /\ b = b'
1160                     ==> (if p then a else b) = (if p' then a' else b')`) THEN
1161     REWRITE_TAC[COMPLEX_RING `z + Cx(&1) = w <=> z = w - Cx(&1)`] THEN
1162     CONJ_TAC THENL
1163      [REWRITE_TAC[GSYM CX_SUB] THEN
1164       MESON_TAC[INTEGER_CLOSED; REAL_ARITH `(n + &1) - &1 = n`];
1165       GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [CGAMMA_RECURRENCE_ALT] THEN
1166       REWRITE_TAC[COMPLEX_RING `a - (z + a):complex = --z`] THEN
1167       GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o LAND_CONV)
1168        [CGAMMA_RECURRENCE_ALT] THEN
1169       REWRITE_TAC[COMPLEX_ADD_LDISTRIB; COMPLEX_MUL_RID; CSIN_ADD] THEN
1170       REWRITE_TAC[GSYM CX_SIN; GSYM CX_COS; SIN_PI; COS_PI] THEN
1171       REWRITE_TAC[COMPLEX_RING `--z + Cx(&1) = Cx(&1) - z`] THEN
1172       REWRITE_TAC[complex_div; COMPLEX_INV_NEG; COMPLEX_MUL_AC;
1173                   CX_NEG; COMPLEX_MUL_LID; COMPLEX_MUL_LZERO] THEN
1174       REWRITE_TAC[COMPLEX_ADD_RID; COMPLEX_MUL_LNEG; COMPLEX_MUL_RNEG] THEN
1175       REWRITE_TAC[COMPLEX_MUL_LID; COMPLEX_NEG_NEG] THEN
1176       REWRITE_TAC[COMPLEX_MUL_AC]];
1177     ALL_TAC] THEN
1178   SUBGOAL_THEN `!n z. integer n ==> g(z + Cx n):complex = g z` ASSUME_TAC THENL
1179    [SUBGOAL_THEN `!n z. g(z + Cx(&n)):complex = g z` ASSUME_TAC THENL
1180      [INDUCT_TAC THEN
1181       ASM_REWRITE_TAC[GSYM REAL_OF_NUM_SUC; COMPLEX_ADD_RID] THEN
1182       ASM_REWRITE_TAC[CX_ADD; COMPLEX_ADD_ASSOC];
1183       REWRITE_TAC[integer] THEN REPEAT STRIP_TAC THEN
1184       FIRST_X_ASSUM(DISJ_CASES_THEN SUBST1_TAC o MATCH_MP
1185        (REAL_ARITH `abs x = a ==> x = a \/ x = --a`)) THEN
1186       ASM_REWRITE_TAC[CX_NEG; GSYM complex_sub] THEN
1187       ASM_MESON_TAC[COMPLEX_RING `(z - w) + w:complex = z`]];
1188     ALL_TAC] THEN
1189   SUBGOAL_THEN `!z. ~(?n. integer n /\ z = Cx n)
1190                     ==> g complex_differentiable (at z)`
1191   ASSUME_TAC THENL
1192    [REPEAT STRIP_TAC THEN MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_AT THEN
1193     EXISTS_TAC `\z. cgamma z * cgamma(Cx(&1) - z) * csin(Cx pi * z)` THEN
1194     SUBGOAL_THEN `closed {z | ?n. integer n /\ z = Cx n}` MP_TAC THENL
1195      [MATCH_MP_TAC DISCRETE_IMP_CLOSED THEN EXISTS_TAC `&1` THEN
1196       REWRITE_TAC[REAL_LT_01; IN_ELIM_THM] THEN MESON_TAC[lemma; dist];
1197       REWRITE_TAC[closed; OPEN_CONTAINS_BALL; IN_UNIV; IN_DIFF]] THEN
1198     DISCH_THEN(MP_TAC o SPEC `z:complex`) THEN
1199     ASM_REWRITE_TAC[IN_ELIM_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
1200     REWRITE_TAC[SUBSET; IN_BALL; IN_DIFF; IN_ELIM_THM; IN_UNIV] THEN
1201     X_GEN_TAC `e:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1202     ONCE_REWRITE_TAC[DIST_SYM] THEN EXPAND_TAC "g" THEN REWRITE_TAC[] THEN
1203     ASM_SIMP_TAC[] THEN
1204     REPEAT(MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_MUL_AT THEN CONJ_TAC) THENL
1205      [ALL_TAC;
1206       GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
1207       MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_COMPOSE_AT THEN
1208       CONJ_TAC;
1209       ALL_TAC] THEN
1210      (MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_AT_CGAMMA ORELSE
1211       COMPLEX_DIFFERENTIABLE_TAC) THEN
1212      REWRITE_TAC[COMPLEX_RING `z + a:complex = b <=> z = b - a`;
1213                  COMPLEX_RING `Cx(&1) - z = a - b <=> z = b - a + Cx(&1)`] THEN
1214      REWRITE_TAC[GSYM CX_ADD; GSYM CX_SUB] THEN ASM_MESON_TAC[INTEGER_CLOSED];
1215      ALL_TAC] THEN
1216   SUBGOAL_THEN `g complex_differentiable at (Cx(&0))` ASSUME_TAC THENL
1217    [MATCH_MP_TAC HOLOMORPHIC_ON_IMP_DIFFERENTIABLE_AT THEN
1218     EXISTS_TAC `ball(Cx(&0),&1)` THEN
1219     REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL; REAL_LT_01] THEN
1220     MATCH_MP_TAC NO_ISOLATED_SINGULARITY THEN EXISTS_TAC `{Cx(&0)}` THEN
1221     REWRITE_TAC[OPEN_BALL; FINITE_SING] THEN CONJ_TAC THENL
1222      [ALL_TAC;
1223       REWRITE_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE; IN_DIFF; IN_SING] THEN
1224       X_GEN_TAC `z:complex` THEN REWRITE_TAC[COMPLEX_IN_BALL_0] THEN
1225       STRIP_TAC THEN MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_AT_WITHIN THEN
1226       FIRST_X_ASSUM MATCH_MP_TAC THEN UNDISCH_TAC `~(z = Cx(&0))` THEN
1227       REWRITE_TAC[CONTRAPOS_THM] THEN DISCH_TAC THEN MATCH_MP_TAC lemma THEN
1228       ASM_REWRITE_TAC[dist; COMPLEX_SUB_RZERO] THEN
1229       MESON_TAC[INTEGER_CLOSED]] THEN
1230     REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
1231     X_GEN_TAC `z:complex` THEN REWRITE_TAC[COMPLEX_IN_BALL_0] THEN
1232     DISCH_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN
1233     ASM_CASES_TAC `z = Cx(&0)` THENL
1234      [ALL_TAC;
1235       MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_AT THEN
1236       FIRST_X_ASSUM MATCH_MP_TAC THEN UNDISCH_TAC `~(z = Cx(&0))` THEN
1237       REWRITE_TAC[CONTRAPOS_THM] THEN DISCH_TAC THEN MATCH_MP_TAC lemma THEN
1238       ASM_REWRITE_TAC[dist; COMPLEX_SUB_RZERO] THEN
1239       MESON_TAC[INTEGER_CLOSED]] THEN
1240     FIRST_X_ASSUM SUBST_ALL_TAC THEN REWRITE_TAC[CONTINUOUS_AT] THEN
1241     EXPAND_TAC "g" THEN
1242     REWRITE_TAC[MESON[INTEGER_CLOSED] `?n. integer n /\ Cx(&0) = Cx(n)`] THEN
1243     MATCH_MP_TAC LIM_TRANSFORM_WITHIN_OPEN THEN
1244     EXISTS_TAC `\z. Cx pi * (z * cgamma(z)) * cgamma(Cx(&1) - z) *
1245                     csin(Cx pi * z) / (Cx pi * z)` THEN
1246     EXISTS_TAC `ball(Cx(&0),&1)` THEN
1247     REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL; REAL_LT_01] THEN CONJ_TAC THENL
1248      [X_GEN_TAC `w:complex` THEN REWRITE_TAC[COMPLEX_IN_BALL_0] THEN
1249       STRIP_TAC THEN COND_CASES_TAC THENL
1250        [UNDISCH_TAC `~(w = Cx(&0))` THEN
1251         MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN MATCH_MP_TAC lemma THEN
1252         ASM_REWRITE_TAC[dist; COMPLEX_SUB_RZERO] THEN
1253         MESON_TAC[INTEGER_CLOSED];
1254         UNDISCH_TAC `~(w = Cx(&0))` THEN MP_TAC PI_NZ THEN
1255         REWRITE_TAC[GSYM CX_INJ] THEN CONV_TAC COMPLEX_FIELD];
1256       GEN_REWRITE_TAC LAND_CONV [COMPLEX_RING
1257        `p = p * Cx(&1) * Cx(&1) * Cx(&1)`] THEN
1258       MATCH_MP_TAC LIM_COMPLEX_LMUL THEN MATCH_MP_TAC LIM_COMPLEX_MUL THEN
1259       CONJ_TAC THENL
1260        [MP_TAC(SPEC `0` CGAMMA_SIMPLE_POLES) THEN
1261         REWRITE_TAC[FACT; COMPLEX_DIV_1; complex_pow; COMPLEX_ADD_RID] THEN
1262         REWRITE_TAC[COMPLEX_NEG_0];
1263         ALL_TAC] THEN
1264       MATCH_MP_TAC LIM_COMPLEX_MUL THEN CONJ_TAC THENL
1265        [SUBGOAL_THEN `(cgamma o (\z. Cx(&1) - z)) continuous (at (Cx(&0)))`
1266         MP_TAC THENL
1267          [MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN
1268           CONJ_TAC THENL [CONTINUOUS_TAC; ALL_TAC] THEN
1269           MATCH_MP_TAC CONTINUOUS_AT_CGAMMA THEN
1270           REWRITE_TAC[GSYM CX_ADD; GSYM CX_SUB; CX_INJ] THEN
1271           REAL_ARITH_TAC;
1272           REWRITE_TAC[CONTINUOUS_AT; o_DEF; COMPLEX_SUB_RZERO; CGAMMA_1]];
1273         SUBGOAL_THEN
1274          `(\z. csin(Cx pi * z) / (Cx pi * z)) =
1275           (\z. csin z / z) o (\w. Cx pi * w)`
1276         SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
1277         MATCH_MP_TAC LIM_COMPOSE_AT THEN
1278         EXISTS_TAC `Cx(&0)` THEN REWRITE_TAC[LIM_CSIN_OVER_X] THEN
1279         SIMP_TAC[EVENTUALLY_AT; COMPLEX_ENTIRE; CX_INJ; PI_NZ;
1280                  GSYM DIST_NZ] THEN
1281         CONJ_TAC THENL [ALL_TAC; MESON_TAC[REAL_LT_01]] THEN
1282         LIM_TAC THEN CONV_TAC COMPLEX_RING]];
1283     ALL_TAC] THEN
1284   SUBGOAL_THEN `g holomorphic_on (:complex)` ASSUME_TAC THENL
1285    [REWRITE_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE; WITHIN_UNIV; IN_UNIV] THEN
1286     X_GEN_TAC `z:complex` THEN ASM_CASES_TAC `?n. integer n /\ z = Cx n` THEN
1287     ASM_SIMP_TAC[] THEN
1288     FIRST_X_ASSUM(X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC) THEN
1289     MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_TRANSFORM_AT THEN
1290     EXISTS_TAC `(g:complex->complex) o (\z. z - Cx n)` THEN
1291     EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN CONJ_TAC THENL
1292      [REWRITE_TAC[o_THM] THEN
1293       ASM_MESON_TAC[COMPLEX_RING `(z - w) + w:complex = z`];
1294       MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_COMPOSE_AT THEN
1295       ASM_REWRITE_TAC[COMPLEX_SUB_REFL] THEN
1296       COMPLEX_DIFFERENTIABLE_TAC];
1297     ALL_TAC] THEN
1298   SUBGOAL_THEN
1299    `!z. g(z / Cx(&2)) * g((z + Cx(&1)) / Cx(&2)) =
1300         cgamma(Cx(&1 / &2)) pow 2 * g(z)`
1301   ASSUME_TAC THENL
1302    [MATCH_MP_TAC(SET_RULE
1303      `!s. s = UNIV /\ (!x. x IN s ==> P x) ==> !x. P x`) THEN
1304     EXISTS_TAC `closure {z | !n. ~(integer n /\ z = Cx n)}` THEN
1305     CONJ_TAC THENL
1306      [REWRITE_TAC[CLOSURE_INTERIOR] THEN
1307       MATCH_MP_TAC(SET_RULE `s = {} ==> t DIFF s = t`) THEN
1308       MATCH_MP_TAC COUNTABLE_EMPTY_INTERIOR THEN
1309       MATCH_MP_TAC DISCRETE_IMP_COUNTABLE THEN
1310       REWRITE_TAC[IN_DIFF; IN_UNIV; IN_ELIM_THM] THEN
1311       REPEAT STRIP_TAC THEN EXISTS_TAC `&1` THEN
1312       REWRITE_TAC[GSYM REAL_NOT_LT; GSYM dist; REAL_LT_01] THEN
1313       ASM_MESON_TAC[lemma];
1314       ALL_TAC] THEN
1315     ONCE_REWRITE_TAC[GSYM COMPLEX_SUB_0] THEN REWRITE_TAC[GSYM IN_SING] THEN
1316     MATCH_MP_TAC FORALL_IN_CLOSURE THEN REWRITE_TAC[CLOSED_SING] THEN
1317     CONJ_TAC THENL
1318      [MATCH_MP_TAC CONTINUOUS_ON_SUB THEN CONJ_TAC THEN
1319       MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN CONJ_TAC THEN
1320       REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
1321       TRY(GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
1322           MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC) THEN
1323       FIRST_ASSUM(MP_TAC o MATCH_MP HOLOMORPHIC_ON_IMP_CONTINUOUS_ON) THEN
1324       REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
1325       REWRITE_TAC[IN_UNIV; WITHIN_UNIV] THEN REPEAT STRIP_TAC THEN
1326       MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN ASM_REWRITE_TAC[] THEN
1327       REWRITE_TAC[complex_div] THEN MATCH_MP_TAC CONTINUOUS_COMPLEX_MUL THEN
1328       CONJ_TAC THEN CONTINUOUS_TAC;
1329       ALL_TAC] THEN
1330     X_GEN_TAC `z:complex` THEN
1331     REWRITE_TAC[IN_ELIM_THM; IN_SING; COMPLEX_SUB_0] THEN DISCH_TAC THEN
1332     EXPAND_TAC "g" THEN REWRITE_TAC[] THEN
1333     REWRITE_TAC[COMPLEX_RING `z / Cx(&2) = w <=> z = Cx(&2) * w`] THEN
1334     REWRITE_TAC[COMPLEX_RING `z + Cx(&1) = w <=> z = w - Cx(&1)`] THEN
1335     REWRITE_TAC[GSYM CX_MUL; GSYM CX_SUB] THEN
1336     REPEAT(COND_CASES_TAC THENL [ASM_MESON_TAC[INTEGER_CLOSED]; ALL_TAC]) THEN
1337     REWRITE_TAC[COMPLEX_RING
1338      `(a * b * c) * (d * e * f):complex =
1339       (a * d) * (e * b) * (c * f)`] THEN
1340     REWRITE_TAC[COMPLEX_RING
1341      `Cx(&1) - (z + Cx(&1)) / Cx(&2) = (Cx(&1) - z) / Cx(&2)`] THEN
1342     REWRITE_TAC[COMPLEX_RING
1343      `(z + Cx(&1)) / Cx(&2) = z / Cx(&2) + Cx(&1) / Cx(&2) /\
1344       Cx(&1) - z / Cx(&2) = ((Cx(&1) - z) / Cx(&2)) + Cx(&1) / Cx(&2)`] THEN
1345     REWRITE_TAC[CGAMMA_LEGENDRE_ALT] THEN
1346     MP_TAC(ISPEC `Cx(&1 / &2) * z * Cx pi` CSIN_DOUBLE) THEN
1347     MP_TAC(SPECL [`Cx(&2)`; `z:complex`; `--z:complex`] CPOW_ADD) THEN
1348     REWRITE_TAC[COMPLEX_ADD_RINV] THEN
1349     CONV_TAC(DEPTH_BINOP_CONV `==>`
1350      (BINOP_CONV(DEPTH_BINOP_CONV `complex_mul`
1351      (RAND_CONV COMPLEX_POLY_CONV)))) THEN
1352     REWRITE_TAC[CPOW_ADD; CX_NEG; COMPLEX_MUL_LNEG; COMPLEX_MUL_LID] THEN
1353     REWRITE_TAC[CPOW_N; CX_INJ; REAL_OF_NUM_EQ; ARITH_EQ; CSIN_ADD] THEN
1354     REWRITE_TAC[GSYM CX_MUL; GSYM CX_SIN; GSYM CX_COS; SIN_PI2; COS_PI2;
1355                 REAL_ARITH `&1 / &2 * x = x / &2`] THEN
1356     CONV_TAC COMPLEX_RING;
1357     ALL_TAC] THEN
1358   SUBGOAL_THEN
1359    `?h. h holomorphic_on (:complex) /\
1360         !z. z IN (:complex) ==> g z = cexp(h z)`
1361   MP_TAC THENL
1362    [MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
1363       CONTRACTIBLE_IMP_HOLOMORPHIC_LOG) THEN
1364     ASM_REWRITE_TAC[CONTRACTIBLE_UNIV; IN_UNIV] THEN
1365     X_GEN_TAC `z:complex` THEN EXPAND_TAC "g" THEN
1366     COND_CASES_TAC THEN REWRITE_TAC[CX_INJ; PI_NZ] THEN
1367     REWRITE_TAC[CGAMMA_EQ_0; CSIN_EQ_0; COMPLEX_ENTIRE] THEN
1368     REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] CX_MUL] THEN
1369     REWRITE_TAC[COMPLEX_RING `a - z + b = Cx(&0) <=> z = a + b`] THEN
1370     REWRITE_TAC[COMPLEX_EQ_MUL_LCANCEL; CX_INJ; PI_NZ] THEN
1371     REWRITE_TAC[COMPLEX_RING `z + a =  Cx(&0) <=> z = --a`] THEN
1372     REWRITE_TAC[GSYM CX_ADD; GSYM CX_NEG] THEN ASM_MESON_TAC[INTEGER_CLOSED];
1373     REWRITE_TAC[IN_UNIV] THEN DISCH_THEN(STRIP_ASSUME_TAC o GSYM)] THEN
1374   MP_TAC(ISPECL [`h:complex->complex`; `(:complex)`]
1375         HOLOMORPHIC_ON_OPEN) THEN
1376   ASM_REWRITE_TAC[OPEN_UNIV; IN_UNIV; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
1377   X_GEN_TAC `h':complex->complex` THEN DISCH_TAC THEN
1378   SUBGOAL_THEN
1379    `!z. (h'(z / Cx(&2)) + h'((z + Cx(&1)) / Cx(&2))) / Cx(&2) = h'(z)`
1380   ASSUME_TAC THENL
1381    [X_GEN_TAC `z:complex` THEN MATCH_MP_TAC
1382      (COMPLEX_RING `!a. ~(a = Cx(&0)) /\ a * x = a * y ==> x = y`) THEN
1383     EXISTS_TAC `g(z / Cx(&2)) * g((z + Cx(&1)) / Cx(&2))` THEN
1384     REWRITE_TAC[COMPLEX_ENTIRE] THEN
1385     CONJ_TAC THENL [ASM_MESON_TAC[CEXP_NZ]; ALL_TAC] THEN
1386     MATCH_MP_TAC COMPLEX_DERIVATIVE_UNIQUE_AT THEN
1387     EXISTS_TAC `\z. g (z / Cx(&2)) * g ((z + Cx(&1)) / Cx(&2)):complex` THEN
1388     EXISTS_TAC `z:complex` THEN CONJ_TAC THENL
1389      [REWRITE_TAC[]; ASM_REWRITE_TAC[]] THEN
1390     FIRST_ASSUM(SUBST1_TAC o SYM o GEN_REWRITE_RULE I [GSYM FUN_EQ_THM]) THEN
1391     REWRITE_TAC[] THEN
1392     ASM GEN_COMPLEX_DIFF_TAC [] THEN
1393     (CONJ_TAC THENL [ASM_REWRITE_TAC[]; CONV_TAC COMPLEX_RING]);
1394     ALL_TAC] THEN
1395   MP_TAC(ISPECL [`h:complex->complex`; `h':complex->complex`; `(:complex)`]
1396         HOLOMORPHIC_DERIVATIVE) THEN
1397   ASM_REWRITE_TAC[OPEN_UNIV] THEN DISCH_TAC THEN
1398   MP_TAC(ISPECL [`h':complex->complex`; `(:complex)`]
1399         HOLOMORPHIC_ON_OPEN) THEN
1400   ASM_REWRITE_TAC[OPEN_UNIV; IN_UNIV; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
1401   X_GEN_TAC `h'':complex->complex` THEN DISCH_TAC THEN
1402   SUBGOAL_THEN
1403    `!z. (h''(z / Cx(&2)) + h''((z + Cx(&1)) / Cx(&2))) / Cx(&4) = h''(z)`
1404   ASSUME_TAC THENL
1405    [X_GEN_TAC `z:complex` THEN
1406     MATCH_MP_TAC COMPLEX_DERIVATIVE_UNIQUE_AT THEN
1407     EXISTS_TAC `\z. (h'(z / Cx(&2)) + h'((z + Cx(&1)) / Cx(&2))) / Cx(&2)` THEN
1408     EXISTS_TAC `z:complex` THEN CONJ_TAC THENL
1409      [REWRITE_TAC[]; ASM_REWRITE_TAC[]] THEN
1410     ASM GEN_COMPLEX_DIFF_TAC [] THEN
1411     (CONJ_TAC THENL [ASM_REWRITE_TAC[ETA_AX]; CONV_TAC COMPLEX_RING]);
1412     ALL_TAC] THEN
1413   MP_TAC(ISPECL [`h':complex->complex`; `h'':complex->complex`; `(:complex)`]
1414         HOLOMORPHIC_DERIVATIVE) THEN
1415   ASM_REWRITE_TAC[OPEN_UNIV] THEN DISCH_TAC THEN
1416   SUBGOAL_THEN `!z. z IN (:complex) ==> h''(z) = Cx(&0)` MP_TAC THENL
1417    [MATCH_MP_TAC ANALYTIC_CONTINUATION THEN
1418     EXISTS_TAC `cball(Cx(&0),&1)` THEN EXISTS_TAC `Cx(&0)` THEN
1419     ASM_REWRITE_TAC[CONNECTED_UNIV; SUBSET_UNIV; IN_UNIV] THEN
1420     SIMP_TAC[INTERIOR_LIMIT_POINT; INTERIOR_CBALL; CENTRE_IN_BALL;
1421              OPEN_UNIV; REAL_LT_01] THEN
1422     MP_TAC(ISPECL [`\z. norm((h'':complex->complex) z)`; `cball(Cx(&0),&1)`]
1423         CONTINUOUS_ATTAINS_SUP) THEN
1424     ASM_REWRITE_TAC[COMPLEX_IN_CBALL_0; COMPACT_CBALL; CBALL_EQ_EMPTY] THEN
1425     REWRITE_TAC[o_DEF] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN ANTS_TAC THENL
1426      [MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN
1427       ASM_MESON_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; CONTINUOUS_ON_SUBSET;
1428                     SUBSET_UNIV];
1429       DISCH_THEN(X_CHOOSE_THEN `w:complex` STRIP_ASSUME_TAC) THEN
1430       REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN
1431       MATCH_MP_TAC(NORM_ARITH
1432        `!w:complex. norm(w) <= norm(w) / &2 /\ norm(z) <= norm(w)
1433                     ==> z = vec 0`) THEN
1434       EXISTS_TAC `(h'':complex->complex) w` THEN ASM_SIMP_TAC[] THEN
1435       FIRST_X_ASSUM(fun th ->
1436         GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM th]) THEN
1437       REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; REAL_ABS_NUM] THEN
1438       MATCH_MP_TAC(NORM_ARITH
1439        `norm(a) <= e /\ norm(b) <= e ==> norm(a + b) / &4 <= e / &2`) THEN
1440       CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
1441       REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; REAL_ABS_NUM] THEN
1442       UNDISCH_TAC `norm(w:complex) <= &1` THEN
1443       MP_TAC(SPEC `&1` COMPLEX_NORM_CX) THEN CONV_TAC NORM_ARITH];
1444       REWRITE_TAC[IN_UNIV] THEN DISCH_TAC] THEN
1445   MP_TAC(ISPECL [`h':complex->complex`; `(:complex)`]
1446         HAS_COMPLEX_DERIVATIVE_ZERO_CONSTANT) THEN
1447   REWRITE_TAC[CONVEX_UNIV; IN_UNIV] THEN ANTS_TAC THENL
1448    [ASM_MESON_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN]; ALL_TAC] THEN
1449   DISCH_THEN(X_CHOOSE_TAC `a:complex`) THEN
1450   MP_TAC(ISPECL [`\z. (h:complex->complex) z - a * z`; `(:complex)`]
1451         HAS_COMPLEX_DERIVATIVE_ZERO_CONSTANT) THEN
1452   REWRITE_TAC[CONVEX_UNIV; IN_UNIV] THEN ANTS_TAC THENL
1453    [GEN_TAC THEN ASM GEN_COMPLEX_DIFF_TAC[] THEN
1454     ASM_REWRITE_TAC[] THEN CONV_TAC COMPLEX_RING;
1455     REWRITE_TAC[COMPLEX_RING `a - b:complex = c <=> a = b + c`] THEN
1456     DISCH_THEN(X_CHOOSE_TAC `b:complex`)] THEN
1457   FIRST_X_ASSUM(MP_TAC o SPECL [`&1`; `Cx(&0)`]) THEN
1458   MP_TAC(ASSUME `!z:complex. cexp (h z) = g z`) THEN
1459   DISCH_THEN(fun th -> REWRITE_TAC[GSYM th]) THEN
1460   REWRITE_TAC[ ASSUME`!x. (h:complex->complex) x = a * x + b`] THEN
1461   REWRITE_TAC[INTEGER_CLOSED; COMPLEX_ADD_LID; COMPLEX_MUL_RZERO] THEN
1462   REWRITE_TAC[CEXP_ADD; COMPLEX_MUL_RID] THEN
1463   REWRITE_TAC[COMPLEX_RING `a * b = b <=> a = Cx(&1) \/ b = Cx(&0)`] THEN
1464   REWRITE_TAC[CEXP_NZ; CEXP_EQ_1] THEN
1465   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC
1466    (X_CHOOSE_THEN `n:real` STRIP_ASSUME_TAC)) THEN
1467   UNDISCH_TAC `!z:complex. cexp(h z) = g z` THEN
1468   ASM_REWRITE_TAC[] THEN ASM_CASES_TAC `n = &0` THENL
1469    [SUBST1_TAC(SYM(SPEC `a:complex` COMPLEX)) THEN
1470     ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO; GSYM CX_DEF] THEN
1471     REWRITE_TAC[COMPLEX_MUL_LZERO; COMPLEX_ADD_LID] THEN
1472     DISCH_THEN(ASSUME_TAC o GSYM) THEN X_GEN_TAC `z:complex` THEN
1473     ASM_CASES_TAC `?n. integer n /\ z = Cx n` THENL
1474      [REWRITE_TAC[complex_div] THEN
1475       MATCH_MP_TAC(COMPLEX_RING
1476        `z = Cx(&0) /\ ((w = Cx(&0)) \/ (y = Cx(&0)))
1477         ==> w * y = p * z`) THEN
1478       REWRITE_TAC[CGAMMA_EQ_0; CSIN_EQ_0; COMPLEX_INV_EQ_0] THEN
1479       CONJ_TAC THENL [ASM_MESON_TAC[REAL_MUL_SYM; CX_MUL]; ALL_TAC] THEN
1480       REWRITE_TAC[OR_EXISTS_THM; GSYM COMPLEX_ADD_ASSOC] THEN
1481       REWRITE_TAC[COMPLEX_RING `c - z + n = Cx(&0) <=> z = n + c`] THEN
1482       FIRST_X_ASSUM(X_CHOOSE_THEN `m:real`
1483        (CONJUNCTS_THEN2 MP_TAC SUBST1_TAC)) THEN
1484       REWRITE_TAC[integer] THEN DISCH_THEN(X_CHOOSE_THEN `p:num`
1485         (MP_TAC o MATCH_MP (REAL_ARITH `abs x = n ==> x = n \/ x = --n`))) THEN
1486       DISCH_THEN(DISJ_CASES_THEN SUBST_ALL_TAC) THEN
1487       REWRITE_TAC[GSYM CX_ADD; CX_INJ; REAL_OF_NUM_ADD; REAL_OF_NUM_EQ;
1488                   REAL_ARITH `--p + n = &0 <=> p = n`] THEN
1489       REWRITE_TAC[EXISTS_OR_THM; GSYM EXISTS_REFL] THEN
1490       REWRITE_TAC[ADD_EQ_0; RIGHT_EXISTS_AND_THM; EXISTS_REFL] THEN
1491       MESON_TAC[num_CASES; ADD1];
1492       SUBGOAL_THEN `(g:complex->complex) z = g(Cx(&0))` MP_TAC THENL
1493        [ASM_REWRITE_TAC[]; EXPAND_TAC "g"] THEN
1494       ASM_REWRITE_TAC[] THEN
1495       COND_CASES_TAC THENL [ALL_TAC; ASM_MESON_TAC[INTEGER_CLOSED]] THEN
1496       MP_TAC PI_NZ THEN REWRITE_TAC[GSYM CX_INJ] THEN CONV_TAC COMPLEX_FIELD];
1497     DISCH_THEN(fun th ->
1498       MP_TAC(SPEC `Cx(inv(&4 * n))` th) THEN MP_TAC(SPEC `Cx(&0)` th)) THEN
1499     REWRITE_TAC[COMPLEX_MUL_RZERO; COMPLEX_ADD_LID] THEN
1500     SUBGOAL_THEN `g(Cx(&0)) = Cx pi` SUBST1_TAC THENL
1501      [ASM_MESON_TAC[INTEGER_CLOSED]; ALL_TAC] THEN
1502     REWRITE_TAC[CEXP_ADD] THEN DISCH_THEN SUBST1_TAC THEN
1503     SUBST1_TAC(SYM(SPEC `a:complex` COMPLEX)) THEN
1504     ASM_REWRITE_TAC[] THEN
1505     GEN_REWRITE_TAC (funpow 3 LAND_CONV o RAND_CONV) [complex_mul] THEN
1506     REWRITE_TAC[RE; IM; REAL_MUL_LZERO; IM_CX; RE_CX] THEN
1507     REWRITE_TAC[CEXP_COMPLEX; REAL_ADD_LID] THEN ASM_SIMP_TAC[REAL_FIELD
1508      `~(n = &0) ==> (&2 * n * pi) * inv(&4 * n) = pi / &2`] THEN
1509     REWRITE_TAC[SIN_PI2; COS_PI2; GSYM ii] THEN
1510     REWRITE_TAC[REAL_MUL_RZERO; REAL_SUB_REFL; REAL_EXP_0] THEN
1511     REWRITE_TAC[COMPLEX_MUL_LID] THEN
1512     MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN EXPAND_TAC "g" THEN
1513     ASM_SIMP_TAC[CX_INJ; REAL_FIELD
1514      `~(n = &0) ==> (inv(&4 * n) = m <=> &4 * m * n = &1)`] THEN
1515     COND_CASES_TAC THENL
1516      [FIRST_X_ASSUM(X_CHOOSE_THEN `m:real` STRIP_ASSUME_TAC) THEN
1517       FIRST_X_ASSUM(MP_TAC o AP_TERM `abs`) THEN
1518       REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NUM] THEN
1519       REPEAT(FIRST_X_ASSUM(CHOOSE_TAC o GEN_REWRITE_RULE I [integer])) THEN
1520       ASM_REWRITE_TAC[REAL_OF_NUM_MUL; REAL_OF_NUM_EQ; MULT_EQ_1] THEN
1521       CONV_TAC NUM_REDUCE_CONV;
1522       MATCH_MP_TAC(MESON[] `real y /\ ~real x ==> ~(x = y)`) THEN
1523       SIMP_TAC[GSYM CX_SUB; GSYM CX_MUL; REAL_CX; REAL_SIN; REAL_GAMMA;
1524                REAL_MUL; ONCE_REWRITE_RULE[COMPLEX_MUL_SYM] REAL_MUL_CX] THEN
1525       REWRITE_TAC[PI_NZ; real; IM_II] THEN ARITH_TAC]]);;
1526
1527 let CGAMMA_HALF = prove
1528  (`cgamma(Cx(&1) / Cx(&2)) = Cx(sqrt pi)`,
1529   MP_TAC(SPEC `Cx(&1) / Cx(&2)` CGAMMA_REFLECTION) THEN
1530   REWRITE_TAC[COMPLEX_RING `Cx(&1) - Cx(&1) / Cx(&2) = Cx(&1) / Cx(&2)`] THEN
1531   REWRITE_TAC[GSYM CX_DIV; GSYM CX_MUL; GSYM CX_SIN] THEN
1532   REWRITE_TAC[REAL_ARITH `x * &1 / &2 = x / &2`; SIN_PI2; REAL_DIV_1] THEN
1533   SUBGOAL_THEN `Cx pi = Cx(sqrt pi) pow 2` SUBST1_TAC THENL
1534    [REWRITE_TAC[GSYM CX_POW] THEN AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN
1535     REWRITE_TAC[SQRT_POW2; PI_POS_LE];
1536     REWRITE_TAC[COMPLEX_RING
1537      `a * a:complex = b pow 2 <=> a = b \/ a = --b`] THEN
1538     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1539     MP_TAC(SPEC `Cx(&1 / &2)` RE_POS_CGAMMA_REAL) THEN
1540     ASM_REWRITE_TAC[REAL_CX; RE_CX; RE_NEG] THEN
1541     CONV_TAC REAL_RAT_REDUCE_CONV THEN MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN
1542     REWRITE_TAC[REAL_ARITH `~(&0 <= --x) <=> &0 < x`] THEN
1543     MATCH_MP_TAC SQRT_POS_LT THEN REWRITE_TAC[PI_POS]]);;
1544
1545 let CGAMMA_LEGENDRE = prove
1546  (`!z. cgamma(z) * cgamma(z + Cx(&1) / Cx(&2)) =
1547        Cx(&2) cpow (Cx(&1) - Cx(&2) * z) * Cx(sqrt pi) * cgamma(Cx(&2) * z)`,
1548   REWRITE_TAC[CGAMMA_LEGENDRE_ALT; CGAMMA_HALF]);;
1549
1550 (* ------------------------------------------------------------------------- *)
1551 (* Thw Weierstrass product definition.                                       *)
1552 (* ------------------------------------------------------------------------- *)
1553
1554 let CGAMMA_WEIERSTRASS = prove
1555  (`!z. ((\n. cexp(--(Cx euler_mascheroni) * z) / z *
1556              cproduct(1..n) (\k. cexp(z / Cx(&k)) / (Cx(&1) + z / Cx(&k))))
1557        --> cgamma z) sequentially`,
1558   GEN_TAC THEN SIMP_TAC[complex_div; CPRODUCT_MUL; FINITE_NUMSEG] THEN
1559   MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
1560   EXISTS_TAC `\n. (cexp(--Cx euler_mascheroni * z) *
1561                    cproduct(1..n) (\k. cexp(z * inv(Cx(&k)))) *
1562                    cexp(--Cx(log(&n)) * z)) *
1563                   (Cx(&n) cpow z / z *
1564                    cproduct (1..n) (\k. inv(Cx(&1) + z * inv(Cx(&k)))))` THEN
1565   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN CONJ_TAC THENL
1566    [EXISTS_TAC `1` THEN REPEAT STRIP_TAC THEN REWRITE_TAC[complex_div] THEN
1567     MATCH_MP_TAC(COMPLEX_RING
1568      `c * c' = Cx(&1) ==> (a * b * c) * (c' * d) * e = ((a * d) * b * e)`) THEN
1569     ASM_SIMP_TAC[cpow; CX_INJ; REAL_OF_NUM_EQ; LE_1; GSYM CEXP_ADD] THEN
1570     REWRITE_TAC[GSYM CEXP_0] THEN AP_TERM_TAC THEN
1571     ASM_SIMP_TAC[CX_LOG; REAL_OF_NUM_LT; LE_1] THEN CONV_TAC COMPLEX_RING;
1572     ALL_TAC] THEN
1573   GEN_REWRITE_TAC LAND_CONV [GSYM COMPLEX_MUL_LID] THEN
1574   MATCH_MP_TAC LIM_COMPLEX_MUL THEN CONJ_TAC THENL
1575    [SIMP_TAC[GSYM CEXP_VSUM; FINITE_NUMSEG; GSYM CEXP_ADD] THEN
1576     REWRITE_TAC[GSYM CEXP_0] THEN
1577     MATCH_MP_TAC(ISPEC `cexp` LIM_CONTINUOUS_FUNCTION) THEN
1578     SIMP_TAC[CONTINUOUS_AT_CEXP; VSUM_COMPLEX_LMUL; FINITE_NUMSEG] THEN
1579     REWRITE_TAC[COMPLEX_RING
1580      `--w * z + z * x + --y * z:complex = z * ((x - y) - w)`] THEN
1581     MATCH_MP_TAC LIM_NULL_COMPLEX_LMUL THEN
1582     REWRITE_TAC[GSYM LIM_NULL_COMPLEX] THEN
1583     REWRITE_TAC[GSYM CX_INV; VSUM_CX] THEN
1584     REWRITE_TAC[GSYM CX_SUB; REWRITE_RULE[o_DEF] (GSYM REALLIM_COMPLEX)] THEN
1585     REWRITE_TAC[EULER_MASCHERONI];
1586     MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN EXISTS_TAC
1587      `\n. (Cx(&n) cpow z * Cx(&(FACT n))) /
1588           cproduct(0..n) (\m. z + Cx(&m))` THEN
1589     REWRITE_TAC[CGAMMA] THEN
1590     REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
1591     X_GEN_TAC `n:num` THEN DISCH_TAC THEN
1592     SIMP_TAC[CPRODUCT_CLAUSES_LEFT; LE_0] THEN
1593     REWRITE_TAC[COMPLEX_ADD_RID; ADD_CLAUSES] THEN
1594     REWRITE_TAC[complex_div; COMPLEX_INV_MUL; GSYM COMPLEX_MUL_ASSOC] THEN
1595     AP_TERM_TAC THEN GEN_REWRITE_TAC LAND_CONV
1596      [COMPLEX_RING `a * b * c:complex = b * a * c`] THEN
1597     AP_TERM_TAC THEN SIMP_TAC[CPRODUCT_INV; FINITE_NUMSEG] THEN
1598     GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM COMPLEX_INV_INV] THEN
1599     REWRITE_TAC[GSYM COMPLEX_INV_MUL] THEN AP_TERM_TAC THEN
1600     MATCH_MP_TAC(COMPLEX_FIELD
1601      `~(z = Cx(&0)) /\ z * x = y ==> inv z * y = x`) THEN
1602     REWRITE_TAC[CX_INJ; REAL_OF_NUM_EQ; FACT_NZ] THEN
1603     CONV_TAC SYM_CONV THEN SPEC_TAC(`n:num`,`p:num`) THEN
1604     INDUCT_TAC THEN REWRITE_TAC[FACT; CPRODUCT_CLAUSES_NUMSEG; ARITH] THEN
1605     REWRITE_TAC[ARITH_RULE `1 <= SUC n`; COMPLEX_MUL_LID] THEN
1606     ASM_REWRITE_TAC[CX_MUL; GSYM REAL_OF_NUM_MUL] THEN
1607     MATCH_MP_TAC(COMPLEX_RING
1608      `d * e:complex = c ==> (a * b) * c = (d * a) * b * e`) THEN
1609     MATCH_MP_TAC(COMPLEX_FIELD
1610      `~(p = Cx(&0)) ==> p * (Cx(&1) + z * inv p) = z + p`) THEN
1611     REWRITE_TAC[CX_INJ; REAL_OF_NUM_EQ; NOT_SUC]]);;
1612
1613 (* ------------------------------------------------------------------------- *)
1614 (* Sometimes the reciprocal function is convenient, since it's entire.       *)
1615 (* ------------------------------------------------------------------------- *)
1616
1617 let COMPLEX_DIFFERENTIABLE_AT_RECIP_CGAMMA = prove
1618  (`!z. (inv o cgamma) complex_differentiable (at z)`,
1619   GEN_TAC THEN ASM_CASES_TAC `!n. ~(z + Cx(&n) = Cx(&0))` THENL
1620    [MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_COMPOSE_AT THEN
1621     ASM_SIMP_TAC[COMPLEX_DIFFERENTIABLE_AT_CGAMMA] THEN
1622     GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN
1623     MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_INV_AT THEN
1624     REWRITE_TAC[COMPLEX_DIFFERENTIABLE_ID; CGAMMA_EQ_0] THEN
1625     ASM_MESON_TAC[];
1626     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN
1627     REWRITE_TAC[COMPLEX_RING `z + w = Cx(&0) <=> z = --w`] THEN
1628     DISCH_THEN(X_CHOOSE_THEN `n:num` SUBST1_TAC) THEN
1629     REWRITE_TAC[complex_differentiable; HAS_COMPLEX_DERIVATIVE_AT] THEN
1630     REWRITE_TAC[o_DEF; CGAMMA_POLES; COMPLEX_INV_0; complex_div;
1631                 COMPLEX_MUL_LZERO; COMPLEX_SUB_RZERO] THEN
1632     SIMP_TAC[GSYM COMPLEX_INV_MUL; COMPLEX_RING `x - --z:complex = x + z`] THEN
1633     EXISTS_TAC `inv(--Cx(&1) pow n / Cx(&(FACT n)))` THEN
1634     MATCH_MP_TAC LIM_COMPLEX_INV THEN
1635     REWRITE_TAC[COMPLEX_DIV_EQ_0; COMPLEX_POW_EQ_0; CX_INJ] THEN
1636     REWRITE_TAC[REAL_OF_NUM_EQ; FACT_NZ] THEN
1637     ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN
1638     REWRITE_TAC[CGAMMA_SIMPLE_POLES] THEN CONV_TAC COMPLEX_RING]);;
1639
1640 let COMPLEX_DIFFERENTIABLE_WITHIN_RECIP_CGAMMA = prove
1641  (`!z s. (inv o cgamma) complex_differentiable at z within s`,
1642   SIMP_TAC[COMPLEX_DIFFERENTIABLE_AT_WITHIN;
1643            COMPLEX_DIFFERENTIABLE_AT_RECIP_CGAMMA]);;
1644
1645 let HOLOMORPHIC_ON_RECIP_CGAMMA = prove
1646  (`!s. (inv o cgamma) holomorphic_on s`,
1647   REWRITE_TAC[HOLOMORPHIC_ON_DIFFERENTIABLE] THEN
1648   REWRITE_TAC[COMPLEX_DIFFERENTIABLE_WITHIN_RECIP_CGAMMA]);;
1649
1650 let CONTINUOUS_AT_RECIP_CGAMMA = prove
1651  (`!z. (inv o cgamma) continuous at z`,
1652   SIMP_TAC[COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_AT;
1653            COMPLEX_DIFFERENTIABLE_AT_RECIP_CGAMMA]);;
1654
1655 let CONTINUOUS_WITHIN_RECIP_CGAMMA = prove
1656  (`!z s. (inv o cgamma) continuous at z within s`,
1657   SIMP_TAC[COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN;
1658            COMPLEX_DIFFERENTIABLE_WITHIN_RECIP_CGAMMA]);;
1659
1660 let CONTINUOUS_ON_RECIP_CGAMMA = prove
1661  (`!s. (inv o cgamma) continuous_on s`,
1662   SIMP_TAC[HOLOMORPHIC_ON_IMP_CONTINUOUS_ON; HOLOMORPHIC_ON_RECIP_CGAMMA]);;
1663
1664 let RECIP_CGAMMA = prove
1665  (`!z. ((\n. cproduct(0..n) (\m. z + Cx(&m)) /
1666             (Cx(&n) cpow z * Cx(&(FACT n)))) --> inv(cgamma z))
1667        sequentially`,
1668   GEN_TAC THEN ASM_CASES_TAC `!n. ~(z + Cx(&n) = Cx(&0))` THENL
1669    [ONCE_REWRITE_TAC[GSYM COMPLEX_INV_INV] THEN
1670     MATCH_MP_TAC LIM_COMPLEX_INV THEN
1671     REWRITE_TAC[COMPLEX_INV_INV; CGAMMA; COMPLEX_INV_DIV; CGAMMA_EQ_0] THEN
1672     ASM_MESON_TAC[];
1673     SUBGOAL_THEN `cgamma z = Cx(&0)` SUBST1_TAC THENL
1674      [ASM_MESON_TAC[CGAMMA_EQ_0]; REWRITE_TAC[COMPLEX_INV_0]] THEN
1675     MATCH_MP_TAC LIM_EVENTUALLY THEN
1676     REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; COMPLEX_DIV_EQ_0; COMPLEX_ENTIRE] THEN
1677     SIMP_TAC[CPRODUCT_EQ_0; IN_NUMSEG; FINITE_NUMSEG; LE_0] THEN
1678     ASM_MESON_TAC[]]);;
1679
1680 let RECIP_CGAMMA_WEIERSTRASS = prove
1681  (`!n. ((\n. (z * cexp(Cx euler_mascheroni * z) *
1682              cproduct(1..n) (\k. (Cx(&1) + z / Cx(&k)) / cexp(z / Cx(&k)))))
1683         --> inv(cgamma z)) sequentially`,
1684   GEN_TAC THEN ASM_CASES_TAC `?n. z + Cx(&n) = Cx(&0)` THENL
1685    [FIRST_X_ASSUM(X_CHOOSE_TAC `N:num`) THEN
1686     MATCH_MP_TAC LIM_EVENTUALLY THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
1687     EXISTS_TAC `N:num` THEN X_GEN_TAC `n:num` THEN REWRITE_TAC[GE] THEN
1688     DISCH_TAC THEN SUBGOAL_THEN `cgamma(z) = Cx(&0)` SUBST1_TAC THENL
1689      [ASM_MESON_TAC[CGAMMA_EQ_0]; REWRITE_TAC[COMPLEX_INV_0]] THEN
1690     REWRITE_TAC[COMPLEX_ENTIRE; COMPLEX_DIV_EQ_0] THEN
1691     ASM_CASES_TAC `N = 0` THENL [ASM_MESON_TAC[COMPLEX_ADD_RID]; ALL_TAC] THEN
1692     REPEAT DISJ2_TAC THEN
1693     SIMP_TAC[CPRODUCT_EQ_0; FINITE_NUMSEG; IN_NUMSEG] THEN
1694     EXISTS_TAC `N:num` THEN ASM_SIMP_TAC[LE_1; COMPLEX_DIV_EQ_0] THEN
1695     DISJ1_TAC THEN MATCH_MP_TAC(COMPLEX_FIELD
1696      `x + n = Cx(&0) /\ ~(n = Cx(&0)) ==> Cx(&1) + x / n = Cx(&0)`) THEN
1697     ASM_REWRITE_TAC[CX_INJ; REAL_OF_NUM_EQ];
1698     GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV o ABS_CONV)
1699      [GSYM COMPLEX_INV_INV] THEN
1700     MATCH_MP_TAC LIM_COMPLEX_INV THEN
1701     ASM_REWRITE_TAC[CGAMMA_EQ_0] THEN
1702     SIMP_TAC[COMPLEX_INV_MUL; GSYM CEXP_NEG; GSYM CPRODUCT_INV;
1703              FINITE_NUMSEG; GSYM COMPLEX_MUL_LNEG; COMPLEX_INV_DIV] THEN
1704     REWRITE_TAC[SIMPLE_COMPLEX_ARITH `inv z * a * b:complex = a / z * b`] THEN
1705     REWRITE_TAC[CGAMMA_WEIERSTRASS]]);;
1706
1707 (* ------------------------------------------------------------------------- *)
1708 (* The real gamma function.                                                  *)
1709 (* ------------------------------------------------------------------------- *)
1710
1711 let gamma = new_definition
1712  `gamma(x) = Re(cgamma(Cx x))`;;
1713
1714 let CX_GAMMA = prove
1715  (`!x. Cx(gamma x) = cgamma(Cx x)`,
1716     REWRITE_TAC[gamma] THEN MESON_TAC[REAL; REAL_CX; REAL_GAMMA]);;
1717
1718 let GAMMA = prove
1719  (`!x. ((\n. (&n rpow x * &(FACT n)) / product(0..n) (\m. x + &m))
1720         ---> gamma(x)) sequentially`,
1721   REWRITE_TAC[REALLIM_COMPLEX; o_DEF; CX_GAMMA; CX_DIV] THEN
1722   X_GEN_TAC `x:real` THEN MP_TAC(SPEC `Cx x` CGAMMA) THEN
1723   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
1724   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
1725   SIMP_TAC[CX_MUL; CX_PRODUCT; FINITE_NUMSEG; CX_ADD; cpow; rpow;
1726            CX_INJ; REAL_OF_NUM_EQ; REAL_OF_NUM_LT; LE_1; CX_LOG; CX_EXP]);;
1727
1728 let GAMMA_EQ_0 = prove
1729  (`!x. gamma(x) = &0 <=> ?n. x + &n = &0`,
1730   REWRITE_TAC[GSYM CX_INJ; CX_ADD; CX_GAMMA; CGAMMA_EQ_0]);;
1731
1732 let REAL_DIFFERENTIABLE_AT_GAMMA = prove
1733  (`!x. (!n. ~(x + &n = &0)) ==> gamma real_differentiable atreal x`,
1734   REPEAT STRIP_TAC THEN
1735   MP_TAC(SPEC `Cx x` COMPLEX_DIFFERENTIABLE_AT_CGAMMA) THEN
1736   ASM_REWRITE_TAC[GSYM CX_ADD; CX_INJ; complex_differentiable] THEN
1737   REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_AT; real_differentiable] THEN
1738   REWRITE_TAC[GSYM CX_GAMMA; HAS_REAL_DERIVATIVE_ATREAL] THEN
1739   REWRITE_TAC[REALLIM_COMPLEX; o_DEF] THEN
1740   DISCH_THEN(X_CHOOSE_TAC `f':complex`) THEN
1741   SUBGOAL_THEN `real f'` ASSUME_TAC THENL
1742    [MATCH_MP_TAC(ISPEC `at (Cx x) within real` REAL_LIM) THEN
1743     EXISTS_TAC `\z. (cgamma z - Cx(gamma x)) / (z - Cx x)` THEN
1744     ASM_SIMP_TAC[LIM_AT_WITHIN] THEN REWRITE_TAC[WITHIN; AT] THEN
1745     SIMP_TAC[TRIVIAL_LIMIT_WITHIN_CONVEX; CONVEX_REAL] THEN
1746     REWRITE_TAC[TRIVIAL_LIMIT_WITHIN_REAL; REAL_CX] THEN
1747     REWRITE_TAC[SET_RULE `p /\ x IN real <=> real x /\ p`] THEN
1748     SIMP_TAC[REAL_EXISTS; IMP_CONJ; LEFT_IMP_EXISTS_THM] THEN
1749     REWRITE_TAC[GSYM REAL_EXISTS; GSYM CX_SUB; GSYM CX_DIV;
1750                 GSYM CX_GAMMA; REAL_CX] THEN
1751     REPEAT(EXISTS_TAC `Cx(x + &1)`) THEN
1752     REWRITE_TAC[REAL_LE_REFL; REAL_CX; DIST_CX] THEN REAL_ARITH_TAC;
1753     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_EXISTS]) THEN
1754     DISCH_THEN(X_CHOOSE_THEN `f':real` SUBST_ALL_TAC) THEN
1755     EXISTS_TAC `f':real` THEN REWRITE_TAC[LIM_ATREAL_ATCOMPLEX] THEN
1756     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_AT]) THEN
1757     REWRITE_TAC[LIM_WITHIN; o_DEF; CX_SUB; CX_DIV; CX_GAMMA] THEN
1758     SIMP_TAC[IMP_CONJ; IN; REAL_EXISTS; LEFT_IMP_EXISTS_THM; RE_CX] THEN
1759     MESON_TAC[]]);;
1760
1761 let REAL_DIFFERENTIABLE_WITHIN_GAMMA = prove
1762  (`!x s. (!n. ~(x + &n = &0)) ==> gamma real_differentiable atreal x within s`,
1763   SIMP_TAC[REAL_DIFFERENTIABLE_AT_GAMMA;
1764            REAL_DIFFERENTIABLE_ATREAL_WITHIN]);;
1765
1766 let REAL_DIFFERENTIABLE_ON_GAMMA = prove
1767  (`!s. s SUBSET {x | !n. ~(x + &n = &0)} ==> gamma real_differentiable_on s`,
1768   SIMP_TAC[SUBSET; IN_ELIM_THM; REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE;
1769            REAL_DIFFERENTIABLE_WITHIN_GAMMA]);;
1770
1771 let REAL_CONTINUOUS_ATREAL_GAMMA = prove
1772  (`!x. (!n. ~(x + &n = &0)) ==> gamma real_continuous atreal x`,
1773   REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_COMPLEX_CONTINUOUS_ATREAL] THEN
1774   REWRITE_TAC[o_DEF; CX_GAMMA] THEN
1775   GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
1776   MATCH_MP_TAC CONTINUOUS_WITHIN_COMPOSE THEN
1777   SIMP_TAC[LINEAR_CONTINUOUS_WITHIN; REWRITE_RULE[o_DEF] LINEAR_CX_RE] THEN
1778   MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN
1779   MATCH_MP_TAC CONTINUOUS_AT_CGAMMA THEN
1780   ASM_REWRITE_TAC[GSYM CX_ADD; RE_CX; CX_INJ]);;
1781
1782 let REAL_CONTINUOUS_WITHIN_GAMMA = prove
1783  (`!x s. (!n. ~(x + &n = &0)) ==> gamma real_continuous atreal x within s`,
1784   SIMP_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL; REAL_CONTINUOUS_ATREAL_GAMMA]);;
1785
1786 let REAL_CONTINUOUS_ON_GAMMA = prove
1787  (`!s. s SUBSET {x | !n. ~(x + &n = &0)} ==> gamma real_continuous_on s`,
1788   SIMP_TAC[SUBSET; IN_ELIM_THM; REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
1789            REAL_CONTINUOUS_WITHIN_GAMMA]);;
1790
1791 let GAMMA_RECURRENCE_ALT = prove
1792  (`!x. gamma(x) = gamma(x + &1) / x`,
1793   REWRITE_TAC[GSYM CX_INJ; CX_DIV; CX_GAMMA; CX_ADD] THEN
1794   REWRITE_TAC[GSYM CGAMMA_RECURRENCE_ALT]);;
1795
1796 let GAMMA_1 = prove
1797  (`gamma(&1) = &1`,
1798   REWRITE_TAC[GSYM CX_INJ; CX_GAMMA; CGAMMA_1]);;
1799
1800 let GAMMA_RECURRENCE = prove
1801  (`!x. gamma(x + &1) = if x = &0 then &1 else x * gamma(x)`,
1802   REWRITE_TAC[GSYM CX_INJ; CX_GAMMA] THEN
1803   GEN_TAC THEN GEN_REWRITE_TAC RAND_CONV [COND_RAND] THEN
1804   REWRITE_TAC[CX_MUL; CX_GAMMA; CX_ADD; GSYM CGAMMA_RECURRENCE]);;
1805
1806 let GAMMA_FACT = prove
1807  (`!n. gamma(&(n + 1)) = &(FACT n)`,
1808   REWRITE_TAC[GSYM CX_INJ; CX_GAMMA; CGAMMA_FACT]);;
1809
1810 let GAMMA_POLES = prove
1811  (`!n. gamma(--(&n)) = &0`,
1812   REWRITE_TAC[GSYM CX_INJ; CX_GAMMA; CGAMMA_POLES; CX_NEG]);;
1813
1814 let GAMMA_SIMPLE_POLES = prove
1815  (`!n. ((\x. (x + &n) * gamma x) ---> -- &1 pow n / &(FACT n))
1816        (atreal(-- &n))`,
1817   REWRITE_TAC[REALLIM_COMPLEX; o_DEF; LIM_ATREAL_ATCOMPLEX] THEN
1818   GEN_TAC THEN
1819   REWRITE_TAC[CX_MUL; CX_ADD; CX_GAMMA; CX_DIV; CX_POW; CX_NEG] THEN
1820   SUBGOAL_THEN
1821    `(\z. (Cx(Re z) + Cx(&n)) * cgamma(Cx(Re z))) =
1822     (\z. (z + Cx(&n)) * cgamma z) o (Cx o Re)`
1823   SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
1824   MATCH_MP_TAC LIM_COMPOSE_WITHIN THEN
1825   MAP_EVERY EXISTS_TAC [`(:complex)`; `--Cx(&n)`] THEN
1826   REWRITE_TAC[CGAMMA_SIMPLE_POLES; WITHIN_UNIV] THEN
1827   REWRITE_TAC[EVENTUALLY_WITHIN; o_DEF; IN_UNIV; GSYM DIST_NZ] THEN
1828   REWRITE_TAC[real; IN; GSYM CX_NEG; CX_INJ] THEN
1829   REWRITE_TAC[COMPLEX_EQ; RE_CX; IM_CX] THEN
1830   CONJ_TAC THENL [ALL_TAC; MESON_TAC[REAL_LT_01]] THEN
1831   MATCH_MP_TAC LIM_AT_WITHIN THEN LIM_TAC THEN REWRITE_TAC[RE_CX] THEN
1832   MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
1833   REWRITE_TAC[REWRITE_RULE[o_DEF] LINEAR_CX_RE]);;
1834
1835 let GAMMA_POS_LE = prove
1836  (`!x. &0 <= x ==> &0 <= gamma x`,
1837   SIMP_TAC[gamma; RE_POS_CGAMMA_REAL; RE_CX; REAL_CX]);;
1838
1839 let GAMMA_POS_LT = prove
1840  (`!x. &0 < x ==> &0 < gamma x`,
1841   SIMP_TAC[REAL_ARITH `&0 < x <=> &0 <= x /\ ~(x = &0)`; GAMMA_POS_LE] THEN
1842   REWRITE_TAC[GAMMA_EQ_0] THEN REAL_ARITH_TAC);;
1843
1844 let GAMMA_LEGENDRE_ALT = prove
1845  (`!x. gamma(x) * gamma(x + &1 / &2) =
1846        &2 rpow (&1 - &2 * x) *  gamma(&1 / &2) * gamma(&2 * x)`,
1847   REWRITE_TAC[GSYM CX_INJ; CX_GAMMA; CX_ADD;
1848               CX_DIV; CGAMMA_LEGENDRE_ALT; CX_MUL] THEN
1849   REWRITE_TAC[cpow; rpow; CX_INJ; REAL_OF_NUM_LT; REAL_OF_NUM_EQ; ARITH] THEN
1850   SIMP_TAC[CX_MUL; CX_EXP; CX_SUB; CX_LOG; REAL_OF_NUM_LT; ARITH]);;
1851
1852 let GAMMA_REFLECTION = prove
1853  (`!x. gamma(x) * gamma(&1 - x) = pi / sin(pi * x)`,
1854   SIMP_TAC[GSYM CX_INJ; CX_MUL; CX_DIV; CX_GAMMA; CX_SIN; CX_SUB] THEN
1855   REWRITE_TAC[CGAMMA_REFLECTION]);;
1856
1857 let GAMMA_HALF = prove
1858  (`gamma(&1 / &2) = sqrt pi`,
1859   REWRITE_TAC[GSYM CX_INJ; CX_DIV; CX_GAMMA; CGAMMA_HALF]);;
1860
1861 let GAMMA_LEGENDRE = prove
1862  (`!x. gamma(x) * gamma(x + &1 / &2) =
1863        &2 rpow (&1 - &2 * x) * sqrt pi * gamma(&2 * x)`,
1864   REWRITE_TAC[GAMMA_LEGENDRE_ALT; GAMMA_HALF]);;
1865
1866 let GAMMA_WEIERSTRASS = prove
1867  (`!x. ((\n. exp(--(euler_mascheroni) * x) / x *
1868              product(1..n) (\k. exp(x / &k) / (&1 + x / &k)))
1869        ---> gamma x) sequentially`,
1870   REWRITE_TAC[REALLIM_COMPLEX; o_DEF; CX_GAMMA; CX_DIV] THEN
1871   X_GEN_TAC `x:real` THEN MP_TAC(SPEC `Cx x` CGAMMA_WEIERSTRASS) THEN
1872   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
1873   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
1874   SIMP_TAC[CX_MUL; CX_DIV; CX_EXP; CX_NEG; CX_PRODUCT; FINITE_NUMSEG;
1875            CX_ADD]);;
1876
1877 (* ------------------------------------------------------------------------- *)
1878 (* Characterization of the real gamma function using log-convexity.          *)
1879 (* ------------------------------------------------------------------------- *)
1880
1881 let REAL_LOG_CONVEX_GAMMA = prove
1882  (`!s. (!x. x IN s ==> &0 < x) ==> gamma real_log_convex_on s`,
1883   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LOG_CONVEX_ON_SUBSET THEN
1884   EXISTS_TAC `{x | &0 < x}` THEN
1885   ASM_REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN POP_ASSUM(K ALL_TAC) THEN
1886   MATCH_MP_TAC(ISPEC `sequentially` REAL_LOG_CONVEX_LIM) THEN
1887   EXISTS_TAC `\n x. (&n rpow x * &(FACT n)) / product(0..n) (\m. x + &m)` THEN
1888   REWRITE_TAC[GAMMA; TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
1889   EXISTS_TAC `1` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
1890   REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC] THEN
1891   REPEAT(MATCH_MP_TAC REAL_LOG_CONVEX_MUL THEN CONJ_TAC) THEN
1892   SIMP_TAC[REAL_LOG_CONVEX_CONST; REAL_POS] THEN
1893   ASM_SIMP_TAC[REAL_LOG_CONVEX_RPOW_RIGHT; REAL_OF_NUM_LT; LE_1] THEN
1894   SIMP_TAC[GSYM PRODUCT_INV; FINITE_NUMSEG] THEN
1895   MATCH_MP_TAC REAL_LOG_CONVEX_PRODUCT THEN
1896   REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN X_GEN_TAC `k:num` THEN
1897   STRIP_TAC THEN
1898   MATCH_MP_TAC MIDPOINT_REAL_LOG_CONVEX THEN
1899   ASM_SIMP_TAC[IN_ELIM_THM; REAL_LT_INV_EQ; REAL_LTE_ADD; REAL_POS] THEN
1900   REPEAT CONJ_TAC THENL
1901    [MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON THEN
1902     REWRITE_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; IN_ELIM_THM] THEN
1903     REPEAT STRIP_TAC THEN REAL_DIFFERENTIABLE_TAC THEN ASM_REAL_ARITH_TAC;
1904     REWRITE_TAC[is_realinterval; IN_ELIM_THM] THEN REAL_ARITH_TAC;
1905     REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_INV_MUL; REAL_POW_INV] THEN
1906     MATCH_MP_TAC REAL_LE_INV2 THEN
1907     ASM_SIMP_TAC[REAL_LT_MUL; REAL_LTE_ADD; REAL_POS] THEN
1908     REWRITE_TAC[REAL_LE_POW_2; REAL_ARITH
1909      `(x + &k) * (y + &k) <= ((x + y) / &2 + &k) pow 2 <=>
1910       &0 <= (x - y) pow 2`]]);;
1911
1912 let GAMMA_REAL_LOG_CONVEX_UNIQUE = prove
1913  (`!f:real->real.
1914         f(&1) = &1 /\ (!x. &0 < x ==> f(x + &1) = x * f(x)) /\
1915         (!x. &0 < x ==> &0 < f x) /\ f real_log_convex_on {x | &0 < x}
1916         ==> !x. &0 < x ==> f x = gamma x`,
1917   GEN_TAC THEN STRIP_TAC THEN
1918   SUBGOAL_THEN `!x. &0 < x /\ x <= &1 ==> f x = gamma x` ASSUME_TAC THENL
1919    [ALL_TAC;
1920     SUBGOAL_THEN
1921      `!y. &0 < y /\ y <= &1 ==> !n. f(&n + y) = gamma(&n + y)`
1922     ASSUME_TAC THENL
1923      [GEN_TAC THEN STRIP_TAC THEN
1924       INDUCT_TAC THEN ASM_SIMP_TAC[REAL_ADD_LID] THEN
1925       REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN
1926       REWRITE_TAC[REAL_ARITH `(n + &1) + x = (n + x) + &1`] THEN
1927       ASM_SIMP_TAC[GAMMA_RECURRENCE; REAL_LET_ADD; REAL_POS] THEN
1928       ASM_REAL_ARITH_TAC;
1929       X_GEN_TAC `x:real` THEN DISCH_TAC THEN
1930       MP_TAC(SPEC `x:real` FLOOR_POS) THEN ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN
1931       DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN
1932       MP_TAC(SPEC `x:real` FLOOR_FRAC) THEN ASM_REWRITE_TAC[] THEN
1933       ASM_CASES_TAC `frac x = &0` THEN ASM_REWRITE_TAC[REAL_LT_LE] THENL
1934        [ASM_CASES_TAC `n = 0` THEN
1935         ASM_SIMP_TAC[REAL_ADD_RID; REAL_LT_IMP_NZ] THEN
1936         SUBGOAL_THEN `&(n - 1) + &1 = &n`
1937          (fun th -> ASM_MESON_TAC[th; REAL_LE_REFL; REAL_LT_01]) THEN
1938         ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUB; LE_1] THEN REAL_ARITH_TAC;
1939         STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `frac x`) THEN
1940         ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ASM_MESON_TAC[]]]]] THEN
1941   X_GEN_TAC `x:real` THEN STRIP_TAC THEN
1942   ASM_CASES_TAC `x = &1` THEN ASM_REWRITE_TAC[GAMMA_1] THEN
1943   SUBGOAL_THEN `&0 < x` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
1944   MATCH_MP_TAC(REAL_FIELD `&0 < g /\ f / g = &1 ==> f = g`) THEN
1945   ASM_SIMP_TAC[GAMMA_POS_LT] THEN
1946   MATCH_MP_TAC(ISPEC `sequentially` REALLIM_UNIQUE) THEN
1947   EXISTS_TAC
1948    `\n. f(x) / ((&n rpow x * &(FACT n)) / product (0..n) (\m. x + &m))` THEN
1949   REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
1950   ASM_SIMP_TAC[REALLIM_DIV; REALLIM_CONST; GAMMA_POS_LT;
1951                GAMMA; REAL_LT_IMP_NZ] THEN
1952   ONCE_REWRITE_TAC[REALLIM_NULL] THEN
1953   MATCH_MP_TAC REALLIM_NULL_COMPARISON THEN
1954   EXISTS_TAC `\n. x * inv(&n)` THEN
1955   SIMP_TAC[REALLIM_NULL_LMUL; REALLIM_1_OVER_N] THEN
1956   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `2` THEN
1957   SUBGOAL_THEN
1958    `!n. &2 <= &n
1959         ==> log(f(&n)) - log(f(&n - &1))
1960               <= (log(f(&n + x)) - log(f(&n))) / x /\
1961             (log(f(&n + x)) - log(f(&n))) / x
1962               <= log(f(&n + &1)) - log(f(&n))`
1963   MP_TAC THENL
1964    [MP_TAC(SPECL [`f:real->real`; `{x | &0 < x}`] REAL_LOG_CONVEX_ON) THEN
1965     ASM_REWRITE_TAC[IN_ELIM_THM] THEN ANTS_TAC THENL
1966      [REWRITE_TAC[is_realinterval; IN_ELIM_THM] THEN REAL_ARITH_TAC;
1967       DISCH_TAC] THEN
1968     MAP_EVERY (MP_TAC o SPECL [`log o f:real->real`; `{x | &0 < x}`])
1969      [REAL_CONVEX_ON_LEFT_SECANT; REAL_CONVEX_ON_RIGHT_SECANT] THEN
1970     ASM_REWRITE_TAC[] THEN
1971     DISCH_THEN(LABEL_TAC "L") THEN DISCH_THEN(LABEL_TAC "R") THEN
1972     REPEAT STRIP_TAC THENL
1973      [USE_THEN "L" (MP_TAC o SPECL [`&n - &1`; `&n + x`; `&n`]) THEN
1974       USE_THEN "R" (MP_TAC o SPECL [`&n - &1`; `&n + x`; `&n`]) THEN
1975       REWRITE_TAC[IN_ELIM_THM; IN_REAL_SEGMENT; o_THM] THEN
1976       ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
1977       REWRITE_TAC[REAL_ARITH `abs(x - (x - &1)) = &1`; REAL_DIV_1] THEN
1978       DISCH_TAC THEN ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
1979       ASM_SIMP_TAC[REAL_ARITH `&0 < x ==> abs((n + x) - n) = x`] THEN
1980       ASM_REAL_ARITH_TAC;
1981       ASM_CASES_TAC `x = &1` THEN
1982       ASM_REWRITE_TAC[REAL_LE_REFL; REAL_DIV_1] THEN
1983       USE_THEN "R" (MP_TAC o SPECL [`&n`; `&n + &1`; `&n + x`]) THEN
1984       REWRITE_TAC[IN_ELIM_THM; IN_REAL_SEGMENT; o_THM] THEN
1985       ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
1986       REWRITE_TAC[REAL_ARITH `abs((n + &1) - n) = &1`; REAL_DIV_1] THEN
1987       ASM_SIMP_TAC[REAL_ARITH `&0 < x ==> abs((n + x) - n) = x`] THEN
1988       ASM_REAL_ARITH_TAC];
1989     ALL_TAC] THEN
1990   ASM_SIMP_TAC[GSYM LOG_DIV; REAL_LT_MUL;
1991     REAL_ARITH `&2 <= x ==> &0 < x /\ &0 < x + &1 /\ &0 < x - &1`;
1992     REAL_FIELD `&0 < x ==> (n * x) / x = n`] THEN
1993   SUBGOAL_THEN
1994    `!n. &2 <= n ==> f(n - &1) = f(n) / (n - &1)` (fun th -> SIMP_TAC[th])
1995   THENL
1996    [REPEAT STRIP_TAC THEN
1997     SUBGOAL_THEN `(f:real->real) n = f((n - &1) + &1)` SUBST1_TAC THENL
1998      [AP_TERM_TAC THEN REAL_ARITH_TAC;
1999       ASM_SIMP_TAC[REAL_ARITH `&2 <= n ==> &0 < n - &1`] THEN
2000       UNDISCH_TAC `&2 <= n` THEN CONV_TAC REAL_FIELD];
2001     ASM_SIMP_TAC[REAL_ARITH `&2 <= x ==> &0 < x`; REAL_FIELD
2002      `&0 < x /\ &2 <= y ==> x / (x / (y - &1)) = y - &1`] THEN
2003     ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ]] THEN
2004   SIMP_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_SUB;
2005            ARITH_RULE `2 <= n ==> 1 <= n`] THEN
2006   REWRITE_TAC[REAL_LE_SUB_LADD; REAL_LE_SUB_RADD] THEN
2007   SUBGOAL_THEN
2008    `!n. 0 < n ==> f(&n) = &(FACT(n - 1))`
2009    (fun th -> SIMP_TAC[ARITH_RULE `2 <= n ==> 0 < n /\ 0 < n - 1`; th])
2010   THENL
2011    [INDUCT_TAC THEN REWRITE_TAC[ARITH; LT_0] THEN
2012     ASM_CASES_TAC `n = 0` THEN
2013     ASM_REWRITE_TAC[REAL_ADD_LID; FACT; ARITH] THEN
2014     ASM_SIMP_TAC[ARITH_RULE `~(n = 0) ==> SUC n - 1 = SUC(n - 1)`] THEN
2015     ASM_SIMP_TAC[REAL_OF_NUM_LT; GSYM REAL_OF_NUM_SUC; LE_1; FACT] THEN
2016     ASM_SIMP_TAC[ARITH_RULE `~(n = 0) ==> SUC(n - 1) = n`] THEN
2017     REWRITE_TAC[REAL_OF_NUM_MUL; MULT_SYM];
2018     ALL_TAC] THEN
2019   GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV o RAND_CONV o BINOP_CONV)
2020    [GSYM REAL_EXP_MONO_LE] THEN
2021   REWRITE_TAC[GSYM REAL_OF_NUM_LE] THEN
2022   ASM_SIMP_TAC[REAL_EXP_ADD; EXP_LOG; REAL_OF_NUM_LT; LE_1; FACT_NZ;
2023                ARITH_RULE `&2 <= &n /\ &0 < x ==> &0 < &n + x`] THEN
2024   REWRITE_TAC[REAL_OF_NUM_LE] THEN
2025   SUBGOAL_THEN
2026    `!n. 0 < n ==> f(&n + x) = product(0..n-1) (\k. x + &k) * f(x)`
2027    (fun th -> SIMP_TAC[ARITH_RULE `2 <= n ==> 0 < n`; th])
2028   THENL
2029    [INDUCT_TAC THEN REWRITE_TAC[ARITH] THEN
2030     DISCH_TAC THEN REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN
2031     ASM_CASES_TAC `n = 0` THENL
2032      [ASM_SIMP_TAC[REAL_ARITH `(&0 + &1) + x = x + &1`; ARITH] THEN
2033       REWRITE_TAC[PRODUCT_SING_NUMSEG; REAL_ADD_RID];
2034       ASM_SIMP_TAC[REAL_ARITH `(n + &1) + x = (n + x) + &1`;
2035                    REAL_LT_ADD; REAL_OF_NUM_LT; LE_1] THEN
2036       ASM_SIMP_TAC[ARITH_RULE `~(n = 0) ==> SUC n - 1 = SUC(n - 1)`] THEN
2037       REWRITE_TAC[PRODUCT_CLAUSES_NUMSEG; LE_0] THEN
2038       ASM_SIMP_TAC[ARITH_RULE `~(n = 0) ==> SUC(n - 1) = n`] THEN
2039       REWRITE_TAC[REAL_MUL_AC; REAL_ADD_AC]];
2040     DISCH_TAC] THEN
2041   X_GEN_TAC `n:num` THEN DISCH_TAC THEN
2042   MATCH_MP_TAC(REAL_ARITH
2043    `&1 <= x /\ x <= &1 + e ==> abs(x - &1) <= e`) THEN
2044   ASM_SIMP_TAC[REAL_OF_NUM_LE; REAL_FIELD
2045    `&2 <= n ==> &1 + x * inv n = (x + n) / n`] THEN
2046   REWRITE_TAC[real_div; REAL_INV_MUL; REAL_INV_INV] THEN
2047   ONCE_REWRITE_TAC[REAL_ARITH `f * (r * n) * p:real = (p * f) * r * n`] THEN
2048   REWRITE_TAC[GSYM REAL_INV_MUL] THEN REWRITE_TAC[GSYM real_div] THEN
2049   SUBGOAL_THEN `&0 < &n rpow x * &(FACT n)` ASSUME_TAC THENL
2050    [ASM_SIMP_TAC[REAL_LT_MUL; REAL_OF_NUM_LT; LE_1; FACT_NZ;
2051                  RPOW_POS_LT; ARITH_RULE `2 <= x ==> 0 < x`];
2052     ALL_TAC]  THEN
2053   CONJ_TAC THENL
2054    [ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_MUL_LID] THEN
2055     FIRST_X_ASSUM(MP_TAC o SPEC `n + 1`) THEN
2056     ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN(MP_TAC o CONJUNCT1)] THEN
2057     REWRITE_TAC[ADD_SUB] THEN
2058     ASM_SIMP_TAC[rpow; REAL_OF_NUM_LE; REAL_ARITH `&2 <= x ==> &0 < x`] THEN
2059     REWRITE_TAC[REAL_MUL_AC];
2060     ASM_SIMP_TAC[PRODUCT_CLAUSES_RIGHT; LE_0;
2061                  ARITH_RULE `2 <= n ==> 0 < n`] THEN
2062     REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC] THEN
2063     GEN_REWRITE_TAC LAND_CONV
2064      [REAL_ARITH `a * b * c * d:real = b * (a * c) * d`] THEN
2065     MATCH_MP_TAC REAL_LE_LMUL THEN
2066     CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2067     ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ] THEN
2068     FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN ASM_REWRITE_TAC[] THEN
2069     DISCH_THEN(MP_TAC o CONJUNCT2) THEN
2070     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
2071     SUBGOAL_THEN `FACT n = FACT(SUC(n - 1))` SUBST1_TAC THENL
2072      [AP_TERM_TAC THEN ASM_ARITH_TAC; REWRITE_TAC[FACT]] THEN
2073     ASM_SIMP_TAC[ARITH_RULE `2 <= n ==> SUC(n - 1) = n`] THEN
2074     MATCH_MP_TAC REAL_EQ_IMP_LE THEN
2075     SUBGOAL_THEN `&0 < &n` MP_TAC THENL
2076      [REWRITE_TAC[REAL_OF_NUM_LT] THEN ASM_ARITH_TAC;
2077       SIMP_TAC[rpow; GSYM REAL_OF_NUM_MUL; REAL_MUL_AC] THEN
2078       CONV_TAC REAL_FIELD]]);;
2079
2080 (* ------------------------------------------------------------------------- *)
2081 (* The integral definition, the current usual one and Euler's original one.  *)
2082 (* ------------------------------------------------------------------------- *)
2083
2084 let EULER_HAS_INTEGRAL_CGAMMA = prove
2085  (`!z. &0 < Re z
2086        ==> ((\t.  Cx(drop t) cpow (z - Cx(&1)) / cexp(Cx(drop t)))
2087             has_integral cgamma(z))
2088            {t | &0 <= drop t}`,
2089   let lemma0 = prove
2090    (`!z a b. &0 < Re z /\ &0 <= drop a
2091              ==> (\t. Cx(drop t) cpow z) continuous_on interval [a,b]`,
2092     REPEAT STRIP_TAC THEN
2093     REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
2094     X_GEN_TAC `t:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
2095     ASM_CASES_TAC `t:real^1 = vec 0` THENL
2096      [ASM_SIMP_TAC[CONTINUOUS_WITHIN; cpow; CX_INJ; GSYM LIFT_EQ; LIFT_NUM;
2097                    LIFT_DROP] THEN
2098       ONCE_REWRITE_TAC[LIM_NULL_COMPLEX_NORM] THEN
2099       REWRITE_TAC[NORM_CEXP] THEN
2100       MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN
2101       EXISTS_TAC `\t. Cx(exp(Re z * log(drop t)))` THEN
2102       EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN CONJ_TAC THENL
2103        [X_GEN_TAC `u:real^1` THEN
2104         REWRITE_TAC[IN_INTERVAL_1; DIST_0; NORM_POS_LT; GSYM DROP_EQ;
2105                     LIFT_DROP; DROP_VEC] THEN
2106         STRIP_TAC THEN SUBGOAL_THEN `&0 < drop u`
2107          (fun th -> SIMP_TAC[GSYM CX_LOG; RE_MUL_CX; th]) THEN
2108         ASM_REAL_ARITH_TAC;
2109         REWRITE_TAC[LIM_WITHIN; IN_INTERVAL_1; DIST_CX; REAL_SUB_RZERO] THEN
2110         X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2111         EXISTS_TAC `e rpow inv(Re z)` THEN
2112         ASM_SIMP_TAC[RPOW_POS_LT; DIST_0; REAL_ABS_EXP] THEN
2113         X_GEN_TAC `u:real^1` THEN STRIP_TAC THEN
2114         SUBGOAL_THEN `e = exp(log e)` SUBST1_TAC THENL
2115          [ASM_MESON_TAC[EXP_LOG]; REWRITE_TAC[REAL_EXP_MONO_LT]] THEN
2116         ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
2117         ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THEN
2118         REWRITE_TAC[REAL_ARITH `x / y:real = inv y * x`] THEN
2119         ASM_SIMP_TAC[GSYM LOG_RPOW] THEN MATCH_MP_TAC LOG_MONO_LT_IMP THEN
2120         SUBGOAL_THEN `norm u = drop u` (fun th -> ASM_MESON_TAC[th]) THEN
2121         REWRITE_TAC[NORM_REAL; GSYM drop] THEN ASM_REAL_ARITH_TAC];
2122       MATCH_MP_TAC DIFFERENTIABLE_IMP_CONTINUOUS_WITHIN THEN
2123       SUBGOAL_THEN
2124        `(\a. Cx(drop a) cpow z) = (\w. w cpow z) o Cx o drop`
2125       SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
2126       MATCH_MP_TAC DIFFERENTIABLE_CHAIN_WITHIN THEN CONJ_TAC THENL
2127        [MATCH_MP_TAC DIFFERENTIABLE_LINEAR THEN
2128         REWRITE_TAC[linear; o_DEF; DROP_ADD; DROP_CMUL; CX_ADD;
2129                     COMPLEX_CMUL; GSYM CX_MUL];
2130         MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_IMP_DIFFERENTIABLE THEN
2131         COMPLEX_DIFFERENTIABLE_TAC THEN DISCH_THEN(K ALL_TAC) THEN
2132         REWRITE_TAC[o_DEF; RE_CX] THEN
2133         ASM_REWRITE_TAC[REAL_LT_LE; GSYM LIFT_EQ; LIFT_NUM; LIFT_DROP] THEN
2134         ASM_REAL_ARITH_TAC]]) in
2135   let lemma1 = prove
2136    (`!n z. &0 < Re z
2137            ==> ((\t. Cx(drop t) cpow (z - Cx(&1)) * Cx(&1 - drop t) pow n)
2138                 has_integral Cx(&(FACT n)) / cproduct (0..n) (\m. z + Cx(&m)))
2139                 (interval[vec 0,vec 1])`,
2140     INDUCT_TAC THEN X_GEN_TAC `z:complex` THEN
2141     ASM_CASES_TAC `z = Cx(&0)` THEN ASM_REWRITE_TAC[RE_CX; REAL_LT_REFL] THEN
2142     DISCH_TAC THENL
2143      [REWRITE_TAC[complex_pow; COMPLEX_MUL_RID; CPRODUCT_CLAUSES_NUMSEG] THEN
2144       MP_TAC(ISPECL
2145        [`\t. Cx(drop t) cpow z / z`;
2146         `\t. Cx(drop t) cpow (z - Cx(&1))`;
2147         `vec 0:real^1`; `vec 1:real^1`]
2148           FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR) THEN
2149       REWRITE_TAC[DROP_VEC; CPOW_1; CPOW_0; FACT; complex_div] THEN
2150       REWRITE_TAC[COMPLEX_MUL_LZERO; COMPLEX_ADD_RID; COMPLEX_SUB_RZERO] THEN
2151       DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[REAL_POS] THEN CONJ_TAC THENL
2152        [MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_RMUL THEN
2153         MATCH_MP_TAC lemma0 THEN ASM_REWRITE_TAC[DROP_VEC; REAL_POS];
2154         REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN REPEAT STRIP_TAC THEN
2155         REWRITE_TAC[CX_SUB] THEN
2156         MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_REAL_COMPLEX THEN
2157         COMPLEX_DIFF_TAC THEN ASM_REWRITE_TAC[RE_CX] THEN
2158         UNDISCH_TAC `~(z = Cx(&0))` THEN CONV_TAC COMPLEX_FIELD];
2159       FIRST_X_ASSUM(MP_TAC o SPEC `z + Cx(&1)`) THEN
2160       REWRITE_TAC[RE_ADD; RE_CX; COMPLEX_RING `(z + Cx(&1)) - Cx(&1) = z`] THEN
2161       ANTS_TAC THENL [ASM_REAL_ARITH_TAC; DISCH_TAC] THEN
2162       MP_TAC(ISPECL
2163        [`complex_mul`;
2164         `\t. Cx(drop t) cpow z`;
2165         `\t. Cx(&1) / Cx(&n + &1) * Cx(&1 - drop t) pow (n + 1)`;
2166         `\t. z *  Cx(drop t) cpow (z - Cx(&1))`;
2167         `\t. --(Cx(&1 - drop t) pow n)`;
2168         `vec 0:real^1`; `vec 1:real^1`;
2169         `{vec 0:real^1}`;
2170         `Cx(&(FACT n)) / cproduct (0..n) (\m. (z + Cx(&1)) + Cx(&m))`]
2171         INTEGRATION_BY_PARTS) THEN
2172       REWRITE_TAC[BILINEAR_COMPLEX_MUL; DROP_VEC;
2173                   REAL_POS; COUNTABLE_SING] THEN
2174       REWRITE_TAC[CPOW_0; REAL_SUB_REFL; COMPLEX_POW_ZERO;
2175                   ADD_EQ_0; ARITH] THEN
2176       REWRITE_TAC[COMPLEX_MUL_LZERO; COMPLEX_MUL_RZERO; COMPLEX_SUB_LZERO] THEN
2177       REWRITE_TAC[COMPLEX_MUL_RNEG; COMPLEX_RING `--Cx(&0) - y = --y`] THEN
2178       ANTS_TAC THENL
2179        [REPEAT CONJ_TAC THENL
2180          [MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN
2181           ASM_SIMP_TAC[lemma0; DROP_VEC; REAL_POS] THEN
2182           MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_LMUL THEN
2183           MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_POW THEN
2184           REWRITE_TAC[CONTINUOUS_ON_CX_LIFT; LIFT_SUB; LIFT_DROP] THEN
2185           SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST];
2186           SIMP_TAC[IN_INTERVAL_1; DROP_VEC; IN_DIFF;
2187                    IN_SING; GSYM DROP_EQ] THEN
2188           REPEAT STRIP_TAC THEN REWRITE_TAC[CX_SUB] THEN
2189           MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_REAL_COMPLEX THEN
2190           COMPLEX_DIFF_TAC THEN
2191           ASM_REWRITE_TAC[RE_CX; COMPLEX_MUL_LID] THEN
2192           REWRITE_TAC[REAL_OF_NUM_ADD; ADD_SUB; COMPLEX_MUL_ASSOC] THEN
2193           MP_TAC(ARITH_RULE `~(n + 1 = 0)`) THEN
2194           REWRITE_TAC[GSYM REAL_OF_NUM_EQ; GSYM CX_INJ] THEN
2195           CONV_TAC COMPLEX_FIELD;
2196           MATCH_MP_TAC HAS_INTEGRAL_NEG THEN ASM_REWRITE_TAC[]];
2197         DISCH_THEN(MP_TAC o SPEC `Cx(&n + &1) / z` o
2198           MATCH_MP HAS_INTEGRAL_COMPLEX_LMUL) THEN
2199         ASM_SIMP_TAC[REAL_ARITH `~(&n + &1 = &0)`; CX_INJ; COMPLEX_FIELD
2200           `~(n = Cx(&0)) /\ ~(z = Cx(&0))
2201            ==> n / z * (z * p) * Cx(&1) / n * q = p * q`] THEN
2202         REWRITE_TAC[GSYM ADD1] THEN MATCH_MP_TAC EQ_IMP THEN
2203         AP_THM_TAC THEN AP_TERM_TAC THEN
2204         SIMP_TAC[FACT; GSYM REAL_OF_NUM_MUL; CX_MUL; GSYM REAL_OF_NUM_SUC] THEN
2205         REWRITE_TAC[complex_div; GSYM COMPLEX_MUL_ASSOC] THEN AP_TERM_TAC THEN
2206         SIMP_TAC[CPRODUCT_CLAUSES_LEFT; ARITH_RULE `0 <= SUC n`] THEN
2207         REWRITE_TAC[ADD1; COMPLEX_INV_MUL; COMPLEX_ADD_RID] THEN
2208         REWRITE_TAC[ISPECL [`f:num->complex`; `m:num`; `1`]
2209                     CPRODUCT_OFFSET] THEN
2210         REWRITE_TAC[GSYM COMPLEX_ADD_ASSOC; GSYM CX_ADD; REAL_OF_NUM_ADD] THEN
2211         REWRITE_TAC[ARITH_RULE `n + 1 = 1 + n`; COMPLEX_MUL_AC]]]) in
2212   let lemma2 = prove
2213    (`!z n. &0 < Re z
2214            ==> ((\t. if drop t <= &n
2215                      then Cx(drop t) cpow (z - Cx(&1)) *
2216                           Cx(&1 - drop t / &n) pow n
2217                      else Cx(&0))
2218                 has_integral (Cx(&n) cpow z * Cx(&(FACT n))) /
2219                              cproduct (0..n) (\m. z + Cx(&m)))
2220                {t | &0 <= drop t}`,
2221     REPEAT STRIP_TAC THEN ASM_CASES_TAC `n = 0` THENL
2222      [ASM_REWRITE_TAC[CPOW_0; COMPLEX_MUL_LZERO; complex_div] THEN
2223       MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN
2224       MAP_EVERY EXISTS_TAC [`\t:real^1. Cx(&0)`; `{vec 0:real^1}`] THEN
2225       REWRITE_TAC[GSYM COMPLEX_VEC_0; HAS_INTEGRAL_0; NEGLIGIBLE_SING] THEN
2226       REWRITE_TAC[IN_DIFF; IN_SING; GSYM DROP_EQ; DROP_VEC; IN_ELIM_THM] THEN
2227       REAL_ARITH_TAC;
2228       REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN
2229       ONCE_REWRITE_TAC[SET_RULE `drop x <= b <=> x IN {x | drop x <= b}`] THEN
2230       REWRITE_TAC[HAS_INTEGRAL_RESTRICT_INTER] THEN
2231       FIRST_ASSUM(MP_TAC o SPEC `n:num` o MATCH_MP lemma1) THEN
2232       DISCH_THEN(MP_TAC o SPECL [`inv(&n)`; `vec 0:real^1`] o
2233        MATCH_MP (REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_AFFINITY)) THEN
2234       REWRITE_TAC[DIMINDEX_1; REAL_POW_1] THEN
2235       ASM_SIMP_TAC[REAL_INV_EQ_0; REAL_OF_NUM_EQ; LE_1; REAL_ABS_INV] THEN
2236       REWRITE_TAC[IMAGE_AFFINITY_INTERVAL; REAL_INV_INV; REAL_POS] THEN
2237       REWRITE_TAC[UNIT_INTERVAL_NONEMPTY; VECTOR_ADD_RID; REAL_ABS_NUM] THEN
2238       REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_NEG_0; VECTOR_ADD_RID] THEN
2239       REWRITE_TAC[DROP_CMUL; COMPLEX_CMUL] THEN
2240       DISCH_THEN(MP_TAC o SPEC `Cx(&n) cpow (z - Cx(&1))` o
2241             MATCH_MP HAS_INTEGRAL_COMPLEX_LMUL) THEN
2242       REWRITE_TAC[COMPLEX_MUL_ASSOC;
2243                   GSYM(ONCE_REWRITE_RULE[COMPLEX_MUL_SYM] CPOW_SUC)] THEN
2244       REWRITE_TAC[complex_div; GSYM COMPLEX_MUL_ASSOC; GSYM LIFT_EQ_CMUL] THEN
2245       REWRITE_TAC[ONCE_REWRITE_RULE[INTER_COMM] INTER; IN_ELIM_THM] THEN
2246       REWRITE_TAC[GSYM DROP_VEC; LIFT_DROP; GSYM IN_INTERVAL_1] THEN
2247       REWRITE_TAC[DROP_VEC; SET_RULE `{x | x IN s} = s`] THEN
2248       REWRITE_TAC[COMPLEX_RING `(z - Cx(&1)) + Cx(&1) = z`] THEN
2249       MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_EQ) THEN
2250       REWRITE_TAC[FORALL_LIFT; IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN
2251       X_GEN_TAC `t:real` THEN STRIP_TAC THEN
2252       REWRITE_TAC[COMPLEX_MUL_ASSOC; REAL_ARITH `inv x * y:real = y / x`] THEN
2253       AP_THM_TAC THEN AP_TERM_TAC THEN IMP_REWRITE_TAC[GSYM CPOW_MUL_REAL] THEN
2254       ASM_SIMP_TAC[REAL_CX; RE_CX; REAL_LE_DIV; REAL_POS; GSYM CX_MUL] THEN
2255       ASM_SIMP_TAC[REAL_DIV_LMUL; REAL_OF_NUM_EQ; LE_1]]) in
2256   let lemma3 = prove
2257    (`f integrable_on s
2258      ==> (\x:real^N. lift(Re(f x))) integrable_on s /\
2259          integral s (\x. lift(Re(f x))) = lift(Re(integral s f))`,
2260     SUBGOAL_THEN `!z. lift(Re z) = (lift o Re) z`
2261      (fun th -> REWRITE_TAC[th]) THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
2262     ONCE_REWRITE_TAC[GSYM o_DEF] THEN REPEAT STRIP_TAC THENL
2263      [MATCH_MP_TAC INTEGRABLE_LINEAR; MATCH_MP_TAC INTEGRAL_LINEAR] THEN
2264     ASM_REWRITE_TAC[linear; COMPLEX_CMUL; o_THM; RE_ADD; RE_MUL_CX] THEN
2265     REWRITE_TAC[LIFT_CMUL; LIFT_ADD]) in
2266   REPEAT STRIP_TAC THEN
2267   MP_TAC(ISPECL
2268    [`\n t. if drop t <= &n
2269            then Cx(drop t) cpow (z - Cx(&1)) * Cx(&1 - drop t / &n) pow n
2270            else Cx(&0)`;
2271     `\t. Cx(drop t) cpow (z - Cx(&1)) / cexp(Cx(drop t))`;
2272     `\t. lift(Re(Cx(drop t) cpow (Cx(Re z) - Cx(&1)) / cexp(Cx(drop t))))`;
2273     `{t | &0 <= drop t}`] DOMINATED_CONVERGENCE) THEN
2274   ASM_SIMP_TAC[REWRITE_RULE[HAS_INTEGRAL_INTEGRABLE_INTEGRAL] lemma2] THEN
2275   ANTS_TAC THENL
2276    [ALL_TAC;
2277     SIMP_TAC[HAS_INTEGRAL_INTEGRABLE_INTEGRAL] THEN
2278     MESON_TAC[CGAMMA; LIM_UNIQUE; TRIVIAL_LIMIT_SEQUENTIALLY]] THEN
2279   REWRITE_TAC[IN_ELIM_THM; LIFT_DROP] THEN REPEAT CONJ_TAC THENL
2280    [ALL_TAC;
2281     REWRITE_TAC[FORALL_LIFT; LIFT_DROP] THEN
2282     MAP_EVERY X_GEN_TAC [`n:num`; `t:real`] THEN DISCH_TAC THEN
2283     REWRITE_TAC[cpow; CX_INJ] THEN ASM_CASES_TAC `t = &0` THEN
2284     ASM_REWRITE_TAC[COMPLEX_MUL_LZERO; COND_ID; RE_CX; CEXP_0; COMPLEX_DIV_1;
2285                     COMPLEX_NORM_0; REAL_LE_REFL] THEN
2286     ASM_SIMP_TAC[GSYM CX_LOG; REAL_LT_LE; GSYM CX_EXP; GSYM CX_SUB;
2287                  GSYM CX_MUL; RE_CX; GSYM CX_DIV; GSYM REAL_EXP_SUB] THEN
2288     COND_CASES_TAC THEN REWRITE_TAC[COMPLEX_NORM_0; REAL_EXP_POS_LE] THEN
2289     REWRITE_TAC[COMPLEX_NORM_MUL; REAL_EXP_SUB; NORM_CEXP] THEN
2290     REWRITE_TAC[RE_MUL_CX; RE_SUB; RE_CX; COMPLEX_NORM_POW] THEN
2291     REWRITE_TAC[real_div] THEN SIMP_TAC[REAL_LE_LMUL_EQ; REAL_EXP_POS_LT] THEN
2292     REWRITE_TAC[COMPLEX_NORM_CX] THEN
2293     SUBGOAL_THEN `~(&n = &0)` MP_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2294     REWRITE_TAC[GSYM real_div; REAL_OF_NUM_EQ] THEN DISCH_TAC THEN
2295     ASM_SIMP_TAC[real_abs; REAL_SUB_LE; REAL_LE_LDIV_EQ; REAL_MUL_LID;
2296                  REAL_OF_NUM_LT; LE_1] THEN
2297     TRANS_TAC REAL_LE_TRANS `exp(--t / &n) pow n` THEN CONJ_TAC THENL
2298      [MATCH_MP_TAC REAL_POW_LE2 THEN
2299       ASM_SIMP_TAC[REAL_SUB_LE; REAL_LE_LDIV_EQ; REAL_MUL_LID;
2300                    REAL_OF_NUM_LT; LE_1] THEN
2301       REWRITE_TAC[REAL_ARITH `&1 - t / n = &1 + --t / n`; REAL_EXP_LE_X];
2302       REWRITE_TAC[GSYM REAL_EXP_N; GSYM REAL_EXP_NEG] THEN
2303       ASM_SIMP_TAC[REAL_DIV_LMUL; REAL_OF_NUM_EQ; REAL_LE_REFL]];
2304     REWRITE_TAC[FORALL_LIFT; LIFT_DROP] THEN X_GEN_TAC `t:real` THEN
2305     DISCH_TAC THEN
2306     MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
2307     EXISTS_TAC `\k. Cx t cpow (z - Cx(&1)) * Cx(&1 - t / &k) pow k` THEN
2308     CONJ_TAC THENL
2309      [MP_TAC(SPEC `t + &1` REAL_ARCH_SIMPLE) THEN
2310       REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; GSYM REAL_OF_NUM_LE] THEN
2311       MATCH_MP_TAC MONO_EXISTS THEN REAL_ARITH_TAC;
2312       REWRITE_TAC[complex_div] THEN MATCH_MP_TAC LIM_COMPLEX_LMUL THEN
2313       REWRITE_TAC[CX_SUB; CX_DIV; GSYM CEXP_NEG] THEN
2314       REWRITE_TAC[SIMPLE_COMPLEX_ARITH `a - x / y:complex = a + --x / y`] THEN
2315       REWRITE_TAC[CEXP_LIMIT]]] THEN
2316   MP_TAC(ISPECL
2317    [`\n t. lift(Re(if drop t <= &n
2318                    then Cx(drop t) cpow (Cx(Re z) - Cx(&1)) *
2319                         Cx(&1 - drop t / &n) pow n
2320                    else Cx(&0)))`;
2321     `\t. lift(Re(Cx(drop t) cpow (Cx(Re z) - Cx(&1)) / cexp(Cx(drop t))))`;
2322     `{t | &0 <= drop t}`]
2323   MONOTONE_CONVERGENCE_INCREASING) THEN
2324   REWRITE_TAC[] THEN ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
2325   ASM_SIMP_TAC[lemma3; REWRITE_RULE[HAS_INTEGRAL_INTEGRABLE_INTEGRAL] lemma2;
2326    RE_CX; bounded; FORALL_IN_GSPEC] THEN
2327   REWRITE_TAC[IN_UNIV; FORALL_LIFT; LIFT_DROP; NORM_LIFT] THEN
2328   REPEAT CONJ_TAC THENL
2329    [MAP_EVERY X_GEN_TAC [`n:num`; `t:real`] THEN DISCH_TAC THEN
2330     ASM_CASES_TAC `t = &0` THEN
2331     ASM_SIMP_TAC[CPOW_0; COMPLEX_MUL_LZERO; COND_ID; REAL_LE_REFL] THEN
2332     ASM_REWRITE_TAC[cpow; CX_INJ] THEN
2333     ASM_SIMP_TAC[cpow; CX_INJ; GSYM CX_SUB; GSYM CX_EXP; GSYM CX_LOG;
2334                  REAL_LT_LE; GSYM CX_MUL; GSYM CX_DIV; RE_CX; GSYM CX_POW] THEN
2335     REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN ASM_CASES_TAC `t <= &n` THEN
2336     ASM_SIMP_TAC[REAL_ARITH `x <= n ==> x <= n + &1`] THENL
2337      [SIMP_TAC[RE_CX; REAL_LE_LMUL_EQ; REAL_EXP_POS_LT] THEN
2338       REWRITE_TAC[GSYM RPOW_POW; GSYM REAL_OF_NUM_SUC] THEN
2339       MATCH_MP_TAC REAL_EXP_LIMIT_RPOW_LE THEN ASM_REAL_ARITH_TAC;
2340       COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL; RE_CX] THEN
2341       MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[REAL_EXP_POS_LE] THEN
2342       MATCH_MP_TAC REAL_POW_LE THEN REWRITE_TAC[REAL_SUB_LE] THEN
2343       SIMP_TAC[REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
2344       ASM_REAL_ARITH_TAC];
2345     X_GEN_TAC `t:real` THEN DISCH_TAC THEN REWRITE_TAC[] THEN
2346     MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN EXISTS_TAC
2347      `\k. lift(Re(Cx t cpow (Cx(Re z) - Cx(&1)) *
2348                   Cx(&1 - t / &k) pow k))` THEN
2349     CONJ_TAC THENL
2350      [MP_TAC(SPEC `t + &1` REAL_ARCH_SIMPLE) THEN
2351       REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; GSYM REAL_OF_NUM_LE] THEN
2352       MATCH_MP_TAC MONO_EXISTS THEN REAL_ARITH_TAC;
2353       REWRITE_TAC[cpow; CX_INJ] THEN
2354       ASM_CASES_TAC `t = &0` THEN
2355       ASM_REWRITE_TAC[COMPLEX_MUL_LZERO; complex_div; LIM_CONST] THEN
2356       ASM_SIMP_TAC[cpow; CX_INJ; GSYM CX_SUB; GSYM CX_EXP; GSYM CX_LOG;
2357               REAL_LT_LE; GSYM CX_MUL; GSYM CX_INV; RE_CX; GSYM CX_POW] THEN
2358       REWRITE_TAC[real_div; LIFT_CMUL; RE_CX] THEN MATCH_MP_TAC LIM_CMUL THEN
2359       REWRITE_TAC[REAL_ARITH `&1 - t * inv x = &1 + --t / x`] THEN
2360       REWRITE_TAC[GSYM REAL_EXP_NEG] THEN
2361       REWRITE_TAC[GSYM(REWRITE_RULE[o_DEF] TENDSTO_REAL)] THEN
2362       REWRITE_TAC[EXP_LIMIT]];
2363     MP_TAC(MATCH_MP CONVERGENT_IMP_BOUNDED (SPEC `Cx(Re z)` CGAMMA)) THEN
2364     REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_UNIV] THEN
2365     MESON_TAC[COMPLEX_NORM_GE_RE_IM; REAL_LE_TRANS]]);;
2366
2367 let EULER_INTEGRAL = prove
2368  (`!z. &0 < Re z
2369        ==> integral {t | &0 <= drop t}
2370                     (\t.  Cx(drop t) cpow (z - Cx(&1)) / cexp(Cx(drop t))) =
2371            cgamma(z)`,
2372   MESON_TAC[INTEGRAL_UNIQUE; EULER_HAS_INTEGRAL_CGAMMA]);;
2373
2374 let EULER_INTEGRABLE = prove
2375  (`!z. &0 < Re z
2376        ==> (\t.  Cx(drop t) cpow (z - Cx(&1)) / cexp(Cx(drop t))) integrable_on
2377            {t | &0 <= drop t}`,
2378   MESON_TAC[EULER_HAS_INTEGRAL_CGAMMA; integrable_on]);;
2379
2380 let EULER_HAS_REAL_INTEGRAL_GAMMA = prove
2381  (`!x. &0 < x
2382        ==> ((\t. t rpow (x - &1) / exp t) has_real_integral gamma(x))
2383            {t | &0 <= t}`,
2384   REPEAT STRIP_TAC THEN REWRITE_TAC[has_real_integral] THEN
2385   MP_TAC(SPEC `Cx x` EULER_HAS_INTEGRAL_CGAMMA) THEN
2386   ASM_REWRITE_TAC[gamma; o_DEF; RE_CX] THEN
2387   DISCH_THEN(MP_TAC o ISPEC `lift o Re` o MATCH_MP
2388    (REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_LINEAR)) THEN
2389   REWRITE_TAC[o_DEF] THEN ANTS_TAC THENL
2390    [REWRITE_TAC[linear; RE_ADD; LIFT_ADD; COMPLEX_CMUL; RE_MUL_CX] THEN
2391     REWRITE_TAC[LIFT_CMUL];
2392     ALL_TAC] THEN
2393   SUBGOAL_THEN `IMAGE lift {t | &0 <= t} = {t | &0 <= drop t}`
2394   SUBST1_TAC THENL
2395    [MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
2396     REWRITE_TAC[IN_ELIM_THM; LIFT_DROP] THEN MESON_TAC[LIFT_DROP];
2397     ALL_TAC] THEN
2398   MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] (REWRITE_RULE[CONJ_ASSOC]
2399         HAS_INTEGRAL_SPIKE)) THEN
2400   EXISTS_TAC `{vec 0:real^1}` THEN
2401   REWRITE_TAC[NEGLIGIBLE_SING; FORALL_LIFT; IN_DIFF; IN_ELIM_THM;
2402               LIFT_DROP; IN_SING; GSYM DROP_EQ; DROP_VEC] THEN
2403   SIMP_TAC[cpow; CX_INJ; rpow; REAL_LT_LE; GSYM CX_LOG; GSYM CX_SUB;
2404            GSYM CX_EXP; GSYM CX_MUL; RE_CX; GSYM CX_DIV]);;
2405
2406 let EULER_REAL_INTEGRAL = prove
2407  (`!x. &0 < x
2408        ==> real_integral {t | &0 <= t} (\t. t rpow (x - &1) / exp t) =
2409            gamma(x)`,
2410   MESON_TAC[REAL_INTEGRAL_UNIQUE; EULER_HAS_REAL_INTEGRAL_GAMMA]);;
2411
2412 let EULER_REAL_INTEGRABLE = prove
2413  (`!x. &0 < x
2414        ==> (\t. t rpow (x - &1) / exp t) real_integrable_on {t | &0 <= t}`,
2415   MESON_TAC[EULER_HAS_REAL_INTEGRAL_GAMMA; real_integrable_on]);;
2416
2417 let EULER_ORIGINAL_REAL_INTEGRABLE = prove
2418  (`!x. &0 < x
2419        ==> (\t. (--log t) rpow (x - &1))
2420                 real_integrable_on real_interval[&0,&1]`,
2421   SUBGOAL_THEN
2422    `!x. &0 < x
2423         ==> ((\t. (--log t) rpow (x - &1))
2424              real_integrable_on real_interval[&0,&1] <=>
2425              (\t. (--log t) rpow x)
2426              real_integrable_on real_interval[&0,&1])`
2427   ASSUME_TAC THENL
2428    [GEN_TAC THEN ASM_CASES_TAC `x = &0` THEN
2429     ASM_REWRITE_TAC[REAL_LT_REFL] THEN DISCH_TAC THEN MP_TAC(ISPECL
2430      [`\t. inv(x) * (--log t) rpow x`;
2431       `\t:real. t`;
2432       `\t. --(&1) / t * (--log t) rpow (x - &1)`;
2433       `\t:real. &1`; `&0`; `&1`; `{&0,&1}`]
2434         REAL_INTEGRABLE_BY_PARTS_EQ) THEN
2435     REWRITE_TAC[COUNTABLE_INSERT; COUNTABLE_EMPTY; REAL_MUL_RID] THEN
2436     ANTS_TAC THENL
2437      [CONJ_TAC THENL
2438        [REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN
2439         MATCH_MP_TAC REAL_CONTINUOUS_ON_LMUL THEN
2440         REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
2441         X_GEN_TAC `t:real` THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN
2442         STRIP_TAC THEN
2443         FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP (REAL_ARITH
2444          `&0 <= x ==> &0 < x \/ x = &0`))
2445         THENL
2446          [MATCH_MP_TAC REAL_CONTINUOUS_MUL THEN
2447           REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN
2448           MATCH_MP_TAC REAL_CONTINUOUS_ATREAL_WITHINREAL THEN
2449           SUBGOAL_THEN
2450            `(\y. --log(y) rpow x) = (\y. y rpow x) o (\x. --x) o log`
2451           SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
2452           REPEAT(MATCH_MP_TAC REAL_CONTINUOUS_ATREAL_COMPOSE THEN
2453                  CONJ_TAC) THEN
2454           ASM_SIMP_TAC[REAL_CONTINUOUS_NEG; REAL_CONTINUOUS_AT_ID;
2455                        REAL_CONTINUOUS_AT_LOG] THEN
2456           MATCH_MP_TAC REAL_CONTINUOUS_AT_RPOW THEN
2457           ASM_SIMP_TAC[REAL_LE_LT];
2458           FIRST_X_ASSUM SUBST_ALL_TAC THEN
2459           REWRITE_TAC[REAL_CONTINUOUS_WITHINREAL; REAL_MUL_RZERO] THEN
2460           MATCH_MP_TAC REALLIM_TRANSFORM_EVENTUALLY THEN
2461           EXISTS_TAC `\y. (--x * log(y rpow inv x) * y rpow inv x) rpow x` THEN
2462           CONJ_TAC THENL
2463            [REWRITE_TAC[EVENTUALLY_WITHINREAL] THEN
2464             REWRITE_TAC[REAL_ARITH `&0 < abs(x - a) <=> ~(x = a)`] THEN
2465             EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
2466             X_GEN_TAC `y:real` THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN
2467             STRIP_TAC THEN
2468             SUBGOAL_THEN `&0 < y` ASSUME_TAC THENL
2469              [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2470             ASM_SIMP_TAC[LOG_RPOW; REAL_LT_INV_EQ; REAL_FIELD
2471               `~(x = &0) ==> --x * (inv x * y) * z = --y * z`] THEN
2472             ASM_SIMP_TAC[RPOW_MUL; RPOW_RPOW; REAL_MUL_LINV] THEN
2473             REWRITE_TAC[RPOW_POW; REAL_POW_1];
2474             SUBGOAL_THEN `&0 = &0 rpow x`
2475              (fun th -> GEN_REWRITE_TAC LAND_CONV [th])
2476             THENL [ASM_SIMP_TAC[rpow; REAL_LT_IMP_NZ; REAL_LT_REFL];
2477                    ALL_TAC] THEN
2478             MATCH_MP_TAC(REWRITE_RULE[] (ISPEC `\y. y rpow x`
2479                 REALLIM_REAL_CONTINUOUS_FUNCTION)) THEN
2480             ASM_SIMP_TAC[REAL_CONTINUOUS_AT_RPOW; REAL_LT_IMP_LE] THEN
2481             MATCH_MP_TAC REALLIM_NULL_LMUL THEN
2482             SUBGOAL_THEN
2483              `(\y. log (y rpow inv x) * y rpow inv x) =
2484               (\y. log y * y) o (\y. y rpow inv x)`
2485             SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
2486             MATCH_MP_TAC REALLIM_COMPOSE_WITHIN THEN
2487             EXISTS_TAC `{x | &0 <= x}` THEN EXISTS_TAC `&0 rpow inv x` THEN
2488             ASM_REWRITE_TAC[REAL_ENTIRE; RPOW_EQ_0; REAL_INV_EQ_0] THEN
2489             REPEAT CONJ_TAC THENL
2490              [MATCH_MP_TAC(REWRITE_RULE[] (ISPEC `\y. y rpow x`
2491                 REALLIM_REAL_CONTINUOUS_FUNCTION)) THEN
2492               ASM_SIMP_TAC[REAL_CONTINUOUS_AT_RPOW; REAL_LT_IMP_LE;
2493                            REAL_LE_INV_EQ] THEN
2494               MP_TAC(ISPEC `&0` REAL_CONTINUOUS_AT_ID) THEN
2495               SIMP_TAC[REAL_CONTINUOUS_ATREAL; REALLIM_ATREAL_WITHINREAL];
2496               REWRITE_TAC[EVENTUALLY_WITHINREAL] THEN
2497               SIMP_TAC[RPOW_POS_LE; IN_REAL_INTERVAL; IN_ELIM_THM] THEN
2498               MESON_TAC[REAL_LT_01];
2499               ASM_REWRITE_TAC[RPOW_ZERO; REAL_INV_EQ_0] THEN
2500               ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
2501               REWRITE_TAC[REALLIM_X_TIMES_LOG]]]];
2502         REWRITE_TAC[IN_REAL_INTERVAL; IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN
2503         X_GEN_TAC `t:real` THEN REWRITE_TAC[DE_MORGAN_THM] THEN STRIP_TAC THEN
2504         CONJ_TAC THEN REAL_DIFF_TAC THEN ASM_REWRITE_TAC[] THEN
2505         ASM_SIMP_TAC[GSYM LOG_INV; REAL_INV_1_LT; LOG_POS_LT] THEN
2506         REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD];
2507       ASM_REWRITE_TAC[REAL_INTEGRABLE_LMUL_EQ; REAL_INV_EQ_0] THEN
2508       DISCH_THEN SUBST1_TAC THEN
2509       REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC] THEN
2510       REWRITE_TAC[REAL_INTEGRABLE_LMUL_EQ] THEN
2511       CONV_TAC REAL_RAT_REDUCE_CONV THEN
2512       MATCH_MP_TAC REAL_INTEGRABLE_SPIKE_EQ THEN EXISTS_TAC `{&0}` THEN
2513       REWRITE_TAC[REAL_NEGLIGIBLE_SING; IN_DIFF; IN_SING] THEN
2514       CONV_TAC REAL_FIELD];
2515     ALL_TAC] THEN
2516   SUBGOAL_THEN
2517    `!n. (\t. --log t pow n) real_integrable_on real_interval[&0,&1]`
2518   ASSUME_TAC THENL
2519    [MATCH_MP_TAC num_INDUCTION THEN
2520     REWRITE_TAC[CONJUNCT1 real_pow; REAL_INTEGRABLE_CONST] THEN
2521     REWRITE_TAC[GSYM RPOW_POW] THEN X_GEN_TAC `n:num` THEN
2522     SUBGOAL_THEN `&n = &(SUC n) - &1` SUBST1_TAC THENL
2523      [REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN REAL_ARITH_TAC;
2524       MATCH_MP_TAC EQ_IMP THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
2525       REWRITE_TAC[REAL_OF_NUM_LT; LT_0]];
2526     ALL_TAC] THEN
2527   SUBGOAL_THEN
2528    `!x. &0 < x
2529         ==> (\t. --log t rpow x) real_integrable_on real_interval[&0,&1]`
2530    (fun th -> ASM_MESON_TAC[th]) THEN
2531   X_GEN_TAC `x:real` THEN DISCH_TAC THEN
2532   MP_TAC(SPEC `x:real` REAL_ARCH_SIMPLE) THEN
2533   DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN
2534   MATCH_MP_TAC REAL_MEASURABLE_BOUNDED_AE_BY_INTEGRABLE_IMP_INTEGRABLE THEN
2535   EXISTS_TAC `\t. max (&1) (--log t pow n)` THEN EXISTS_TAC `{&0}` THEN
2536   REWRITE_TAC[REAL_NEGLIGIBLE_SING] THEN REPEAT CONJ_TAC THENL
2537    [MATCH_MP_TAC REAL_MEASURABLE_ON_RPOW THEN
2538     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC INTEGRABLE_IMP_REAL_MEASURABLE THEN
2539     FIRST_X_ASSUM(MP_TAC o SPEC `1`) THEN REWRITE_TAC[REAL_POW_1];
2540     MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_IMP_INTEGRABLE THEN
2541     MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_MAX THEN
2542     REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_CONST] THEN MATCH_MP_TAC
2543       ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_LBOUND THEN
2544     EXISTS_TAC `\x:real. min (--log(&0) pow n) (&0)` THEN
2545     ASM_REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_CONST] THEN
2546     REWRITE_TAC[IN_REAL_INTERVAL] THEN X_GEN_TAC `t:real` THEN
2547     STRIP_TAC THEN ASM_CASES_TAC `t = &0` THEN ASM_REWRITE_TAC[] THENL
2548      [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2549     SUBGOAL_THEN `&0 < t` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2550     MATCH_MP_TAC(REAL_ARITH `b <= c ==> min a b <= c`) THEN
2551     MATCH_MP_TAC REAL_POW_LE THEN ASM_SIMP_TAC[GSYM LOG_INV] THEN
2552     MATCH_MP_TAC LOG_POS THEN MATCH_MP_TAC REAL_INV_1_LE THEN
2553     ASM_REWRITE_TAC[];
2554     REWRITE_TAC[IN_REAL_INTERVAL; IN_DIFF; IN_SING] THEN
2555     X_GEN_TAC `t:real` THEN STRIP_TAC THEN
2556     SUBGOAL_THEN `&0 < t` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2557     SUBGOAL_THEN `&0 <= --log t` ASSUME_TAC THENL
2558      [ASM_SIMP_TAC[GSYM LOG_INV] THEN MATCH_MP_TAC LOG_POS THEN
2559       MATCH_MP_TAC REAL_INV_1_LE THEN ASM_REAL_ARITH_TAC;
2560       ASM_SIMP_TAC[real_abs; RPOW_POS_LE]] THEN
2561     ASM_CASES_TAC `--(log t) <= &1` THENL
2562      [MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= max y z`) THEN
2563       MATCH_MP_TAC RPOW_1_LE THEN ASM_REAL_ARITH_TAC;
2564       MATCH_MP_TAC(REAL_ARITH `x <= z ==> x <= max y z`) THEN
2565       REWRITE_TAC[GSYM RPOW_POW] THEN MATCH_MP_TAC RPOW_MONO THEN
2566       ASM_REAL_ARITH_TAC]]);;
2567
2568 let EULER_ORIGINAL_INTEGRABLE = prove
2569  (`!z. &0 < Re z
2570        ==> (\t. (--clog(Cx(drop t))) cpow (z - Cx(&1)))
2571            integrable_on interval[vec 0,vec 1]`,
2572   REPEAT STRIP_TAC THEN
2573   MATCH_MP_TAC MEASURABLE_BOUNDED_AE_BY_INTEGRABLE_IMP_INTEGRABLE THEN
2574   EXISTS_TAC `\t. lift((--log(drop t)) rpow (Re z - &1))` THEN
2575   EXISTS_TAC `{vec 0:real^1,vec 1}` THEN
2576   REWRITE_TAC[NEGLIGIBLE_INSERT; NEGLIGIBLE_EMPTY] THEN REPEAT CONJ_TAC THENL
2577    [MATCH_MP_TAC
2578      CONTINUOUS_AE_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET THEN
2579     EXISTS_TAC `{vec 0:real^1,vec 1}` THEN
2580     REWRITE_TAC[NEGLIGIBLE_INSERT; NEGLIGIBLE_EMPTY;
2581                 LEBESGUE_MEASURABLE_INTERVAL] THEN
2582     SUBGOAL_THEN
2583      `(\t. --clog (Cx(drop t)) cpow (z - Cx(&1))) =
2584       ((\w. w cpow (z - Cx(&1))) o (--) o clog) o (\x. Cx(drop x))`
2585     SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
2586     MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
2587     SIMP_TAC[CONTINUOUS_ON_CX_DROP; CONTINUOUS_ON_ID] THEN
2588     MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
2589     REWRITE_TAC[IN_DIFF; IN_INSERT; NOT_IN_EMPTY; DE_MORGAN_THM;
2590                 IMP_CONJ; FORALL_IN_IMAGE] THEN
2591     REWRITE_TAC[FORALL_LIFT; IN_INTERVAL_1; LIFT_DROP] THEN
2592     REWRITE_TAC[GSYM DROP_EQ; LIFT_DROP; DROP_VEC; o_DEF] THEN
2593     REPEAT STRIP_TAC THEN
2594     MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_AT THEN
2595     COMPLEX_DIFFERENTIABLE_TAC THEN
2596     ASM_SIMP_TAC[GSYM CX_LOG; RE_CX; REAL_LT_LE; RE_NEG; GSYM LOG_INV] THEN
2597     DISCH_TAC THEN REWRITE_TAC[GSYM REAL_LT_LE] THEN
2598     MATCH_MP_TAC LOG_POS_LT THEN MATCH_MP_TAC REAL_INV_1_LT THEN
2599     ASM_REAL_ARITH_TAC;
2600     REWRITE_TAC[INTERVAL_REAL_INTERVAL; DROP_VEC;
2601                 REWRITE_RULE[o_DEF] (GSYM REAL_INTEGRABLE_ON)] THEN
2602     MATCH_MP_TAC EULER_ORIGINAL_REAL_INTEGRABLE THEN ASM_REWRITE_TAC[];
2603
2604     REWRITE_TAC[FORALL_LIFT; IN_DIFF; IN_INSERT; GSYM DROP_EQ; LIFT_DROP;
2605                 IN_INTERVAL_1; DROP_VEC; NOT_IN_EMPTY] THEN
2606     X_GEN_TAC `x:real` THEN DISCH_TAC THEN
2607     SUBGOAL_THEN `&0 < x /\ x < &1` STRIP_ASSUME_TAC THENL
2608      [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2609     ASM_SIMP_TAC[GSYM CX_LOG; cpow; rpow; GSYM CX_NEG; REAL_LT_IMP_NZ; RE_CX;
2610           REAL_LT_IMP_LE; COMPLEX_NORM_MUL; NORM_CEXP; RE_SUB; CX_INJ;
2611           REAL_LE_REFL; RE_MUL_CX; GSYM LOG_INV; LOG_POS_LT; REAL_INV_1_LT]]);;
2612
2613 let EULER_ORIGINAL_HAS_INTEGRAL_CGAMMA = prove
2614  (`!z. &0 < Re z
2615        ==> ((\t. (--clog(Cx(drop t))) cpow (z - Cx(&1)))
2616             has_integral cgamma(z)) (interval[vec 0,vec 1])`,
2617   REPEAT STRIP_TAC THEN
2618   FIRST_ASSUM(ASSUME_TAC o MATCH_MP EULER_ORIGINAL_INTEGRABLE) THEN
2619   FIRST_ASSUM(MP_TAC o MATCH_MP INDEFINITE_INTEGRAL_CONTINUOUS_LEFT) THEN
2620   REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
2621   DISCH_THEN(MP_TAC o SPEC `vec 0:real^1`) THEN
2622   REWRITE_TAC[ENDS_IN_UNIT_INTERVAL; CONTINUOUS_WITHIN] THEN DISCH_TAC THEN
2623   ASM_REWRITE_TAC[HAS_INTEGRAL_INTEGRABLE_INTEGRAL] THEN
2624   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE
2625    [TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`] LIM_UNIQUE)) THEN
2626   REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN CONJ_TAC THENL
2627    [MATCH_MP_TAC CONNECTED_IMP_PERFECT THEN
2628     REWRITE_TAC[ENDS_IN_UNIT_INTERVAL; CONNECTED_INTERVAL] THEN
2629     MATCH_MP_TAC(SET_RULE
2630      `{a,b} SUBSET interval[a,b] /\ ~(a = b)
2631       ==> ~(?x. interval[a,b] = {x})`) THEN
2632     REWRITE_TAC[INSERT_SUBSET; EMPTY_SUBSET; ENDS_IN_UNIT_INTERVAL] THEN
2633     REWRITE_TAC[VEC_EQ; ARITH_EQ];
2634     ALL_TAC] THEN
2635   MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
2636   EXISTS_TAC `\x. integral(interval[vec 0,lift(--log(drop x))])
2637           (\t. Cx(drop t) cpow (z - Cx(&1)) / cexp(Cx(drop t)))` THEN
2638   REWRITE_TAC[EVENTUALLY_WITHIN] THEN CONJ_TAC THENL
2639    [EXISTS_TAC `&1` THEN
2640     REWRITE_TAC[REAL_LT_01; DIST_0; NORM_POS_LT; IN_INTERVAL_1; DROP_VEC;
2641                 GSYM DROP_EQ; DROP_VEC; FORALL_LIFT; LIFT_DROP] THEN
2642     X_GEN_TAC `x:real` THEN STRIP_TAC THEN
2643     SUBGOAL_THEN `&0 < x` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2644     MP_TAC(ISPECL
2645      [`\t. (--clog(Cx(drop(--t)))) cpow (z - Cx(&1))`;
2646       `\t. --lift(exp(--drop t))`;
2647       `\t. lift(exp(--drop t))`;
2648       `vec 0:real^1`; `lift(--log x):real^1`; `--vec 1:real^1`; `vec 0:real^1`;
2649       `{vec 0:real^1,vec 1}`]
2650           HAS_INTEGRAL_SUBSTITUTION_STRONG) THEN
2651     REWRITE_TAC[LIFT_DROP; DROP_VEC; GSYM DROP_NEG] THEN
2652     REWRITE_TAC[GSYM REFLECT_INTERVAL; GSYM INTEGRAL_REFLECT_GEN] THEN
2653     REWRITE_TAC[DROP_NEG; LIFT_DROP; REAL_LE_NEG2; REAL_EXP_MONO_LE] THEN
2654     REWRITE_TAC[REAL_NEG_NEG; DROP_VEC; REAL_EXP_0; REAL_NEG_0] THEN
2655     SIMP_TAC[GSYM CX_LOG; REAL_EXP_POS_LT; LOG_EXP] THEN ANTS_TAC THENL
2656      [REWRITE_TAC[REAL_POS; COUNTABLE_INSERT; COUNTABLE_EMPTY] THEN
2657       CONV_TAC REAL_RAT_REDUCE_CONV THEN
2658       ASM_SIMP_TAC[GSYM LOG_INV; LOG_POS; REAL_INV_1_LE] THEN
2659       REWRITE_TAC[GSYM DROP_NEG; INTEGRABLE_REFLECT_GEN] THEN
2660       REWRITE_TAC[REFLECT_INTERVAL; VECTOR_NEG_NEG; VECTOR_NEG_0] THEN
2661       ASM_SIMP_TAC[EULER_ORIGINAL_INTEGRABLE] THEN REPEAT CONJ_TAC THENL
2662        [REWRITE_TAC[GSYM LIFT_NEG; DROP_NEG] THEN
2663         REWRITE_TAC[GSYM LIFT_NUM; GSYM IMAGE_LIFT_REAL_INTERVAL] THEN
2664         REWRITE_TAC[REWRITE_RULE[o_DEF] (GSYM REAL_CONTINUOUS_ON)] THEN
2665         MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON THEN
2666         REWRITE_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE] THEN
2667         REPEAT STRIP_TAC THEN REAL_DIFFERENTIABLE_TAC;
2668         REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; DROP_VEC;
2669                     FORALL_LIFT; LIFT_DROP; DROP_NEG] THEN
2670         X_GEN_TAC `y:real` THEN STRIP_TAC THEN
2671         REWRITE_TAC[REAL_ARITH `--x <= &0 <=> &0 <= x`; REAL_EXP_POS_LE] THEN
2672         REWRITE_TAC[REAL_EXP_NEG; REAL_LE_NEG2] THEN
2673         MATCH_MP_TAC REAL_INV_LE_1 THEN
2674         GEN_REWRITE_TAC LAND_CONV [GSYM REAL_EXP_0] THEN
2675         ASM_REWRITE_TAC[REAL_EXP_MONO_LE];
2676         REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; DROP_VEC;
2677                     FORALL_LIFT; LIFT_DROP; DROP_NEG; IN_DIFF; IN_INSERT;
2678                     NOT_IN_EMPTY; GSYM DROP_EQ; DE_MORGAN_THM] THEN
2679         X_GEN_TAC `y:real` THEN REPEAT STRIP_TAC THENL
2680          [MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_AT_WITHIN THEN
2681           REWRITE_TAC[GSYM LIFT_NEG; REWRITE_RULE[o_DEF]
2682            (GSYM HAS_REAL_VECTOR_DERIVATIVE_AT)] THEN
2683           REAL_DIFF_TAC THEN REAL_ARITH_TAC;
2684           MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN
2685           SUBGOAL_THEN
2686            `(\t. --clog(Cx(--drop t)) cpow (z - Cx(&1))) =
2687             (\w. --clog w cpow (z - Cx(&1))) o (\t. Cx(drop(--t)))`
2688           SUBST1_TAC THENL [REWRITE_TAC[o_DEF; DROP_NEG]; ALL_TAC] THEN
2689           MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN CONJ_TAC THENL
2690            [MATCH_MP_TAC CONTINUOUS_CX_DROP THEN
2691             GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN
2692             SIMP_TAC[CONTINUOUS_NEG; CONTINUOUS_AT_ID];
2693             MATCH_MP_TAC COMPLEX_DIFFERENTIABLE_IMP_CONTINUOUS_AT THEN
2694             COMPLEX_DIFFERENTIABLE_TAC THEN
2695             REWRITE_TAC[RE_CX; VECTOR_NEG_NEG; LIFT_DROP] THEN
2696             SIMP_TAC[REAL_EXP_POS_LT; GSYM CX_LOG; LOG_EXP] THEN
2697             REWRITE_TAC[RE_NEG; RE_CX; REAL_NEG_NEG] THEN
2698             ASM_REAL_ARITH_TAC]]];
2699       DISCH_THEN(MP_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN
2700       ASM_SIMP_TAC[EXP_LOG; LIFT_NUM; COMPLEX_CMUL; CX_EXP; CEXP_NEG; CX_NEG;
2701                    COMPLEX_NEG_NEG] THEN
2702       DISCH_THEN(SUBST1_TAC o SYM) THEN
2703       ONCE_REWRITE_TAC[COMPLEX_MUL_SYM] THEN REWRITE_TAC[complex_div]];
2704    FIRST_ASSUM(MP_TAC o MATCH_MP EULER_HAS_INTEGRAL_CGAMMA) THEN
2705    GEN_REWRITE_TAC LAND_CONV [HAS_INTEGRAL_ALT] THEN
2706    REWRITE_TAC[INTEGRABLE_RESTRICT_INTER; INTEGRAL_RESTRICT_INTER] THEN
2707    DISCH_THEN(ASSUME_TAC o CONJUNCT2) THEN REWRITE_TAC[LIM_WITHIN] THEN
2708    X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2709    FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
2710    DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
2711    EXISTS_TAC `exp(--B)` THEN ASM_REWRITE_TAC[REAL_EXP_POS_LT] THEN
2712    REWRITE_TAC[REAL_LT_01; DIST_0; NORM_POS_LT; IN_INTERVAL_1; DROP_VEC;
2713                GSYM DROP_EQ; DROP_VEC; FORALL_LIFT; LIFT_DROP; NORM_LIFT] THEN
2714    X_GEN_TAC `x:real` THEN STRIP_TAC THEN
2715    SUBGOAL_THEN `&0 < x` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2716    FIRST_X_ASSUM(MP_TAC o SPECL [`--lift B`; `lift(--log x)`]) THEN
2717    ANTS_TAC THENL
2718     [REWRITE_TAC[BALL_1; SUBSET_INTERVAL_1; DROP_ADD; DROP_SUB; DROP_VEC] THEN
2719      REWRITE_TAC[LIFT_DROP; DROP_NEG] THEN DISJ2_TAC THEN
2720      REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
2721      REWRITE_TAC[REAL_ADD_LID] THEN
2722      ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LE] THEN
2723      ASM_SIMP_TAC[REAL_EXP_NEG; EXP_LOG] THEN
2724      GEN_REWRITE_TAC LAND_CONV [GSYM REAL_INV_INV] THEN
2725      ONCE_REWRITE_TAC[GSYM REAL_EXP_NEG] THEN
2726      MATCH_MP_TAC REAL_LE_INV2 THEN ASM_REAL_ARITH_TAC;
2727      MATCH_MP_TAC(NORM_ARITH
2728       `i = j ==> norm(i - g) < e ==> dist(j,g) < e`) THEN
2729      AP_THM_TAC THEN AP_TERM_TAC THEN
2730      REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM; IN_INTERVAL_1] THEN
2731      REWRITE_TAC[DROP_NEG; LIFT_DROP; DROP_VEC] THEN ASM_REAL_ARITH_TAC]]);;
2732
2733 let EULER_ORIGINAL_INTEGRAL = prove
2734  (`!z. &0 < Re z
2735        ==> integral (interval[vec 0,vec 1])
2736                     (\t. (--clog(Cx(drop t))) cpow (z - Cx(&1))) =
2737            cgamma(z)`,
2738   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2739   MATCH_MP_TAC EULER_ORIGINAL_HAS_INTEGRAL_CGAMMA THEN
2740   ASM_REWRITE_TAC[]);;
2741
2742 let EULER_ORIGINAL_HAS_REAL_INTEGRAL_GAMMA = prove
2743  (`!x. &0 < x
2744        ==> ((\t. (--log t) rpow (x - &1)) has_real_integral gamma(x))
2745            (real_interval[&0,&1])`,
2746   REPEAT STRIP_TAC THEN REWRITE_TAC[has_real_integral] THEN
2747   MP_TAC(SPEC `Cx x` EULER_ORIGINAL_HAS_INTEGRAL_CGAMMA) THEN
2748   ASM_REWRITE_TAC[gamma; o_DEF; RE_CX] THEN
2749   DISCH_THEN(MP_TAC o ISPEC `lift o Re` o MATCH_MP
2750    (REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_LINEAR)) THEN
2751   REWRITE_TAC[o_DEF] THEN ANTS_TAC THENL
2752    [REWRITE_TAC[linear; RE_ADD; LIFT_ADD; COMPLEX_CMUL; RE_MUL_CX] THEN
2753     REWRITE_TAC[LIFT_CMUL];
2754     REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_NUM]] THEN
2755   MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ] (REWRITE_RULE[CONJ_ASSOC]
2756         HAS_INTEGRAL_SPIKE)) THEN
2757   EXISTS_TAC `{vec 0:real^1,vec 1}` THEN
2758   REWRITE_TAC[NEGLIGIBLE_INSERT; FORALL_LIFT; IN_INTERVAL_1; DE_MORGAN_THM;
2759     LIFT_DROP; IN_INSERT; NOT_IN_EMPTY; GSYM DROP_EQ; DROP_VEC; IN_DIFF] THEN
2760   REWRITE_TAC[NEGLIGIBLE_EMPTY] THEN X_GEN_TAC `y:real` THEN STRIP_TAC THEN
2761   SUBGOAL_THEN `&0 < y` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2762   SUBGOAL_THEN `&0 < --log y` ASSUME_TAC THENL
2763    [ASM_SIMP_TAC[GSYM LOG_INV] THEN MATCH_MP_TAC LOG_POS_LT THEN
2764     MATCH_MP_TAC REAL_INV_1_LT THEN ASM_REAL_ARITH_TAC;
2765     ASM_SIMP_TAC[GSYM CX_LOG; cpow; rpow; COMPLEX_NEG_EQ_0; CX_INJ;
2766                  REAL_LT_IMP_NZ] THEN
2767     ASM_SIMP_TAC[GSYM CX_NEG; GSYM CX_LOG; GSYM CX_SUB; GSYM CX_MUL] THEN
2768     COND_CASES_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2769     REWRITE_TAC[GSYM CX_EXP; RE_CX]]);;
2770
2771 let EULER_ORIGINAL_REAL_INTEGRAL = prove
2772  (`!x. &0 < x
2773        ==> real_integral (real_interval[&0,&1])
2774                          (\t. (--log t) rpow (x - &1)) =
2775            gamma(x)`,
2776   MESON_TAC[REAL_INTEGRAL_UNIQUE; EULER_ORIGINAL_HAS_REAL_INTEGRAL_GAMMA]);;
2777
2778 (* ------------------------------------------------------------------------- *)
2779 (* Stirling's approximation.                                                 *)
2780 (* ------------------------------------------------------------------------- *)
2781
2782 let LGAMMA_STIRLING_INTEGRALS_EXIST,LGAMMA_STIRLING = (CONJ_PAIR o prove)
2783  (`(!z n. 1 <= n /\ (Im z = &0 ==> &0 < Re z)
2784           ==> (\t. Cx(bernoulli n (frac (drop t))) / (z + Cx(drop t)) pow n)
2785               integrable_on {t | &0 <= drop t}) /\
2786    (!z p.
2787       (Im z = &0 ==> &0 < Re z)
2788       ==> lgamma(z) =
2789           ((z - Cx(&1) / Cx(&2)) * clog(z) - z + Cx(log(&2 * pi) / &2)) +
2790           vsum(1..p) (\k. Cx(bernoulli (2 * k) (&0) /
2791                              (&4 * &k pow 2 - &2 * &k)) / z pow (2 * k - 1)) -
2792           integral {t | &0 <= drop t}
2793                    (\t. Cx(bernoulli (2 * p + 1) (frac(drop t))) /
2794                         (z + Cx(drop t)) pow (2 * p + 1)) /
2795           Cx(&(2 * p + 1)))`,
2796   let lemma1 = prove
2797    (`!p n z. (Im z = &0 ==> &0 < Re z)
2798              ==> (\x. Cx(bernoulli (2 * p + 1) (frac(drop x))) *
2799                    Cx(&(FACT(2 * p))) / (z + Cx(drop x)) pow (2 * p + 1))
2800                  integrable_on interval [lift(&0),lift(&n)] /\
2801                  vsum(0..n) (\m. clog(Cx(&m) + z)) =
2802                  (z + Cx(&n) + Cx(&1) / Cx(&2)) * clog(z + Cx(&n)) -
2803                  (z - Cx(&1) / Cx(&2)) * clog(z) - Cx(&n) +
2804                  vsum(1..p)
2805                   (\k. Cx(bernoulli (2 * k) (&0) / &(FACT(2 * k))) *
2806                        (Cx(&(FACT(2 * k - 2))) / (z + Cx(&n)) pow (2 * k - 1) -
2807                         Cx(&(FACT(2 * k - 2))) / z pow (2 * k - 1))) +
2808                  integral (interval[lift(&0),lift(&n)])
2809                    (\x. Cx(bernoulli (2 * p + 1) (frac(drop x))) *
2810                         Cx(&(FACT(2 * p))) / (z + Cx(drop x)) pow (2 * p + 1)) /
2811                  Cx(&(FACT(2 * p + 1)))`,
2812     REPEAT GEN_TAC THEN STRIP_TAC THEN
2813     REWRITE_TAC[COMPLEX_RING `Cx(&n) + z = z + Cx(&n)`] THEN MP_TAC(ISPECL
2814      [`\n w. if n = 0 then (z + w) * clog(z + w) - (z + w)
2815              else if n = 1 then clog(z + w)
2816              else Cx(--(&1) pow n * &(FACT(n - 2))) /
2817                   (z + w) pow (n - 1)`;
2818       `0`; `n:num`; `p:num`] COMPLEX_EULER_MACLAURIN_ANTIDERIVATIVE) THEN
2819     ASM_REWRITE_TAC[ADD_EQ_0; MULT_EQ_0; MULT_EQ_1] THEN
2820     CONV_TAC NUM_REDUCE_CONV THEN ANTS_TAC THENL
2821      [REWRITE_TAC[IN_REAL_INTERVAL; LE_0] THEN
2822       MAP_EVERY X_GEN_TAC [`k:num`; `x:real`] THEN REPEAT STRIP_TAC THEN
2823       SUBGOAL_THEN `~(z + Cx x = Cx(&0))` ASSUME_TAC THENL
2824        [REWRITE_TAC[COMPLEX_EQ; IM_ADD; RE_ADD; IM_CX; RE_CX] THEN
2825         ASM_REAL_ARITH_TAC;
2826         ALL_TAC] THEN
2827       REWRITE_TAC[o_THM; ARITH_RULE `k + 1 = 1 <=> k = 0`] THEN
2828       ASM_CASES_TAC `k = 0` THEN ASM_REWRITE_TAC[] THENL
2829        [COMPLEX_DIFF_TAC THEN CONJ_TAC THENL
2830          [REWRITE_TAC[RE_ADD; IM_ADD; RE_CX; IM_CX] THEN ASM_REAL_ARITH_TAC;
2831           UNDISCH_TAC `~(z + Cx x = Cx(&0))` THEN CONV_TAC COMPLEX_FIELD];
2832         ALL_TAC] THEN
2833       ASM_CASES_TAC `k = 1` THEN ASM_REWRITE_TAC[] THEN COMPLEX_DIFF_TAC THEN
2834       CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
2835       REWRITE_TAC[complex_div; COMPLEX_ADD_LID; COMPLEX_MUL_LID;
2836                   COMPLEX_POW_1; IM_ADD; RE_ADD; IM_CX; RE_CX] THEN
2837       (CONJ_TAC ORELSE ASM_REAL_ARITH_TAC) THEN
2838       ASM_REWRITE_TAC[COMPLEX_POW_EQ_0] THEN
2839       REWRITE_TAC[REAL_POW_ADD; REAL_POW_1; COMPLEX_MUL_LZERO] THEN
2840       REWRITE_TAC[REAL_MUL_RNEG; REAL_MUL_RID; REAL_NEG_NEG; REAL_MUL_LNEG] THEN
2841       REWRITE_TAC[COMPLEX_MUL_RID; CX_NEG; COMPLEX_POW_POW] THEN
2842       REWRITE_TAC[GSYM COMPLEX_MUL_ASSOC; COMPLEX_SUB_LZERO; COMPLEX_NEG_NEG;
2843                   COMPLEX_MUL_LNEG] THEN
2844       REWRITE_TAC[GSYM complex_div] THEN AP_TERM_TAC THEN
2845       FIRST_X_ASSUM(K ALL_TAC o check (is_imp o concl)) THEN
2846       ASM_SIMP_TAC[GSYM complex_div; COMPLEX_DIV_POW2] THEN COND_CASES_TAC THENL
2847        [MATCH_MP_TAC(TAUT `F ==> p`) THEN ASM_ARITH_TAC; ALL_TAC] THEN
2848       ASM_SIMP_TAC[ADD_SUB; ARITH_RULE
2849        `~(k = 0) /\ ~(k = 1) ==> (k - 1) * 2 - (k - 1 - 1) = k`] THEN
2850       REWRITE_TAC[COMPLEX_MUL_ASSOC; complex_div] THEN
2851       AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[GSYM CX_MUL] THEN
2852       AP_TERM_TAC THEN REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN AP_TERM_TAC THEN
2853       ASM_SIMP_TAC[ARITH_RULE `~(k = 0) ==> (k + 1) - 2 = k - 1`] THEN
2854       ASM_SIMP_TAC[ARITH_RULE
2855        `~(k = 0) /\ ~(k = 1) ==> k - 1 = SUC(k - 2)`] THEN
2856       REWRITE_TAC[FACT; REAL_OF_NUM_MUL] THEN REWRITE_TAC[MULT_SYM];
2857       REWRITE_TAC[ARITH_RULE `~(2 * p + 2 = 1)`] THEN
2858       DISCH_THEN(CONJUNCTS_THEN2 MP_TAC SUBST1_TAC)] THEN
2859     SIMP_TAC[LE_1] THEN
2860     REWRITE_TAC[ARITH_RULE `(2 * p + 2) - 1 = 2 * p + 1`; ADD_SUB] THEN
2861     REWRITE_TAC[REAL_POW_NEG; EVEN_ADD; EVEN_MULT; ARITH_EVEN] THEN
2862     REWRITE_TAC[REAL_POW_ONE; REAL_MUL_LID] THEN
2863     DISCH_TAC THEN ASM_REWRITE_TAC[COMPLEX_ADD_RID] THEN
2864     CONV_TAC COMPLEX_RING) in
2865   let lemma2 = prove
2866    (`!z n. 2 <= n /\ (Im z = &0 ==> &0 < Re z)
2867            ==> (\t. inv(z + Cx(drop t)) pow n)
2868                absolutely_integrable_on {t | &0 <= drop t}`,
2869     REPEAT STRIP_TAC THEN REWRITE_TAC[COMPLEX_POW_INV] THEN
2870     MATCH_MP_TAC
2871       MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE THEN
2872     EXISTS_TAC `\t. lift(inv(max (abs(Im z)) (Re z + drop t)) pow n)` THEN
2873     REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
2874      [MATCH_MP_TAC CONTINUOUS_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET THEN
2875       CONJ_TAC THENL
2876        [MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_INV THEN
2877         SIMP_TAC[CONTINUOUS_ON_COMPLEX_POW; CONTINUOUS_ON_ADD;
2878           CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID; CONTINUOUS_ON_CX_DROP] THEN
2879         REWRITE_TAC[IN_ELIM_THM; GSYM FORALL_DROP] THEN
2880         REWRITE_TAC[COMPLEX_POW_EQ_0] THEN
2881         REWRITE_TAC[COMPLEX_EQ; RE_ADD; IM_ADD; RE_CX; IM_CX] THEN
2882         ASM_REAL_ARITH_TAC;
2883         MATCH_MP_TAC LEBESGUE_MEASURABLE_CONVEX THEN
2884         MATCH_MP_TAC IS_INTERVAL_CONVEX THEN
2885         REWRITE_TAC[IS_INTERVAL_1; IN_ELIM_THM] THEN REAL_ARITH_TAC];
2886       ALL_TAC;
2887       REWRITE_TAC[FORALL_IN_GSPEC; GSYM FORALL_DROP; LIFT_DROP] THEN
2888       X_GEN_TAC `x:real` THEN DISCH_TAC THEN
2889      REWRITE_TAC[GSYM COMPLEX_POW_INV; COMPLEX_NORM_POW] THEN
2890      MATCH_MP_TAC REAL_POW_LE2 THEN
2891      REWRITE_TAC[NORM_POS_LE; COMPLEX_NORM_INV] THEN
2892      MATCH_MP_TAC REAL_LE_INV2 THEN
2893      MP_TAC(SPEC `z + Cx x` COMPLEX_NORM_GE_RE_IM) THEN
2894      REWRITE_TAC[RE_ADD; IM_ADD; RE_CX; IM_CX] THEN ASM_REAL_ARITH_TAC] THEN
2895     REWRITE_TAC[REAL_ARITH `max m n = if n <= m then m else n`] THEN
2896     REWRITE_TAC[COND_RAND; COND_RATOR] THEN
2897     MATCH_MP_TAC INTEGRABLE_CASES THEN REWRITE_TAC[IN_ELIM_THM] THEN
2898     CONJ_TAC THENL
2899      [SUBGOAL_THEN
2900        `{t | &0 <= drop t /\ Re z + drop t <= abs (Im z)} =
2901         interval[vec 0,lift(abs(Im z) - Re z)]`
2902        (fun th -> REWRITE_TAC[th; INTEGRABLE_CONST]) THEN
2903       SIMP_TAC[EXTENSION; IN_ELIM_THM; IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN
2904       REAL_ARITH_TAC;
2905       ALL_TAC] THEN
2906     MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE_SET) THEN
2907     EXISTS_TAC
2908      `{t | abs(Im z) - Re z <= drop t} INTER {t | &0 <= drop t}` THEN
2909     CONJ_TAC THENL
2910      [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN
2911       EXISTS_TAC `{lift(abs(Im z) - Re z)}` THEN
2912       REWRITE_TAC[NEGLIGIBLE_SING] THEN
2913       REWRITE_TAC[SUBSET; IN_DIFF; IN_UNION;
2914                   IN_ELIM_THM; IN_SING; IN_INTER] THEN
2915       REWRITE_TAC[GSYM DROP_EQ; LIFT_DROP] THEN ASM_REAL_ARITH_TAC;
2916       ALL_TAC] THEN
2917     REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_INTER] THEN
2918     REWRITE_TAC[integrable_on] THEN
2919     ONCE_REWRITE_TAC[HAS_INTEGRAL_LIM_AT_POSINFINITY] THEN
2920     REWRITE_TAC[INTEGRABLE_RESTRICT_INTER; INTEGRAL_RESTRICT_INTER] THEN
2921     SUBGOAL_THEN
2922      `!a. {t | abs(Im z) - Re z <= drop t} INTER interval[vec 0,a] =
2923           interval[lift(max (&0) (abs (Im z) - Re z)),a]`
2924      (fun th -> REWRITE_TAC[th])
2925     THENL
2926      [REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM; IN_INTERVAL_1] THEN
2927       REWRITE_TAC[LIFT_DROP; DROP_VEC] THEN REAL_ARITH_TAC;
2928       ALL_TAC] THEN
2929     SUBGOAL_THEN
2930      `!b. &0 <= drop b /\ abs (Im z) - Re z <= drop b
2931            ==> ((\x. lift(inv (Re z + drop x) pow n)) has_integral
2932                 lift
2933                 (inv((&1 - &n) * (Re z + drop b) pow (n - 1)) -
2934                  inv((&1 - &n) *
2935                      (Re z + max(&0) (abs(Im z) - Re z)) pow (n - 1))))
2936                (interval[lift(max (&0) (abs (Im z) - Re z)),b])`
2937     ASSUME_TAC THENL
2938      [REPEAT STRIP_TAC THEN
2939       MP_TAC(ISPECL
2940        [`\x. lift(inv((&1 - &n) * (Re z + drop x) pow (n - 1)))`;
2941         `\x. lift(inv(Re z + drop x) pow n)`;
2942         `lift(max (&0) (abs (Im z) - Re z))`;
2943         `b:real^1`] FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN
2944       ASM_REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP; REAL_MAX_LE] THEN
2945       ANTS_TAC THENL
2946        [REWRITE_TAC[FORALL_LIFT; LIFT_DROP; INTERVAL_REAL_INTERVAL] THEN
2947         REWRITE_TAC[REWRITE_RULE[o_DEF]
2948          (GSYM HAS_REAL_VECTOR_DERIVATIVE_WITHIN)] THEN
2949         REWRITE_TAC[REAL_INV_MUL; REAL_INV_POW] THEN REPEAT STRIP_TAC THEN
2950         REAL_DIFF_TAC THEN
2951         ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUB; ARITH_RULE `2 <= n ==> 1 <= n`] THEN
2952         CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
2953         ASM_SIMP_TAC[real_div; REAL_OF_NUM_LE; REAL_FIELD
2954          `&2 <= x ==> inv(&1 - x) * (x - &1) * y * --(&0 + &1) * p =
2955                      y * p`] THEN
2956         REWRITE_TAC[GSYM REAL_INV_MUL; GSYM REAL_INV_POW] THEN
2957         AP_TERM_TAC THEN REWRITE_TAC[GSYM REAL_POW_ADD] THEN
2958         AP_TERM_TAC THEN ASM_ARITH_TAC;
2959         REWRITE_TAC[LIFT_DROP; GSYM LIFT_SUB]];
2960       ALL_TAC] THEN
2961     EXISTS_TAC `lift(inv
2962                   ((&n - &1) *
2963                    (Re z + max (&0) (abs(Im z) - Re z)) pow (n - 1)))` THEN
2964     CONJ_TAC THENL
2965      [X_GEN_TAC `b:real^1` THEN
2966       ASM_CASES_TAC `&0 <= drop b /\ abs (Im z) - Re z <= drop b` THENL
2967        [ASM_MESON_TAC[integrable_on]; MATCH_MP_TAC INTEGRABLE_ON_NULL] THEN
2968       REWRITE_TAC[CONTENT_EQ_0_1; LIFT_DROP] THEN ASM_REAL_ARITH_TAC;
2969       ALL_TAC] THEN
2970     MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
2971     EXISTS_TAC
2972      `\b. lift(inv((&1 - &n) * (Re z + b) pow (n - 1)) -
2973                inv((&1 - &n) *
2974                    (Re z + max (&0) (abs(Im z) - Re z)) pow (n - 1)))` THEN
2975     CONJ_TAC THENL
2976      [REWRITE_TAC[EVENTUALLY_AT_POSINFINITY; real_ge] THEN
2977       EXISTS_TAC `max(&0) (abs(Im z) - Re z)` THEN
2978       REWRITE_TAC[FORALL_DROP; LIFT_DROP] THEN
2979       REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
2980       MATCH_MP_TAC INTEGRAL_UNIQUE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
2981       ASM_REAL_ARITH_TAC;
2982       ALL_TAC] THEN
2983     REWRITE_TAC[LIFT_SUB; VECTOR_SUB] THEN
2984     GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_ADD_LID] THEN
2985     MATCH_MP_TAC LIM_ADD THEN
2986     REWRITE_TAC[GSYM LIFT_NEG; GSYM REAL_INV_NEG; GSYM REAL_MUL_LNEG] THEN
2987     REWRITE_TAC[REAL_NEG_SUB; LIM_CONST] THEN
2988     REWRITE_TAC[REAL_INV_MUL; LIFT_CMUL] THEN
2989     MATCH_MP_TAC LIM_NULL_CMUL THEN
2990     REWRITE_TAC[GSYM LIFT_NUM; GSYM LIM_CX_LIFT] THEN
2991     REWRITE_TAC[CX_INV; CX_POW; GSYM COMPLEX_POW_INV; CX_ADD] THEN
2992     ONCE_REWRITE_TAC[COMPLEX_ADD_SYM] THEN
2993     MATCH_MP_TAC LIM_INV_X_POW_OFFSET THEN ASM_ARITH_TAC) in
2994   let lemma3 = prove
2995    (`!z n. 2 <= n /\ (Im z = &0 ==> &0 < Re z)
2996            ==> (\t. Cx(bernoulli n (frac (drop t))) / (z + Cx(drop t)) pow n)
2997                integrable_on {t | &0 <= drop t}`,
2998     REPEAT STRIP_TAC THEN
2999     REWRITE_TAC[complex_div; GSYM COMPLEX_CMUL] THEN
3000     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
3001     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_ON_MUL_BERNOULLI_FRAC THEN
3002     ASM_SIMP_TAC[GSYM COMPLEX_POW_INV; lemma2]) in
3003   let lemma4 = prove
3004    (`!z p. (Im z = &0 ==> &0 < Re z) /\ 1 <= p
3005            ==> ((\t. Cx(bernoulli 1 (frac(drop t))) / (z + Cx(drop t)))
3006                 has_integral
3007                 (integral {t | &0 <= drop t}
3008                           (\t. Cx(bernoulli (2 * p + 1) (frac(drop t))) /
3009                                (z + Cx(drop t)) pow (2 * p + 1)) /
3010                  Cx(&(2 * p + 1)) -
3011                  vsum(1..p) (\k. Cx(bernoulli (2 * k) (&0) /
3012                                     (&4 * &k pow 2 - &2 * &k)) /
3013                                  z pow (2 * k - 1))))
3014                 {t | &0 <= drop t}`,
3015     REPEAT STRIP_TAC THEN
3016     MATCH_MP_TAC HAS_INTEGRAL_LIM_SEQUENTIALLY THEN CONJ_TAC THENL
3017      [REWRITE_TAC[o_DEF; LIFT_DROP; complex_div; COMPLEX_VEC_0] THEN
3018       MATCH_MP_TAC LIM_NULL_COMPLEX_LMUL_BOUNDED THEN
3019       EXISTS_TAC `&1 / &2` THEN CONJ_TAC THENL
3020        [MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `x:real` THEN
3021         REWRITE_TAC[BERNOULLI_CONV `bernoulli 1 x`] THEN DISJ1_TAC THEN
3022         REWRITE_TAC[COMPLEX_NORM_CX] THEN
3023         MP_TAC(SPEC `x:real` FLOOR_FRAC) THEN REAL_ARITH_TAC;
3024         MATCH_MP_TAC(REWRITE_RULE[o_DEF] LIM_INFINITY_POSINFINITY_CX) THEN
3025         ONCE_REWRITE_TAC[COMPLEX_ADD_SYM] THEN REWRITE_TAC[LIM_INV_Z_OFFSET]];
3026       ALL_TAC] THEN
3027     MP_TAC(GEN `n:num` (CONJ
3028      (SPECL [`0`; `n:num`; `z:complex`] lemma1)
3029      (SPECL [`p:num`; `n:num`; `z:complex`] lemma1))) THEN
3030     ASM_REWRITE_TAC[FORALL_AND_THM] THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN
3031     REWRITE_TAC[VSUM_CLAUSES_NUMSEG] THEN CONV_TAC NUM_REDUCE_CONV THEN
3032     REWRITE_TAC[SIMPLE_COMPLEX_ARITH `a * Cx(&1) / b = a / b`] THEN
3033     REWRITE_TAC[LIFT_NUM; COMPLEX_POW_1; COMPLEX_DIV_1] THEN
3034     DISCH_THEN(fun th -> ONCE_REWRITE_TAC[th]) THEN
3035     REWRITE_TAC[VECTOR_ARITH `a + vec 0 + x:real^N = a + y <=> x = y`] THEN
3036     DISCH_THEN(fun th -> ONCE_REWRITE_TAC[th]) THEN
3037     GEN_REWRITE_TAC LAND_CONV [COMPLEX_RING `a - b:complex = --b + a`] THEN
3038     MATCH_MP_TAC LIM_ADD THEN CONJ_TAC THENL
3039      [REWRITE_TAC[GSYM VSUM_NEG] THEN MATCH_MP_TAC LIM_VSUM THEN
3040       REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
3041       X_GEN_TAC `k:num` THEN STRIP_TAC THEN
3042       REWRITE_TAC[CX_DIV; complex_div; GSYM COMPLEX_MUL_RNEG] THEN
3043       REWRITE_TAC[GSYM COMPLEX_MUL_ASSOC] THEN
3044       MATCH_MP_TAC LIM_COMPLEX_LMUL THEN
3045       REWRITE_TAC[SIMPLE_COMPLEX_ARITH
3046        `inv x * (y * w - y * z):complex = y / x * (w - z)`] THEN
3047       SUBGOAL_THEN
3048        `Cx(&(FACT(2 * k - 2))) / Cx(&(FACT(2 * k))) =
3049         inv(Cx(&4 * &k pow 2 - &2 * &k))`
3050        (fun th -> ONCE_REWRITE_TAC[th])
3051       THENL
3052        [MATCH_MP_TAC(COMPLEX_FIELD
3053          `~(y = Cx(&0)) /\ ~(z = Cx(&0)) /\ x * z = y
3054           ==> x / y = inv(z)`) THEN
3055         REWRITE_TAC[CX_INJ; REAL_OF_NUM_EQ; FACT_NZ] THEN
3056         REWRITE_TAC[REAL_ENTIRE; REAL_ARITH
3057          `&4 * x pow 2 - &2 * x = (&2 * x) * (&2 * x - &1)`] THEN
3058         ASM_SIMP_TAC[ARITH_RULE `1 <= k ==> 1 <= 2 * k`; REAL_OF_NUM_SUB;
3059                      REAL_OF_NUM_MUL; GSYM CX_MUL; CX_INJ; REAL_OF_NUM_EQ] THEN
3060         CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
3061         UNDISCH_TAC `1 <= k` THEN SPEC_TAC(`k:num`,`k:num`) THEN
3062         INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES; MULT_CLAUSES] THEN
3063         CONV_TAC NUM_REDUCE_CONV THEN DISCH_THEN (K ALL_TAC) THEN
3064         REWRITE_TAC[ARITH_RULE `(2 + k) - 2 = k /\ (2 + k) - 1 = k + 1`] THEN
3065         REWRITE_TAC[ARITH_RULE `2 + k = SUC(SUC k)`; FACT] THEN ARITH_TAC;
3066         MATCH_MP_TAC LIM_COMPLEX_LMUL THEN
3067         ONCE_REWRITE_TAC[COMPLEX_RING `--z = Cx(&0) - z`] THEN
3068         MATCH_MP_TAC LIM_SUB THEN REWRITE_TAC[LIM_CONST] THEN
3069         REWRITE_TAC[GSYM COMPLEX_POW_INV] THEN
3070         ONCE_REWRITE_TAC[COMPLEX_ADD_SYM] THEN
3071         MATCH_MP_TAC LIM_INV_N_POW_OFFSET THEN ASM_ARITH_TAC];
3072       MP_TAC(SPECL [`z:complex`; `2 * p + 1`] lemma3) THEN
3073       ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_TAC] THEN
3074       FIRST_ASSUM(MP_TAC o SPEC `Cx(&(FACT(2 * p)))` o
3075           MATCH_MP INTEGRABLE_COMPLEX_LMUL) THEN
3076       DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
3077       ASM_SIMP_TAC[INTEGRAL_COMPLEX_LMUL] THEN
3078       REWRITE_TAC[HAS_INTEGRAL_LIM_AT_POSINFINITY] THEN
3079       DISCH_THEN(MP_TAC o
3080           MATCH_MP LIM_POSINFINITY_SEQUENTIALLY o CONJUNCT2) THEN
3081       DISCH_THEN(MP_TAC o SPEC `inv(Cx(&(FACT(2 * p + 1))))` o
3082           MATCH_MP LIM_COMPLEX_RMUL) THEN
3083       MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THENL
3084        [REWRITE_TAC[LIFT_NUM; FUN_EQ_THM] THEN
3085         X_GEN_TAC `n:num` THEN REWRITE_TAC[complex_div] THEN
3086         AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC INTEGRAL_EQ THEN
3087         REWRITE_TAC[complex_div; COMPLEX_MUL_AC];
3088
3089         REWRITE_TAC[complex_div] THEN MATCH_MP_TAC(COMPLEX_RING
3090          `x * y:complex = z ==> (x * i) * y = i * z`) THEN
3091         REWRITE_TAC[GSYM ADD1; FACT; GSYM REAL_OF_NUM_MUL; CX_MUL] THEN
3092         MATCH_MP_TAC(COMPLEX_FIELD
3093          `~(a = Cx(&0)) /\ ~(b = Cx(&0)) ==> a * inv(b * a) = inv b`) THEN
3094         REWRITE_TAC[CX_INJ; REAL_OF_NUM_EQ; FACT_NZ; NOT_SUC]]]) in
3095   let lemma5 = prove
3096    (`!z n. 1 <= n /\ (Im z = &0 ==> &0 < Re z)
3097            ==> (\t. Cx(bernoulli n (frac (drop t))) / (z + Cx(drop t)) pow n)
3098                integrable_on {t | &0 <= drop t}`,
3099     REPEAT STRIP_TAC THEN FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE
3100      `1 <= n ==> n = 1 \/ 2 <= n`)) THEN
3101     ASM_SIMP_TAC[lemma3; COMPLEX_POW_1] THEN
3102     REWRITE_TAC[integrable_on] THEN
3103     ASM_MESON_TAC[LE_REFL; lemma4]) in
3104   let lemma6 = prove
3105    (`!z. (Im z = &0 ==> &0 < Re z)
3106          ==> lgamma(z) =
3107              ((z - Cx(&1) / Cx(&2)) * clog(z) - z + Cx(&1)) +
3108              (integral {t | &0 <= drop t}
3109                        (\t. Cx(bernoulli 1 (frac(drop t))) /
3110                             (Cx(&1) + Cx(drop t))) -
3111               integral {t | &0 <= drop t}
3112                        (\t. Cx(bernoulli 1 (frac(drop t))) /
3113                             (z + Cx(drop t))))`,
3114     REPEAT STRIP_TAC THEN
3115     SUBGOAL_THEN `!n. ~(z + Cx(&n) = Cx(&0))` ASSUME_TAC THENL
3116      [REWRITE_TAC[COMPLEX_EQ; IM_ADD; RE_ADD; IM_CX; RE_CX] THEN
3117       ASM_REAL_ARITH_TAC;
3118       ALL_TAC] THEN
3119     SUBGOAL_THEN `~(z = Cx(&0))` ASSUME_TAC THENL
3120      [ASM_MESON_TAC[COMPLEX_ADD_RID]; ALL_TAC] THEN
3121     FIRST_ASSUM(MP_TAC o MATCH_MP LGAMMA_ALT) THEN
3122     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT]
3123      (REWRITE_RULE[TRIVIAL_LIMIT_SEQUENTIALLY]
3124           (ISPEC `sequentially` LIM_UNIQUE))) THEN
3125     MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN EXISTS_TAC
3126      `\n. z * clog (Cx(&n)) - clog (Cx(&n + &1)) +
3127           ((Cx(&1) + Cx(&n) + Cx(&1) / Cx(&2)) * clog (Cx(&1) + Cx(&n)) -
3128            (Cx(&1) - Cx(&1) / Cx(&2)) * clog (Cx(&1)) -
3129            Cx(&n) +
3130            integral (interval [lift (&0),lift (&n)])
3131            (\x. Cx(bernoulli 1 (frac (drop x))) *
3132                 Cx(&1) / (Cx(&1) + Cx(drop x)) pow 1) /
3133            Cx(&1)) -
3134           ((z + Cx(&n) + Cx(&1) / Cx(&2)) * clog (z + Cx(&n)) -
3135            (z - Cx(&1) / Cx(&2)) * clog z -
3136            Cx(&n) +
3137            integral (interval [lift (&0),lift (&n)])
3138            (\x. Cx(bernoulli 1 (frac (drop x))) *
3139                 Cx(&1) / (z + Cx(drop x)) pow 1) /
3140            Cx(&1))` THEN
3141     REWRITE_TAC[] THEN CONJ_TAC THENL
3142      [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
3143       EXISTS_TAC `1` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
3144       SUBGOAL_THEN
3145        `clog(Cx(&(FACT n))) =
3146         vsum(0..n) (\m. clog(Cx(&m) + Cx(&1))) - clog(Cx(&n + &1))`
3147       SUBST1_TAC THENL
3148        [REWRITE_TAC[REAL_OF_NUM_ADD; GSYM CX_ADD] THEN
3149         REWRITE_TAC[GSYM(SPEC `1` VSUM_OFFSET); ADD_CLAUSES] THEN
3150         SIMP_TAC[GSYM NPRODUCT_FACT; REAL_OF_NUM_NPRODUCT; FINITE_NUMSEG;
3151                  GSYM CX_LOG; LOG_PRODUCT; PRODUCT_POS_LT; IN_NUMSEG;
3152                  REAL_OF_NUM_LT; LE_1; GSYM VSUM_CX] THEN
3153         REWRITE_TAC[GSYM ADD1; VSUM_CLAUSES_NUMSEG] THEN
3154         REWRITE_TAC[ARITH_RULE `1 <= SUC n`; REAL_OF_NUM_SUC] THEN
3155         SIMP_TAC[CX_LOG; REAL_OF_NUM_LT; LT_0] THEN
3156         REWRITE_TAC[COMPLEX_RING `(a + b) - b:complex = a`];
3157         ONCE_REWRITE_TAC[COMPLEX_RING
3158          `(a + b - c) - d:complex = (a - c) + (b - d)`]] THEN
3159       MP_TAC(SPECL [`0`; `n:num`] lemma1) THEN
3160       CONV_TAC NUM_REDUCE_CONV THEN
3161       ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG; ARITH; VECTOR_ADD_LID] THEN
3162       ASM_SIMP_TAC[RE_CX; REAL_LT_01];
3163       ALL_TAC] THEN
3164     REWRITE_TAC[COMPLEX_POW_1; COMPLEX_DIV_1] THEN
3165     ONCE_REWRITE_TAC[COMPLEX_RING
3166      `a + (b - c - n + x) - (d - e - n + y):complex =
3167       (a + (b - c) - (d - e)) + (x - y)`] THEN
3168     MATCH_MP_TAC LIM_ADD THEN CONJ_TAC THENL
3169      [REWRITE_TAC[CLOG_1; COMPLEX_MUL_RZERO; COMPLEX_SUB_RZERO] THEN
3170       ONCE_REWRITE_TAC[LIM_NULL_COMPLEX] THEN REWRITE_TAC[] THEN
3171       ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN REWRITE_TAC[CX_ADD] THEN
3172       MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN EXISTS_TAC
3173        `\n. z * (clog(Cx(&n)) - clog(z + Cx(&n))) +
3174                 (Cx(&n) + Cx(&1) / Cx(&2)) *
3175                 (clog(Cx(&1) + Cx(&n)) - clog(z + Cx(&n))) -
3176                 (Cx(&1) - z)` THEN
3177       CONJ_TAC THENL
3178        [MATCH_MP_TAC ALWAYS_EVENTUALLY THEN CONV_TAC COMPLEX_RING;
3179         ALL_TAC] THEN
3180       MATCH_MP_TAC LIM_NULL_COMPLEX_ADD THEN CONJ_TAC THENL
3181        [MATCH_MP_TAC LIM_NULL_COMPLEX_LMUL THEN
3182         GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV o BINDER_CONV o
3183                          LAND_CONV o RAND_CONV) [GSYM COMPLEX_ADD_LID] THEN
3184         ONCE_REWRITE_TAC[COMPLEX_ADD_SYM] THEN REWRITE_TAC[LIM_SUB_CLOG];
3185         ONCE_REWRITE_TAC[COMPLEX_RING
3186          `(a + h) * x - y:complex = h * x + a * x - y`] THEN
3187         MATCH_MP_TAC LIM_NULL_COMPLEX_ADD THEN REWRITE_TAC[] THEN
3188         ONCE_REWRITE_TAC[COMPLEX_ADD_SYM] THEN
3189         SIMP_TAC[LIM_NULL_COMPLEX_LMUL; LIM_SUB_CLOG] THEN
3190         REWRITE_TAC[GSYM LIM_NULL_COMPLEX; LIM_N_MUL_SUB_CLOG]];
3191       REWRITE_TAC[complex_div; COMPLEX_MUL_LID] THEN
3192       REWRITE_TAC[LIFT_NUM] THEN MATCH_MP_TAC LIM_SUB THEN
3193       CONJ_TAC THEN REWRITE_TAC[GSYM LIFT_NUM] THEN
3194       MATCH_MP_TAC LIM_POSINFINITY_SEQUENTIALLY THEN
3195       REWRITE_TAC[LIFT_NUM] THEN
3196       MATCH_MP_TAC(MATCH_MP (TAUT `(p <=> q /\ r) ==> (p ==> r)`)
3197           (SPEC_ALL HAS_INTEGRAL_LIM_AT_POSINFINITY)) THEN
3198       REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL; GSYM complex_div] THEN
3199       ONCE_REWRITE_TAC[COMPLEX_RING `z + x:complex = (z + x) pow 1`] THEN
3200       MATCH_MP_TAC lemma5 THEN
3201       ASM_REWRITE_TAC[LE_REFL; RE_CX; REAL_LT_01]]) in
3202   let lemma7 = prove
3203    (`((\y. integral {t | &0 <= drop t}
3204             (\t. Cx (bernoulli 1 (frac (drop t))) / (ii * Cx y + Cx(drop t))))
3205       --> Cx(&0)) at_posinfinity`,
3206     MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
3207     EXISTS_TAC
3208      `\y. integral {t | &0 <= drop t}
3209                    (\t. Cx(bernoulli 3 (frac (drop t))) /
3210                         (ii * Cx y + Cx(drop t)) pow 3) / Cx(&3) -
3211           Cx(bernoulli 2 (&0) / &2) / (ii * Cx y)` THEN
3212     CONJ_TAC THENL
3213      [REWRITE_TAC[EVENTUALLY_AT_POSINFINITY; real_ge] THEN
3214       EXISTS_TAC `&1` THEN X_GEN_TAC `y:real` THEN DISCH_TAC THEN
3215       SUBGOAL_THEN `&0 < y` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
3216       MP_TAC(ISPECL [`ii * Cx y`; `1`] lemma4) THEN
3217       ASM_SIMP_TAC[IM_MUL_II; RE_CX; REAL_LT_IMP_NZ; LE_REFL] THEN
3218       REWRITE_TAC[VSUM_SING_NUMSEG] THEN
3219       CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
3220       REWRITE_TAC[COMPLEX_POW_1] THEN
3221       DISCH_THEN(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN REFL_TAC;
3222       ALL_TAC] THEN
3223     MATCH_MP_TAC LIM_NULL_COMPLEX_SUB THEN CONJ_TAC THENL
3224      [ALL_TAC;
3225       REWRITE_TAC[complex_div] THEN MATCH_MP_TAC LIM_NULL_COMPLEX_LMUL THEN
3226       REWRITE_TAC[COMPLEX_INV_MUL] THEN MATCH_MP_TAC LIM_NULL_COMPLEX_LMUL THEN
3227       REWRITE_TAC[LIM_INV_X]] THEN
3228     ONCE_REWRITE_TAC[complex_div] THEN MATCH_MP_TAC LIM_NULL_COMPLEX_RMUL THEN
3229     MATCH_MP_TAC LIM_NULL_COMPARISON_COMPLEX THEN
3230     EXISTS_TAC
3231      `\y. Cx(&1 / &2 / y) *
3232           integral {t | &0 <= drop t}
3233                   (\t. inv(Cx(&1) + Cx(drop t)) pow 2)` THEN
3234     CONJ_TAC THENL
3235      [ALL_TAC;
3236       MATCH_MP_TAC LIM_NULL_COMPLEX_RMUL THEN
3237       REWRITE_TAC[real_div; CX_MUL] THEN
3238       MATCH_MP_TAC LIM_NULL_COMPLEX_LMUL THEN
3239       REWRITE_TAC[LIM_INV_X; CX_INV]] THEN
3240     REWRITE_TAC[EVENTUALLY_AT_POSINFINITY; real_ge] THEN
3241     EXISTS_TAC `&1` THEN X_GEN_TAC `y:real` THEN DISCH_TAC THEN
3242     SIMP_TAC[GSYM INTEGRAL_COMPLEX_LMUL; lemma2;
3243              ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE; ARITH;
3244              RE_CX; REAL_OF_NUM_LT] THEN
3245     MATCH_MP_TAC(REAL_ARITH
3246       `abs(Re z) <= norm z /\ x <= Re z ==> x <= norm z`) THEN
3247     REWRITE_TAC[COMPLEX_NORM_GE_RE_IM] THEN REWRITE_TAC[RE_DEF] THEN
3248     MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT THEN
3249     REWRITE_TAC[DIMINDEX_2; ARITH] THEN REPEAT CONJ_TAC THENL
3250      [MATCH_MP_TAC lemma5 THEN
3251       REWRITE_TAC[ARITH; IM_MUL_II; RE_CX] THEN ASM_REAL_ARITH_TAC;
3252       MATCH_MP_TAC INTEGRABLE_COMPLEX_LMUL THEN
3253       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
3254       MATCH_MP_TAC lemma2 THEN
3255       REWRITE_TAC[RE_CX; REAL_LT_01] THEN ARITH_TAC;
3256       ALL_TAC] THEN
3257     REWRITE_TAC[FORALL_LIFT; IN_ELIM_THM; LIFT_DROP; GSYM RE_DEF] THEN
3258     X_GEN_TAC `x:real` THEN DISCH_TAC THEN
3259     REWRITE_TAC[GSYM CX_ADD; GSYM CX_INV; GSYM CX_MUL; GSYM CX_POW] THEN
3260     REWRITE_TAC[COMPLEX_NORM_DIV; COMPLEX_NORM_CX; RE_CX] THEN
3261     REWRITE_TAC[REAL_ARITH `&1 / &2 / y * x = (&1 / &4) * (&2 / y * x)`] THEN
3262     REWRITE_TAC[real_div] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
3263     REWRITE_TAC[REAL_ABS_POS; REAL_LE_INV_EQ; NORM_POS_LE] THEN CONJ_TAC THENL
3264      [MP_TAC(SPECL [`3`; `frac x`] BERNOULLI_BOUND) THEN
3265       CONV_TAC NUM_REDUCE_CONV THEN
3266       REWRITE_TAC[BERNOULLI_CONV `bernoulli 2 (&0)`] THEN
3267       ANTS_TAC THENL [ALL_TAC; REAL_ARITH_TAC] THEN
3268       SIMP_TAC[IN_REAL_INTERVAL; REAL_LT_IMP_LE; FLOOR_FRAC];
3269       ALL_TAC] THEN
3270     REWRITE_TAC[REAL_POW_INV; GSYM REAL_INV_MUL; GSYM REAL_MUL_ASSOC] THEN
3271     GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [GSYM REAL_INV_INV] THEN
3272     REWRITE_TAC[GSYM REAL_INV_MUL] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
3273     CONJ_TAC THENL
3274      [MATCH_MP_TAC REAL_LT_MUL THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
3275       MATCH_MP_TAC REAL_LT_MUL THEN
3276       CONJ_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC REAL_POW_LT] THEN
3277       ASM_REAL_ARITH_TAC;
3278       ALL_TAC] THEN
3279     REWRITE_TAC[COMPLEX_NORM_POW; REAL_ARITH
3280        `x pow 3 = (x:real) * x pow 2`] THEN
3281     ONCE_REWRITE_TAC[REAL_ARITH `inv(&2) * y * x = y * x / &2`] THEN
3282     MATCH_MP_TAC REAL_LE_MUL2 THEN REPEAT CONJ_TAC THENL
3283      [ASM_REAL_ARITH_TAC;
3284       W(MP_TAC o PART_MATCH (rand o rand) COMPLEX_NORM_GE_RE_IM o
3285         rand o snd) THEN
3286       REWRITE_TAC[IM_ADD; IM_MUL_II; RE_CX; IM_CX] THEN REAL_ARITH_TAC;
3287       REWRITE_TAC[REAL_ARITH `&0 <= x / &2 <=> &0 <= x`] THEN
3288       MATCH_MP_TAC REAL_POW_LE THEN ASM_REAL_ARITH_TAC;
3289
3290       REWRITE_TAC[COMPLEX_SQNORM] THEN
3291       REWRITE_TAC[RE_ADD; IM_ADD; RE_MUL_II; IM_MUL_II; IM_CX; RE_CX] THEN
3292       REWRITE_TAC[REAL_ADD_LID; REAL_ADD_RID; REAL_NEG_0] THEN
3293       MATCH_MP_TAC(REAL_ARITH
3294        `&1 pow 2 <= y pow 2 /\ &0 <= (x - &1) pow 2
3295        ==> (&1 + x) pow 2 / &2 <= x pow 2 + y pow 2`) THEN
3296       REWRITE_TAC[REAL_LE_POW_2] THEN MATCH_MP_TAC REAL_POW_LE2 THEN
3297       ASM_REAL_ARITH_TAC]) in
3298   let lemma8 = prove
3299    (`integral {t | &0 <= drop t}
3300               (\t. Cx (bernoulli 1 (frac (drop t))) / (Cx(&1) + Cx(drop t))) =
3301      Cx(log(&2 * pi) / &2 - &1)`,
3302     MATCH_MP_TAC(MESON[REAL]
3303      `real z /\ Re z = y ==> z = Cx y`) THEN
3304     CONJ_TAC THENL
3305      [MATCH_MP_TAC REAL_COMPLEX_INTEGRAL THEN CONJ_TAC THENL
3306        [ONCE_REWRITE_TAC[COMPLEX_RING `z + x:complex = (z + x) pow 1`] THEN
3307         MATCH_MP_TAC lemma5 THEN
3308         ASM_REWRITE_TAC[LE_REFL; RE_CX; REAL_LT_01];
3309         REWRITE_TAC[GSYM CX_ADD; GSYM CX_DIV; REAL_CX]];
3310       GEN_REWRITE_TAC I [GSYM CX_INJ]] THEN
3311     MATCH_MP_TAC(ISPEC `at_posinfinity` LIM_UNIQUE) THEN
3312     EXISTS_TAC
3313      `\y:real. Cx(Re(integral {t | &0 <= drop t}
3314           (\t. Cx(bernoulli 1 (frac (drop t))) / (Cx(&1) + Cx(drop t)))))` THEN
3315     REWRITE_TAC[TRIVIAL_LIMIT_AT_POSINFINITY; LIM_CONST] THEN
3316     MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
3317     EXISTS_TAC
3318      `\y. Cx(Re(lgamma(ii * Cx y) -
3319           ((ii * Cx y - Cx(&1) / Cx(&2)) * clog(ii * Cx y) -
3320            ii * Cx y + Cx(&1)) +
3321           integral {t | &0 <= drop t}
3322                    (\t. Cx(bernoulli 1 (frac(drop t))) /
3323                         (ii * Cx y + Cx(drop t)))))` THEN
3324     REWRITE_TAC[EVENTUALLY_AT_POSINFINITY; real_ge] THEN CONJ_TAC THENL
3325      [EXISTS_TAC `&1` THEN X_GEN_TAC `y:real` THEN DISCH_TAC THEN
3326       AP_TERM_TAC THEN AP_TERM_TAC THEN
3327       MP_TAC(SPEC `ii * Cx y` lemma6) THEN
3328       ASM_SIMP_TAC[IM_MUL_II; RE_CX; REAL_LT_IMP_NZ] THEN
3329       ANTS_TAC THENL [ASM_REAL_ARITH_TAC; DISCH_THEN SUBST1_TAC] THEN
3330       REWRITE_TAC[COMPLEX_RING `(s + i - j) - s + j:complex = i`];
3331       ALL_TAC] THEN
3332     REWRITE_TAC[RE_ADD; RE_SUB; CX_ADD; CX_SUB] THEN
3333     GEN_REWRITE_TAC LAND_CONV [GSYM COMPLEX_ADD_RID] THEN
3334     MATCH_MP_TAC LIM_ADD THEN CONJ_TAC THENL
3335      [ALL_TAC;
3336       MATCH_MP_TAC LIM_NULL_COMPARISON_COMPLEX THEN
3337       EXISTS_TAC `\y. integral {t | &0 <= drop t}
3338          (\t. Cx(bernoulli 1 (frac(drop t))) / (ii * Cx y + Cx(drop t)))` THEN
3339       REWRITE_TAC[lemma7] THEN MATCH_MP_TAC ALWAYS_EVENTUALLY THEN
3340       REWRITE_TAC[COMPLEX_NORM_CX; COMPLEX_NORM_GE_RE_IM]] THEN
3341     REWRITE_TAC[RE_MUL_II; IM_CX; REAL_NEG_0; COMPLEX_SUB_RZERO; RE_CX] THEN
3342     MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
3343     EXISTS_TAC
3344      `\y. Cx(log(norm(cgamma(ii * Cx y)))) -
3345           (Cx(--(pi * y + log y) / &2) + Cx(&1))` THEN
3346     REWRITE_TAC[EVENTUALLY_AT_POSINFINITY; real_ge] THEN CONJ_TAC THENL
3347      [EXISTS_TAC `&1` THEN X_GEN_TAC `y:real` THEN DISCH_TAC THEN
3348       SUBGOAL_THEN `&0 < y` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
3349       BINOP_TAC THENL
3350        [MP_TAC(SPEC `ii * Cx y` CGAMMA_LGAMMA) THEN COND_CASES_TAC THENL
3351          [FIRST_X_ASSUM(CHOOSE_THEN (MP_TAC o AP_TERM `Im`)) THEN
3352           REWRITE_TAC[IM_ADD; IM_MUL_II; IM_CX; RE_CX] THEN ASM_REAL_ARITH_TAC;
3353           DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[NORM_CEXP; LOG_EXP]];
3354         AP_THM_TAC THEN AP_TERM_TAC THEN
3355         AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN
3356         REWRITE_TAC[COMPLEX_SUB_RDISTRIB; RE_SUB; GSYM CX_DIV] THEN
3357         REWRITE_TAC[GSYM COMPLEX_MUL_ASSOC; RE_MUL_II; IM_MUL_II; RE_MUL_CX;
3358                     IM_MUL_CX] THEN
3359         ASM_SIMP_TAC[RE_CX; IM_CX; REAL_LT_IMP_LE; CX_INJ; REAL_LT_IMP_NZ;
3360                      GSYM CX_LOG; CLOG_MUL_II] THEN
3361         REWRITE_TAC[RE_ADD; IM_ADD; RE_CX; IM_CX; RE_MUL_II; IM_MUL_II] THEN
3362         REAL_ARITH_TAC];
3363       ALL_TAC] THEN
3364     MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
3365     EXISTS_TAC
3366      `\y. Cx((log(&2 * pi) - log(&1 - inv(exp(pi * y) pow 2))) / &2 - &1)` THEN
3367     REWRITE_TAC[EVENTUALLY_AT_POSINFINITY; real_ge] THEN CONJ_TAC THENL
3368      [EXISTS_TAC `&1` THEN X_GEN_TAC `y:real` THEN DISCH_TAC THEN
3369       SUBGOAL_THEN `&0 < y` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
3370       MP_TAC(SPEC `ii * Cx y + Cx(&1)` CGAMMA_REFLECTION) THEN
3371       REWRITE_TAC[CGAMMA_RECURRENCE; COMPLEX_ENTIRE; II_NZ; CX_INJ] THEN
3372       ASM_SIMP_TAC[REAL_LT_IMP_NZ] THEN
3373       REWRITE_TAC[COMPLEX_RING `Cx(&1) - (z + Cx(&1)) = --z`] THEN
3374       MP_TAC(SPEC `cgamma(ii * Cx y)` COMPLEX_NORM_POW_2) THEN
3375       REWRITE_TAC[CNJ_MUL; CNJ_II; CNJ_CX; CNJ_CGAMMA] THEN
3376       REWRITE_TAC[COMPLEX_MUL_LNEG; GSYM COMPLEX_MUL_ASSOC] THEN
3377       DISCH_THEN(SUBST1_TAC o SYM) THEN
3378       REWRITE_TAC[COMPLEX_RING `w * (z + Cx(&1)) = w * z + w`] THEN
3379       REWRITE_TAC[CSIN_ADD; GSYM CX_SIN; GSYM CX_COS; SIN_PI; COS_PI] THEN
3380       REWRITE_TAC[COMPLEX_MUL_RZERO; CX_NEG; COMPLEX_MUL_RNEG] THEN
3381       REWRITE_TAC[COMPLEX_ADD_RID; COMPLEX_MUL_RID] THEN
3382       REWRITE_TAC[csin; COMPLEX_RING `--ii * x * ii * y = x * y`] THEN
3383       REWRITE_TAC[COMPLEX_RING `ii * x * ii * y = --(x * y)`] THEN
3384       REWRITE_TAC[complex_div; COMPLEX_INV_INV; COMPLEX_INV_MUL;
3385                   COMPLEX_INV_NEG; COMPLEX_MUL_RNEG] THEN
3386       ASM_SIMP_TAC[CX_INJ; REAL_LT_IMP_NZ; COMPLEX_FIELD
3387        `~(y = Cx(&0))
3388         ==> (ii * y * z = --(p * i * Cx(&2) * ii) <=>
3389              z = --(Cx(&2) * p) * inv y * i)`] THEN
3390       REWRITE_TAC[GSYM COMPLEX_INV_MUL; GSYM CX_MUL;
3391                   GSYM CX_EXP; CEXP_NEG] THEN
3392       REWRITE_TAC[COMPLEX_MUL_LNEG; GSYM COMPLEX_MUL_RNEG;
3393                   COMPLEX_NEG_INV] THEN
3394       REWRITE_TAC[COMPLEX_NEG_SUB] THEN
3395       REWRITE_TAC[GSYM CX_INV; GSYM CX_SUB; GSYM CX_MUL; GSYM CX_INV] THEN
3396       REWRITE_TAC[CX_INJ; GSYM CX_POW] THEN
3397       DISCH_THEN(MP_TAC o AP_TERM `sqrt`) THEN
3398       REWRITE_TAC[POW_2_SQRT_ABS; REAL_ABS_NORM] THEN
3399       DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[REAL_INV_MUL] THEN
3400       SUBGOAL_THEN `&0 < exp(pi * y) - inv(exp(pi * y))` ASSUME_TAC THENL
3401        [MATCH_MP_TAC(REAL_ARITH `x < &1 /\ &1 < y ==> &0 < y - x`) THEN
3402         CONJ_TAC THENL [MATCH_MP_TAC REAL_INV_LT_1; ALL_TAC] THEN
3403         MATCH_MP_TAC REAL_EXP_LT_1 THEN MATCH_MP_TAC REAL_LT_MUL THEN
3404         ASM_REWRITE_TAC[PI_POS];
3405         ASM_SIMP_TAC[LOG_MUL; REAL_LT_INV_EQ; PI_POS; REAL_LT_MUL;
3406                  REAL_ARITH `&0 < &2 * x <=> &0 < x`; LOG_SQRT; LOG_INV]] THEN
3407       REWRITE_TAC[GSYM CX_ADD; GSYM CX_SUB] THEN
3408       REWRITE_TAC[REAL_ARITH
3409       `(l2 + --l + x) / &2 - (--(py + l) / &2 + &1) =
3410        (l2 + py + x) / &2 - &1`] THEN
3411       SIMP_TAC[REAL_EXP_NZ; REAL_FIELD
3412        `~(e = &0) ==> e - inv e = e * (&1 - inv(e pow 2))`] THEN
3413       SUBGOAL_THEN `inv (exp (pi * y) pow 2) < &1` ASSUME_TAC THENL
3414        [MATCH_MP_TAC REAL_INV_LT_1 THEN
3415         MATCH_MP_TAC REAL_POW_LT_1 THEN
3416         REWRITE_TAC[ARITH] THEN
3417         MATCH_MP_TAC REAL_EXP_LT_1 THEN
3418         MATCH_MP_TAC REAL_LT_MUL THEN
3419         ASM_SIMP_TAC[REAL_LT_MUL; PI_POS];
3420         ASM_SIMP_TAC[LOG_MUL; REAL_EXP_POS_LT; REAL_SUB_LT; LOG_EXP]] THEN
3421       REWRITE_TAC[CX_INJ] THEN REAL_ARITH_TAC;
3422       ALL_TAC] THEN
3423     REWRITE_TAC[CX_SUB; CX_DIV] THEN MATCH_MP_TAC LIM_SUB THEN
3424     REWRITE_TAC[LIM_CONST] THEN
3425     MATCH_MP_TAC LIM_COMPLEX_DIV THEN REWRITE_TAC[LIM_CONST] THEN
3426     CONJ_TAC THENL [ALL_TAC; CONV_TAC COMPLEX_RING] THEN
3427     GEN_REWRITE_TAC LAND_CONV [GSYM COMPLEX_SUB_RZERO] THEN
3428     MATCH_MP_TAC LIM_SUB THEN REWRITE_TAC[LIM_CONST] THEN
3429     MP_TAC(ISPECL
3430      [`clog`; `at_posinfinity`;
3431       `\y. Cx(&1 - inv(exp(pi * y) pow 2))`;
3432       `Cx(&1)`] LIM_CONTINUOUS_FUNCTION) THEN
3433     REWRITE_TAC[CLOG_1] THEN ANTS_TAC THENL
3434      [SIMP_TAC[CONTINUOUS_AT_CLOG; RE_CX; REAL_LT_01; CX_SUB] THEN
3435       GEN_REWRITE_TAC LAND_CONV [GSYM COMPLEX_SUB_RZERO] THEN
3436       MATCH_MP_TAC LIM_SUB THEN REWRITE_TAC[LIM_CONST] THEN
3437       REWRITE_TAC[CX_INV; CX_EXP; CX_POW; GSYM COMPLEX_POW_INV] THEN
3438       MATCH_MP_TAC LIM_NULL_COMPLEX_POW THEN CONV_TAC NUM_REDUCE_CONV THEN
3439       REWRITE_TAC[LIM_AT_POSINFINITY] THEN
3440       X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3441       EXISTS_TAC `&1 + inv(e)` THEN REWRITE_TAC[dist; real_ge] THEN
3442       X_GEN_TAC `x:real` THEN DISCH_TAC THEN
3443       REWRITE_TAC[COMPLEX_SUB_RZERO; COMPLEX_NORM_INV] THEN
3444       MATCH_MP_TAC REAL_LT_LINV THEN ASM_REWRITE_TAC[NORM_CEXP; RE_CX] THEN
3445       FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
3446        `&1 + e <= x
3447         ==> &1 + pi * x <= z /\ &0 <= x * (pi - &1)  ==> e < z`)) THEN
3448       REWRITE_TAC[REAL_EXP_LE_X] THEN MATCH_MP_TAC REAL_LE_MUL THEN
3449       MP_TAC(SPEC `e:real` REAL_LT_INV_EQ) THEN
3450       MP_TAC PI_APPROX_32 THEN ASM_REAL_ARITH_TAC;
3451       MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
3452       REWRITE_TAC[EVENTUALLY_AT_POSINFINITY; real_ge] THEN
3453       EXISTS_TAC `&1` THEN X_GEN_TAC `y:real` THEN DISCH_TAC THEN
3454       SUBGOAL_THEN `&0 < y` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
3455       MATCH_MP_TAC(GSYM CX_LOG) THEN REWRITE_TAC[REAL_SUB_LT] THEN
3456       MATCH_MP_TAC REAL_INV_LT_1 THEN MATCH_MP_TAC REAL_POW_LT_1 THEN
3457       REWRITE_TAC[ARITH] THEN MATCH_MP_TAC REAL_EXP_LT_1 THEN
3458       MATCH_MP_TAC REAL_LT_MUL THEN ASM_SIMP_TAC[REAL_LT_MUL; PI_POS]]) in
3459   CONJ_TAC THENL [MATCH_ACCEPT_TAC lemma5; ALL_TAC] THEN
3460   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[lemma6] THEN
3461   REWRITE_TAC[lemma8; CX_SUB] THEN
3462   REWRITE_TAC[COMPLEX_RING
3463    `(x + Cx(&1)) + (a - Cx(&1)) - b = (x + a) - b`] THEN
3464   REWRITE_TAC[complex_sub; GSYM COMPLEX_ADD_ASSOC] THEN AP_TERM_TAC THEN
3465   AP_TERM_TAC THEN AP_TERM_TAC THEN  ASM_CASES_TAC `p = 0` THENL
3466    [ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG] THEN
3467     CONV_TAC NUM_REDUCE_CONV THEN
3468     REWRITE_TAC[COMPLEX_POW_1; COMPLEX_DIV_1; VECTOR_ADD_LID];
3469     MP_TAC(SPECL [`z:complex`; `p:num`] lemma4) THEN
3470     ASM_SIMP_TAC[LE_1] THEN
3471     DISCH_THEN(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN
3472     REWRITE_TAC[complex_sub; COMPLEX_NEG_ADD; VECTOR_NEG_NEG] THEN
3473     REWRITE_TAC[COMPLEX_ADD_SYM]]);;
3474
3475 let LOG_GAMMA_STIRLING = prove
3476  (`!x p. &0 < x
3477          ==> log(gamma x) =
3478              ((x - &1 / &2) * log(x) - x + log(&2 * pi) / &2) +
3479              sum(1..p) (\k. bernoulli (2 * k) (&0) /
3480                             (&4 * &k pow 2 - &2 * &k) / x pow (2 * k - 1)) -
3481              real_integral {t | &0 <= t}
3482                            (\t. bernoulli (2 * p + 1) (frac t) /
3483                                 (x + t) pow (2 * p + 1)) /
3484              &(2 * p + 1)`,
3485   REPEAT STRIP_TAC THEN
3486   GEN_REWRITE_TAC I [GSYM REAL_EXP_INJ] THEN
3487   ASM_SIMP_TAC[EXP_LOG; GAMMA_POS_LT] THEN
3488   GEN_REWRITE_TAC I [GSYM CX_INJ] THEN REWRITE_TAC[CX_GAMMA] THEN
3489   MP_TAC(ISPEC `Cx x` CGAMMA_LGAMMA) THEN
3490   COND_CASES_TAC THENL
3491    [FIRST_ASSUM(CHOOSE_THEN (MP_TAC o AP_TERM `Re`)) THEN
3492     REWRITE_TAC[RE_ADD; RE_CX] THEN ASM_REAL_ARITH_TAC;
3493     ALL_TAC] THEN
3494   DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[CX_EXP] THEN AP_TERM_TAC THEN
3495   MP_TAC(ISPECL [`Cx x`; `p:num`] LGAMMA_STIRLING) THEN
3496   ASM_REWRITE_TAC[RE_CX; CX_GAMMA] THEN DISCH_THEN SUBST1_TAC THEN
3497   REWRITE_TAC[CX_ADD; CX_SUB; CX_DIV; CX_MUL; GSYM VSUM_CX] THEN
3498   ASM_SIMP_TAC[GSYM CX_LOG; CX_POW] THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
3499   AP_THM_TAC THEN AP_TERM_TAC THEN
3500   REWRITE_TAC[COMPLEX_EQ; RE_CX; IM_CX] THEN
3501   REWRITE_TAC[RE_DEF; IM_DEF] THEN CONJ_TAC THEN
3502   W(MP_TAC o PART_MATCH (lhand o rand) INTEGRAL_COMPONENT o lhand o snd) THEN
3503   ASM_SIMP_TAC[LGAMMA_STIRLING_INTEGRALS_EXIST;
3504                ARITH_RULE `1 <= 2 * p + 1`; RE_CX] THEN
3505   DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[GSYM RE_DEF; GSYM IM_DEF] THEN
3506   REWRITE_TAC[GSYM CX_ADD; GSYM CX_POW; GSYM CX_DIV; RE_CX; IM_CX] THEN
3507   REWRITE_TAC[LIFT_NUM; INTEGRAL_0; DROP_VEC] THEN
3508   SUBGOAL_THEN
3509    `{t | &0 <= drop t} = IMAGE lift {t | &0 <= t}`
3510   SUBST1_TAC THENL
3511    [REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP];
3512     MATCH_MP_TAC(GSYM(REWRITE_RULE[o_DEF] REAL_INTEGRAL))] THEN
3513   REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF] THEN
3514   MP_TAC(SPECL [`Cx x`; `2 * p + 1`] LGAMMA_STIRLING_INTEGRALS_EXIST) THEN
3515   ASM_REWRITE_TAC[RE_CX; ARITH_RULE `1 <= 2 * p + 1`] THEN
3516   GEN_REWRITE_TAC LAND_CONV [INTEGRABLE_COMPONENTWISE] THEN
3517   DISCH_THEN(MP_TAC o SPEC `1`) THEN REWRITE_TAC[DIMINDEX_2; ARITH] THEN
3518   REWRITE_TAC[GSYM CX_ADD; GSYM CX_POW; GSYM CX_DIV; RE_CX; GSYM RE_DEF] THEN
3519   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
3520   REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);;
3521
3522 (* ------------------------------------------------------------------------- *)
3523 (* Some other mathematical facts that don't directly involve the gamma       *)
3524 (* function can now be proved relatively easily: Euler's product for sin,    *)
3525 (* Wallis's product for pi, and the Gaussian integral.                       *)
3526 (* ------------------------------------------------------------------------- *)
3527
3528 let CSIN_PRODUCT = prove
3529  (`!z. ((\n. z * cproduct(1..n) (\m. Cx(&1) - (z / Cx(pi * &m)) pow 2))
3530        --> csin(z)) sequentially`,
3531   GEN_TAC THEN REWRITE_TAC[CX_MUL; complex_div; COMPLEX_INV_MUL] THEN
3532   REWRITE_TAC[COMPLEX_MUL_ASSOC] THEN REWRITE_TAC[GSYM complex_div] THEN
3533   ABBREV_TAC `w = z / Cx pi` THEN
3534   SUBGOAL_THEN `Cx pi * w = z` ASSUME_TAC THENL
3535    [EXPAND_TAC "w" THEN MP_TAC PI_NZ THEN REWRITE_TAC[GSYM CX_INJ] THEN
3536     CONV_TAC COMPLEX_FIELD;
3537     EXPAND_TAC "z" THEN
3538     SUBGOAL_THEN `csin (Cx pi * w) = Cx pi * csin(Cx pi * w) / Cx pi`
3539     SUBST1_TAC THENL
3540      [MP_TAC PI_NZ THEN REWRITE_TAC[GSYM CX_INJ] THEN CONV_TAC COMPLEX_FIELD;
3541       REWRITE_TAC[GSYM COMPLEX_MUL_ASSOC] THEN
3542       MATCH_MP_TAC LIM_COMPLEX_LMUL THEN
3543       ONCE_REWRITE_TAC[GSYM COMPLEX_INV_DIV] THEN
3544       REWRITE_TAC[GSYM CGAMMA_REFLECTION] THEN
3545       REWRITE_TAC[COMPLEX_INV_DIV; COMPLEX_INV_MUL] THEN
3546       POP_ASSUM_LIST(K ALL_TAC) THEN SPEC_TAC(`w:complex`,`z:complex`)]] THEN
3547   X_GEN_TAC `z:complex` THEN
3548   MP_TAC(SPEC `z:complex` RECIP_CGAMMA) THEN
3549   MP_TAC(SPEC `Cx(&1) - z` RECIP_CGAMMA) THEN
3550   REWRITE_TAC[COMPLEX_RING `Cx(&1) - z + m = (m + Cx(&1)) - z`] THEN
3551   REWRITE_TAC[GSYM CX_ADD; REAL_OF_NUM_ADD] THEN
3552   REWRITE_TAC[GSYM
3553    (ISPECL [`f:num->complex`; `m:num`; `1`] CPRODUCT_OFFSET)] THEN
3554   SIMP_TAC[CPRODUCT_CLAUSES_LEFT; LE_0] THEN
3555   REWRITE_TAC[ADD_CLAUSES; COMPLEX_ADD_RID; GSYM IMP_CONJ_ALT] THEN
3556   SIMP_TAC[CPRODUCT_CLAUSES_RIGHT; ARITH_RULE `0 < n + 1 /\ 1 <= n + 1`] THEN
3557   DISCH_THEN(MP_TAC o MATCH_MP LIM_COMPLEX_MUL) THEN
3558   REWRITE_TAC[GSYM REAL_OF_NUM_ADD; CX_ADD; ADD_SUB] THEN
3559   SUBGOAL_THEN `((\n. Cx(&n) / (Cx(&n) + Cx(&1) - z)) --> Cx(&1)) sequentially`
3560   MP_TAC THENL
3561    [GEN_REWRITE_TAC LAND_CONV [GSYM COMPLEX_INV_1] THEN
3562     ONCE_REWRITE_TAC[GSYM COMPLEX_INV_DIV] THEN
3563     MATCH_MP_TAC LIM_COMPLEX_INV THEN
3564     CONJ_TAC THENL [ALL_TAC; CONV_TAC COMPLEX_RING] THEN
3565     REWRITE_TAC[complex_div; COMPLEX_ADD_RDISTRIB] THEN
3566     GEN_REWRITE_TAC LAND_CONV [GSYM COMPLEX_ADD_RID] THEN
3567     MATCH_MP_TAC LIM_ADD THEN
3568     SIMP_TAC[LIM_INV_N; LIM_NULL_COMPLEX_LMUL] THEN
3569     MATCH_MP_TAC LIM_EVENTUALLY THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
3570     EXISTS_TAC `1` THEN
3571     SIMP_TAC[COMPLEX_MUL_RINV; CX_INJ; REAL_OF_NUM_EQ; LE_1];
3572     REWRITE_TAC[IMP_IMP] THEN
3573     DISCH_THEN(MP_TAC o MATCH_MP LIM_COMPLEX_MUL)] THEN
3574   REWRITE_TAC[COMPLEX_MUL_LID] THEN
3575   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
3576   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
3577   MP_TAC(ISPEC `norm(z:complex)` REAL_ARCH_SIMPLE) THEN
3578   DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
3579   EXISTS_TAC `MAX 1 N` THEN X_GEN_TAC `n:num` THEN
3580   REWRITE_TAC[ARITH_RULE `MAX a b <= c <=> a <= c /\ b <= c`] THEN
3581   STRIP_TAC THEN REWRITE_TAC[CPOW_SUB; CPOW_N; COMPLEX_POW_1] THEN
3582   ASM_SIMP_TAC[CX_INJ; REAL_OF_NUM_EQ; LE_1] THEN
3583   REWRITE_TAC[complex_div; COMPLEX_INV_MUL; COMPLEX_INV_INV] THEN
3584   REWRITE_TAC[GSYM COMPLEX_MUL_ASSOC] THEN REWRITE_TAC[COMPLEX_RING
3585    `a * b * c * d * e * f * g * h * i * j * k :complex =
3586     (a * i) * (j * e) * (h * b) * c * (d * g) * (f * k)`] THEN
3587   SUBGOAL_THEN `~((Cx(&n) + Cx(&1)) - z = Cx(&0))` ASSUME_TAC THENL
3588    [REWRITE_TAC[COMPLEX_SUB_0; GSYM CX_ADD] THEN
3589     DISCH_THEN(MP_TAC o AP_TERM `norm:complex->real`) THEN
3590     REWRITE_TAC[COMPLEX_NORM_CX] THEN
3591     RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN
3592     ASM_REAL_ARITH_TAC;
3593     REWRITE_TAC[COMPLEX_RING `n + Cx(&1) - z = (n + Cx(&1)) - z`]] THEN
3594   ASM_SIMP_TAC[COMPLEX_MUL_RINV; CX_INJ; REAL_OF_NUM_EQ; CPOW_EQ_0; LE_1] THEN
3595   REWRITE_TAC[COMPLEX_MUL_LID] THEN AP_TERM_TAC THEN
3596   SIMP_TAC[GSYM NPRODUCT_FACT; REAL_OF_NUM_NPRODUCT; CX_PRODUCT; FINITE_NUMSEG;
3597            GSYM CPRODUCT_INV; GSYM CPRODUCT_MUL] THEN
3598   MATCH_MP_TAC CPRODUCT_EQ THEN X_GEN_TAC `k:num` THEN
3599   REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN
3600   SUBGOAL_THEN `~(Cx(&k) = Cx(&0))` MP_TAC THENL
3601    [ASM_SIMP_TAC[CX_INJ; REAL_OF_NUM_EQ; LE_1];
3602     CONV_TAC COMPLEX_FIELD]);;
3603
3604 let SIN_PRODUCT = prove
3605  (`!x. ((\n. x * product(1..n) (\m. &1 - (x / (pi * &m)) pow 2)) ---> sin(x))
3606        sequentially`,
3607   GEN_TAC THEN MP_TAC(SPEC `Cx x` CSIN_PRODUCT) THEN
3608   REWRITE_TAC[REALLIM_COMPLEX; o_DEF] THEN
3609   SIMP_TAC[CX_MUL; CX_PRODUCT; FINITE_NUMSEG; CX_SIN] THEN
3610   REWRITE_TAC[CX_SUB; CX_DIV; CX_POW; CX_MUL]);;
3611
3612 let WALLIS_ALT = prove
3613  (`((\n. product(1..n) (\k. (&2 * &k) / (&2 * &k - &1) *
3614                             (&2 * &k) / (&2 * &k + &1))) ---> pi / &2)
3615    sequentially`,
3616   ONCE_REWRITE_TAC[GSYM REAL_INV_INV] THEN MATCH_MP_TAC REALLIM_INV THEN
3617   CONJ_TAC THENL [ALL_TAC; MP_TAC PI_POS THEN CONV_TAC REAL_FIELD] THEN
3618   MP_TAC(SPEC `pi / &2` SIN_PRODUCT) THEN REWRITE_TAC[SIN_PI2] THEN
3619   REWRITE_TAC[real_div; REAL_INV_MUL; REAL_MUL_ASSOC; REAL_INV_INV] THEN
3620   DISCH_THEN(MP_TAC o SPEC `inv pi * &2` o MATCH_MP REALLIM_LMUL) THEN
3621   SIMP_TAC[REAL_MUL_RID; PI_NZ; REAL_FIELD
3622    `~(pi = &0) ==> (pi * x) * inv pi = x /\
3623                    (inv pi * &2) * (pi * inv(&2)) * y = y`] THEN
3624   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REALLIM_TRANSFORM_EVENTUALLY) THEN
3625   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
3626   X_GEN_TAC `n:num` THEN DISCH_TAC THEN
3627   SIMP_TAC[GSYM PRODUCT_INV; FINITE_NUMSEG] THEN
3628   MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN REWRITE_TAC[GSYM REAL_OF_NUM_LE] THEN
3629   CONV_TAC REAL_FIELD);;
3630
3631 let WALLIS = prove
3632  (`((\n. (&2 pow n * &(FACT n)) pow 4 / (&(FACT(2 * n)) * &(FACT(2 * n + 1))))
3633     ---> pi / &2) sequentially`,
3634   MP_TAC WALLIS_ALT THEN
3635   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REALLIM_TRANSFORM_EVENTUALLY) THEN
3636   MATCH_MP_TAC ALWAYS_EVENTUALLY THEN REWRITE_TAC[] THEN
3637   MATCH_MP_TAC num_INDUCTION THEN REWRITE_TAC[PRODUCT_CLAUSES_NUMSEG] THEN
3638   CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
3639   X_GEN_TAC `n:num` THEN DISCH_TAC THEN
3640   ASM_REWRITE_TAC[ARITH_RULE `1 <= SUC n`] THEN
3641   REWRITE_TAC[GSYM ADD1; ARITH_RULE `2 * SUC n = SUC(SUC(2 * n))`] THEN
3642   REWRITE_TAC[FACT; real_pow; GSYM REAL_OF_NUM_MUL] THEN
3643   REWRITE_TAC[GSYM REAL_OF_NUM_SUC; GSYM REAL_OF_NUM_MUL] THEN
3644   MAP_EVERY (MP_TAC o C SPEC FACT_NZ) [`n:num`; `2 * n`] THEN
3645   REWRITE_TAC[GSYM REAL_OF_NUM_EQ] THEN CONV_TAC REAL_FIELD);;
3646
3647 let GAUSSIAN_INTEGRAL = prove
3648  (`((\x. exp(--(x pow 2))) has_real_integral sqrt pi) (:real)`,
3649   SUBGOAL_THEN
3650    `((\x. exp(--(x pow 2))) has_real_integral gamma(&1 / &2) / &2)
3651     {x | &0 <= x}`
3652   ASSUME_TAC THENL
3653    [ALL_TAC;
3654     SUBGOAL_THEN
3655      `(:real) = {x | &0 <= x} UNION IMAGE (--) {x | &0 <= x}`
3656     SUBST1_TAC THENL
3657      [REWRITE_TAC[EXTENSION; IN_UNION; IN_IMAGE; IN_UNIV; IN_ELIM_THM] THEN
3658       REWRITE_TAC[REAL_ARITH `x:real = --y <=> --x = y`; UNWIND_THM1] THEN
3659       REAL_ARITH_TAC;
3660       ONCE_REWRITE_TAC[REAL_ARITH `sqrt x = sqrt x / &2 + sqrt x / &2`]] THEN
3661     MATCH_MP_TAC HAS_REAL_INTEGRAL_UNION THEN
3662     REWRITE_TAC[GSYM HAS_REAL_INTEGRAL_REFLECT_GEN] THEN
3663     ASM_SIMP_TAC[REAL_POW_NEG; ARITH; GSYM GAMMA_HALF] THEN
3664     MATCH_MP_TAC REAL_NEGLIGIBLE_SUBSET THEN EXISTS_TAC `{&0}` THEN
3665     REWRITE_TAC[REAL_NEGLIGIBLE_SING; IN_ELIM_THM; SET_RULE
3666     `s INTER IMAGE f s SUBSET {a} <=> !x. x IN s /\ f x IN s ==> f x = a`] THEN
3667     REAL_ARITH_TAC] THEN
3668   MP_TAC(SPEC `&1 / &2` EULER_HAS_REAL_INTEGRAL_GAMMA) THEN
3669   CONV_TAC REAL_RAT_REDUCE_CONV THEN
3670   DISCH_THEN(MP_TAC o SPEC `inv(&2)` o MATCH_MP HAS_REAL_INTEGRAL_RMUL) THEN
3671   REWRITE_TAC[GSYM real_div] THEN
3672   ONCE_REWRITE_TAC[HAS_REAL_INTEGRAL_ALT] THEN
3673   REWRITE_TAC[HAS_REAL_INTEGRAL_RESTRICT_INTER;
3674            REAL_INTEGRABLE_RESTRICT_INTER; REAL_INTEGRAL_RESTRICT_INTER] THEN
3675   REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN
3676   REWRITE_TAC[TAUT `p /\ q <=> ~(p ==> ~q)`] THEN
3677   SIMP_TAC[REAL_ARITH `&0 < B ==> --B <= B /\ ~(B <= --B)`] THEN
3678   REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC; INTER; IN_REAL_INTERVAL] THEN
3679   REWRITE_TAC[IN_ELIM_THM; REAL_ARITH
3680    `&0 <= x /\ (a <= x /\ x <= b) <=> max (&0) a <= x /\ x <= b`] THEN
3681   REWRITE_TAC[GSYM real_interval] THEN
3682   ONCE_REWRITE_TAC[REAL_ARITH
3683    `a <= --B /\ --B < B /\ B <= b <=>
3684     max (&0) a = &0 /\ &0 < B /\ a <= --B /\ B <= b`] THEN
3685   SIMP_TAC[] THEN
3686   REWRITE_TAC[REAL_ARITH
3687    `max (&0) a = &0 /\ &0 < B /\ a <= --B /\ B <= b <=>
3688     a <= --B /\ &0 < B /\ B <= b`] THEN
3689   GEN_REWRITE_TAC (BINOP_CONV o ONCE_DEPTH_CONV) [IMP_CONJ] THEN
3690   REWRITE_TAC[RIGHT_FORALL_IMP_THM; LEFT_FORALL_IMP_THM] THEN
3691   REWRITE_TAC[MESON[REAL_LE_REFL] `?a. a <= B`] THEN
3692   ONCE_REWRITE_TAC[
3693    MESON[REAL_ARITH `a <= max a b /\ (&0 <= a ==> max (&0) a = a)`]
3694    `(!a. P (max (&0) a)) <=> (!a. &0 <= a ==> P a)`] THEN
3695   REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN STRIP_TAC THEN
3696   SUBGOAL_THEN
3697    `!a b. &0 <= a /\ a <= b
3698           ==> ((\x. exp(--(x pow 2))) has_real_integral
3699                real_integral (real_interval[a pow 2,b pow 2])
3700                              (\t. t rpow (-- &1 / &2) / exp t / &2))
3701               (real_interval[a,b])`
3702   MP_TAC THENL
3703    [REPEAT STRIP_TAC THEN
3704     MP_TAC(ISPECL
3705      [`\t. t rpow (&1 / &2 - &1) / exp t / &2`;
3706       `\x:real. x pow 2`; `\x. &2 * x`;
3707       `a:real`; `b:real`; `(a:real) pow 2`; `(b:real) pow 2`; `{&0}`]
3708      HAS_REAL_INTEGRAL_SUBSTITUTION_STRONG) THEN
3709     REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
3710     ASM_SIMP_TAC[REAL_LE_REFL; REAL_LE_POW_2; COUNTABLE_SING;
3711                  REAL_POW_LE2] THEN
3712     ANTS_TAC THENL
3713      [REPEAT CONJ_TAC THENL
3714        [MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON THEN
3715         REWRITE_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE] THEN
3716         REPEAT STRIP_TAC THEN REAL_DIFFERENTIABLE_TAC;
3717         REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_REAL_INTERVAL] THEN
3718         SIMP_TAC[REAL_LE_POW_2; GSYM REAL_LE_SQUARE_ABS] THEN
3719         ASM_REAL_ARITH_TAC;
3720         REWRITE_TAC[IN_DIFF; IN_SING; IN_REAL_INTERVAL] THEN
3721         REPEAT STRIP_TAC THENL
3722          [REAL_DIFF_TAC THEN CONV_TAC NUM_REDUCE_CONV THEN
3723           REAL_ARITH_TAC;
3724           MATCH_MP_TAC REAL_DIFFERENTIABLE_IMP_CONTINUOUS_WITHINREAL THEN
3725           REAL_DIFFERENTIABLE_TAC THEN
3726           ASM_REWRITE_TAC[REAL_LT_POW_2; REAL_EXP_NZ]]];
3727       MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ]
3728        (REWRITE_RULE[CONJ_ASSOC] HAS_REAL_INTEGRAL_SPIKE)) THEN
3729       EXISTS_TAC `{&0}` THEN REWRITE_TAC[REAL_NEGLIGIBLE_SING] THEN
3730       X_GEN_TAC `x:real` THEN
3731       REWRITE_TAC[IN_REAL_INTERVAL; IN_DIFF; IN_SING] THEN STRIP_TAC THEN
3732       SUBGOAL_THEN `&0 <= x` ASSUME_TAC THENL
3733        [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
3734       REWRITE_TAC[REAL_EXP_NEG; GSYM RPOW_POW] THEN
3735       ASM_SIMP_TAC[RPOW_RPOW] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
3736       REWRITE_TAC[RPOW_NEG; RPOW_POW; REAL_POW_1] THEN
3737       MP_TAC(SPEC `(x:real) pow 2` REAL_EXP_NZ) THEN
3738       UNDISCH_TAC `~(x = &0)` THEN CONV_TAC REAL_FIELD];
3739     FIRST_X_ASSUM(K ALL_TAC o SPECL [`a:real`; `b:real`]) THEN
3740     DISCH_THEN(LABEL_TAC "*")] THEN
3741   CONJ_TAC THENL
3742    [MAP_EVERY X_GEN_TAC [`a:real`; `b:real`] THEN STRIP_TAC THEN
3743     DISJ_CASES_TAC(REAL_ARITH `b <= a \/ a <= b`) THEN
3744     ASM_SIMP_TAC[REAL_INTEGRABLE_ON_NULL] THEN
3745     REWRITE_TAC[real_integrable_on] THEN ASM_MESON_TAC[];
3746     ALL_TAC] THEN
3747   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3748   REMOVE_THEN "*" (MP_TAC o SPEC `&0`) THEN
3749   REWRITE_TAC[REAL_LE_REFL; HAS_REAL_INTEGRAL_INTEGRABLE_INTEGRAL] THEN
3750   ONCE_REWRITE_TAC[REAL_ARITH
3751    `&0 < B /\ B <= b <=> &0 < B /\ B <= b /\ &0 <= b`] THEN
3752   SIMP_TAC[] THEN DISCH_THEN(K ALL_TAC) THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
3753   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
3754   DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
3755   EXISTS_TAC `max B (&1)` THEN
3756   ASM_REWRITE_TAC[REAL_LT_MAX; REAL_MAX_LE] THEN
3757   X_GEN_TAC `b:real` THEN STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
3758   ASM_REWRITE_TAC[] THEN TRANS_TAC REAL_LE_TRANS `(b:real) pow 1` THEN
3759   CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
3760   MATCH_MP_TAC REAL_POW_MONO THEN ASM_REWRITE_TAC[ARITH]);;