2 * HOL Light proof that e is transcendental.
4 * This HOL Light proof and its relationship to the informal proof is
7 * "Formalizing a Proof that e is Transcendental", Journal of Formal
8 * Reasoning, Vol 4, No 1. 2011.
10 * It follows the informal proof provided by the good folks at the
13 * http://planetmath.org/encyclopedia/EIsTranscendental2.html
15 * Note: the original proof script linked to in the above paper
16 * partitioned the proofs amongst several files, each encapsulated
17 * in an Ocaml module. This file has simply concatenated those files
18 * and hence the module structure persists.
20 * Jesse Bingham, Jan 2012
21 * jesse.d.bingham@intel.com
22 * jesse.bingham@gmail.com
25 (* this is needed since the sum from the HOL core (iter.ml, i think)
26 * which is used below, gets overwritten when Library/analysis.ml is loaded.
30 (* required stuff from HOL Light library... *)
31 needs "Library/binomial.ml";;
32 needs "Library/analysis.ml";;
33 needs "Library/transc.ml";;
34 needs "Library/prime.ml";;
35 needs "Library/iter.ml";;
36 needs "Library/integer.ml";;
37 needs "Library/floor.ml";;
38 (* get def of transcendental from Harrison's Liouville proof *)
39 needs "100/liouville.ml";;
44 * A few misculaneous proof utility functions
47 (* A listified version of ADD_ASSUM *)
48 let ADD_ASSUMS lst thm =
49 let f x y = ADD_ASSUM y x in
50 List.fold_left f thm lst
52 (* A tactic that takes a goal with an assumption A /\ B and replaces
53 * it with a goal with the two assumptions A and B
55 let SPLIT_CONJOINED_ASSUMPT_TAC t =
57 (ONCE_REWRITE_TAC [TAUT `(X /\ Y ==> Z) <=> (X ==> Y ==> Z)`]) THEN
58 (DISCH_TAC THEN DISCH_TAC)
60 (* Adds an assumption and discharges it in one fell swoop *)
61 let ADD_ASSUM_DISCH ass thm = DISCH ass (ADD_ASSUM ass thm);;
62 (* BRW = Bolean ReWrite *)
63 let BRW t f = ONCE_REWRITE_RULE [TAUT t] f;;
64 (* Those two boolean rewrites come in handy *)
65 let BRW0 f = BRW `(X ==> Y ==> Z) <=> (X /\ Y ==> Z)` f;;
66 let BRW1 f = BRW `(X /\ Y ==> Z) <=> (X ==> Y ==> Z)` f;;
67 (* a bunch of trivial real theorems that are useful for
68 * rewriting/simplifying/mesoning
70 let rewrites0 = map REAL_ARITH [`&0 + (y:real) = y`;`(x:real) * &0 = &0`;`(&1:real) + &0 = &1`;`(x:real) * &1 = x`];;
72 module Pm_lemma1 = struct
74 let PDI_DEF = new_recursive_definition num_RECURSION
75 ` (poly_diff_iter p 0 = p)
76 /\ (poly_diff_iter p (SUC n) = poly_diff (poly_diff_iter p n))
78 let PDI_POLY_DIFF_COMM = prove(
79 `! p n.(poly_diff_iter (poly_diff p) n) = (poly_diff (poly_diff_iter p n))`,
80 STRIP_TAC THEN INDUCT_TAC THEN (ASM_SIMP_TAC [PDI_DEF])
83 let SODN = new_definition
84 `SODN p n = iterate poly_add (0..n) (\i.poly_diff_iter p i)`
86 let SOD = new_definition `!p. SOD p = SODN p (LENGTH p)`;;
88 let PHI = new_definition `Phi f x = (exp (-- x)) * (poly (SOD f) x)`
90 let PLANETMATH_EQN_1_1_1 = prove(
91 `! x f.((Phi f) diffl ((exp (--x)) * ((poly (poly_diff (SOD f)) x) - (poly (SOD f) x))) )(x)`,
92 let lem1 = SPECL [`\x.exp (--x)`;
95 `poly (poly_diff (SOD f)) x`;
97 let EXP_NEG_X_DIFF = prove(
98 `!x. ((\x.exp (--x)) diffl (-- (exp (--x))))(x)`,
99 STRIP_TAC THEN DIFF_TAC THEN REAL_ARITH_TAC) in
100 let lem2 = SPEC `x:real` EXP_NEG_X_DIFF in
101 let lem3 = SPECL [`SOD f`;`x:real`] POLY_DIFF in
102 let lem4 = CONJ lem2 lem3 in
103 let lem5 = BETA_RULE (MP lem1 lem4) in
104 let lem6 = REAL_ARITH `(a*(b - c)) = (-- a*c) + (b*a)` in
106 `Phi f = \x.((exp (-- x)) * (poly (SOD f) x))`,
107 (PURE_REWRITE_TAC [SYM (ABS `x:real` (SPEC_ALL PHI))])
108 THEN (ACCEPT_TAC (SYM (ETA_CONV `\x.(Phi f x)`))))
110 (REPEAT STRIP_TAC) THEN
111 (REWRITE_TAC [PHI_abs]) THEN
112 (REWRITE_TAC [lem6]) THEN
116 let POLY_SUB = prove(
117 `!p1 p2 x. poly (p1 ++ (neg p2)) x = poly p1 x - poly p2 x`,
118 (REWRITE_TAC [POLY_ADD;poly_neg;POLY_CMUL]) THEN REAL_ARITH_TAC
120 let ZERO_INSERT_NUMSEG = prove(
121 `!n. (0..n) = (0 INSERT (1..n))`,
122 let lem01 = SIMP_RULE [ARITH_RULE `0 <= n`] (SPECL [`0`;`n:num`] NUMSEG_LREC) in
123 let lem02 = SIMP_RULE [ARITH_RULE `0 + 1 = 1`] lem01 in
124 (ACCEPT_TAC (GEN_ALL (GSYM lem02)))
126 let PDI_POLYDIFF_SUC_LEMMA = prove(
127 `!f n .(poly_diff_iter (poly_diff f) n) = poly_diff_iter f (SUC n)`,
128 STRIP_TAC THEN INDUCT_TAC THENL
129 [ (SIMP_TAC [PDI_DEF]);
130 (ONCE_REWRITE_TAC [PDI_DEF]) THEN
131 (ONCE_REWRITE_TAC [PDI_DEF]) THEN
132 (SIMP_TAC [PDI_POLY_DIFF_COMM])
135 let SOD_POLY_DIFF_ITERATE = prove(
136 `!f .(SOD (poly_diff f)) = iterate (++) (1..(LENGTH f)) (\i.poly_diff_iter f i)`,
137 let lemA1 = SPECL [`1`;`0`] NUMSEG_EMPTY in
138 let lemA2 = SIMP_RULE [ARITH_RULE `0 < 1`] lemA1 in
139 let lem1 = MATCH_MP ITERATE_IMAGE_NONZERO MONOIDAL_POLY_ADD in
140 let lem2 = ISPECL [`poly_diff_iter f`;`SUC`;`0..(LENGTH (poly_diff f))`] lem1 in
141 let lem3 = SIMP_RULE [FINITE_NUMSEG] lem2 in
142 let lem4 = ONCE_REWRITE_RULE [ARITH_RULE `~(~(x=y) /\ (SUC x) = (SUC y))`] lem3 in
143 let lem5 = SIMP_RULE [] lem4 in
144 let lem6 = ISPECL [`0`;`n:num`;`1`] NUMSEG_OFFSET_IMAGE in
145 let lem7 = SIMP_RULE [ARITH_RULE `!m.m+1 = SUC m`] lem6 in
146 let lem8 = SIMP_RULE [ARITH_RULE `SUC 0 = 1`] lem7 in
147 let lem9 = ONCE_REWRITE_RULE [ETA_CONV `(\i. SUC i)`] lem8 in
148 let lem10 = ONCE_REWRITE_RULE [GSYM lem9] lem5 in
149 let lem11 = ONCE_REWRITE_RULE [GSYM (ETA_CONV `(\i. poly_diff_iter f i)`)] lem10 in
150 let lem12 = SIMP_RULE [o_DEF] lem11 in
152 `! h t.SUC (LENGTH (poly_diff (CONS h t))) = LENGTH (CONS h t)`,
153 (SIMP_TAC [LENGTH_POLY_DIFF;LENGTH;PRE])
155 (ONCE_REWRITE_TAC [SOD]) THEN (ONCE_REWRITE_TAC [SODN]) THEN
156 (ONCE_REWRITE_TAC [PDI_POLYDIFF_SUC_LEMMA ]) THEN LIST_INDUCT_TAC THENL
157 [ (SIMP_TAC [poly_diff;LENGTH]) THEN
158 (SIMP_TAC [GSYM lemma0;lem12]) THEN
159 (SIMP_TAC [NUMSEG_SING;MONOIDAL_POLY_ADD;ITERATE_SING]) THEN
160 (SIMP_TAC [lemA2;MATCH_MP ITERATE_CLAUSES_GEN MONOIDAL_POLY_ADD]) THEN
161 (ONCE_REWRITE_TAC [POLY_ADD_IDENT]) THEN
162 (SIMP_TAC [PDI_DEF;POLY_DIFF_CLAUSES]);
163 (SIMP_TAC [lem12;GSYM lemma0])
166 let ZERO_ITERATE_POLYADD_LEMMA = prove(
167 `!n f .iterate (++) (0 INSERT (1..n)) f
168 = (f 0) ++ iterate (++) (1..n) f`,
169 let lem0 = prove(`!n. ~(0 IN (1..n))`,
170 STRIP_TAC THEN (ONCE_REWRITE_TAC [IN_NUMSEG]) THEN
172 let lem1 = ISPEC `poly_add` ITERATE_CLAUSES_GEN in
173 let lem2 = SIMP_RULE [MONOIDAL_POLY_ADD] lem1 in
174 let lem3 = CONJUNCT2 lem2 in
175 let lem4 = ISPECL [`f:(num -> (real)list)`;`0`;`1..n`] lem3 in
176 let lem5 = ISPECL [`poly_add`;`f:(num -> (real)list)`;`1..n` ] FINITE_SUPPORT in
177 let lem6 = SIMP_RULE [FINITE_NUMSEG] lem5 in
178 let lem7 = MP lem4 lem6 in
179 let lem9 = SIMP_RULE [lem0] lem7 in
180 (ACCEPT_TAC (GEN_ALL lem9))
182 let SOD_SOD_POLYDIFF = prove(
183 `!f .(SOD f) = f ++ (SOD (poly_diff f))`,
184 (ONCE_REWRITE_TAC [SOD_POLY_DIFF_ITERATE]) THEN (ONCE_REWRITE_TAC [SOD]) THEN
185 (ONCE_REWRITE_TAC [SODN]) THEN
186 (ONCE_REWRITE_TAC [ZERO_INSERT_NUMSEG]) THEN
187 (ONCE_REWRITE_TAC [ZERO_ITERATE_POLYADD_LEMMA]) THEN
188 (BETA_TAC) THEN (SIMP_TAC [PDI_DEF])
190 let SUC_INSERT_NUMSEG = prove(
191 `!n. (0..(SUC n)) = (SUC n) INSERT (0..n)`,
192 let lem01 = SIMP_RULE [ARITH_RULE `0 <= SUC n`]
193 (SPECL [`0`;`n:num`] NUMSEG_REC) in
194 ACCEPT_TAC (GEN_ALL lem01)
196 let SUC_NOT_IN_NUMSEG = prove(
197 `!m n. ~((SUC n) IN (m..n))`,
198 STRIP_TAC THEN (ONCE_REWRITE_TAC [IN_NUMSEG]) THEN ARITH_TAC
200 let SUC_ITERATE_PDI_POLYDIFF_LEMMA = prove(
201 `iterate (++) ((SUC n) INSERT (0..n)) (\i.poly_diff_iter (poly_diff p) i) =
202 (poly_diff_iter (poly_diff p) (SUC n)) ++
203 iterate (++) (0..n) (\i.poly_diff_iter (poly_diff p) i)`,
204 let lem1 = ISPEC `poly_add` ITERATE_CLAUSES_GEN in
205 let lem2 = SIMP_RULE [MONOIDAL_POLY_ADD] lem1 in
206 let lem3 = CONJUNCT2 lem2 in
207 let lem4 = ISPECL [`(\i.poly_diff_iter (poly_diff p) i)`;`SUC n`;`0..n`] lem3 in
208 let lem5 = ISPECL [`poly_add`;`\i.poly_diff_iter (poly_diff p) i`;`0..n` ] FINITE_SUPPORT in
209 let lem6 = SIMP_RULE [FINITE_NUMSEG] lem5 in
210 let lem7 = MP lem4 lem6 in
211 let lem9 = SIMP_RULE [SPEC `0` SUC_NOT_IN_NUMSEG] lem7 in
214 let SODN_POLY_DIFF_COMM = prove(
215 `!n p.(SODN (poly_diff p) n) = poly_diff (SODN p n)`,
216 let lem = MP (ISPEC `poly_add` ITERATE_SING) MONOIDAL_POLY_ADD in
217 let lem1 = ISPEC `poly_add` ITERATE_CLAUSES_GEN in
218 let lem2 = SIMP_RULE [MONOIDAL_POLY_ADD] lem1 in
219 let lem3 = CONJUNCT2 lem2 in
220 let lem10 = SIMP_RULE [GSYM SUC_INSERT_NUMSEG] SUC_ITERATE_PDI_POLYDIFF_LEMMA in
221 let lema00 = ISPECL [`(\i.poly_diff_iter (p) i)`;`SUC n`;`0..n`] lem3 in
222 let lema0 = SIMP_RULE [GSYM SUC_INSERT_NUMSEG] lema00 in
223 let lem15 = ISPECL [`poly_add`;`\i.poly_diff_iter (p) i`;`0..n` ] FINITE_SUPPORT in
224 let lem16 = SIMP_RULE [FINITE_NUMSEG] lem15 in
225 let lema1 = MP lema0 lem16 in
226 let lema2 = SIMP_RULE [SPEC `0` SUC_NOT_IN_NUMSEG] lema1 in
227 let lema3 = ONCE_REWRITE_RULE [GSYM SODN] lema2 in
229 [ (ONCE_REWRITE_TAC [SODN]) THEN
230 (SIMP_TAC [NUMSEG_SING;ITERATE_SING]) THEN
231 (ONCE_REWRITE_TAC [lem]) THEN
233 (SIMP_TAC [PDI_POLY_DIFF_COMM])
235 (ONCE_REWRITE_TAC [SODN]) THEN (ONCE_REWRITE_TAC [lem10]) THEN
236 (ONCE_REWRITE_TAC [GSYM SODN]) THEN (ASM_SIMP_TAC []) THEN
237 (ONCE_REWRITE_TAC [PDI_DEF ]) THEN
238 (ONCE_REWRITE_TAC [PDI_POLY_DIFF_COMM]) THEN
239 (ONCE_REWRITE_TAC [GSYM POLYDIFF_ADD]) THEN
240 STRIP_TAC THEN AP_TERM_TAC THEN
241 (ONCE_REWRITE_TAC [lema3]) THEN (SIMP_TAC [PDI_DEF])
244 let SUC_ITERATE_POLYADD_LEMMA = prove(
245 `!n f .iterate (++) ((SUC n) INSERT (0..n)) f
246 = (f (SUC n)) ++ iterate (++) (0..n) f`,
247 let lem1 = ISPEC `poly_add` ITERATE_CLAUSES_GEN in
248 let lem2 = SIMP_RULE [MONOIDAL_POLY_ADD] lem1 in
249 let lem3 = CONJUNCT2 lem2 in
250 let lem4 = ISPECL [`f:(num -> (real)list)`;`SUC n`;`0..n`] lem3 in
251 let lem5 = ISPECL [`poly_add`;`f:(num -> (real)list)`;`0..n` ] FINITE_SUPPORT in
252 let lem6 = SIMP_RULE [FINITE_NUMSEG] lem5 in
253 let lem7 = MP lem4 lem6 in
254 let lem9 = SIMP_RULE [SPEC `0` SUC_NOT_IN_NUMSEG] lem7 in
255 ACCEPT_TAC (GEN_ALL lem9)
257 let NUMSEG_LENGTH_POLYDIFF_LEMMA = prove(
258 `!f. (0..(LENGTH f)) = ((LENGTH f) INSERT (0..(LENGTH (poly_diff f))))`,
259 (SIMP_TAC [LENGTH_POLY_DIFF]) THEN (LIST_INDUCT_TAC) THENL
260 [ (SIMP_TAC [LENGTH;PRE]) THEN (SIMP_TAC [NUMSEG_CLAUSES]) THEN
261 (SIMP_TAC [INSERT_DEF;NOT_IN_EMPTY;IN]);
262 (SIMP_TAC [LENGTH;PRE]) THEN
263 (SIMP_TAC [ARITH_RULE `0 <= SUC n`;NUMSEG_REC])
266 let POLY_DIFF_LENGTH_LT = prove(
267 `!p. (~(p=[])) ==> (LENGTH (poly_diff p)) < (LENGTH p)`,
268 SIMP_TAC [LENGTH_POLY_DIFF;LENGTH_EQ_NIL;
269 ARITH_RULE `!n.(~(n=0)) ==> (PRE n) < n`]
271 let POLY_DIFF_LENGTH_LE_SUC = prove(
272 `! p n . (LENGTH p <= SUC n) ==> (LENGTH (poly_diff p) <= n)`,
273 (REPEAT STRIP_TAC) THEN (ASM_CASES_TAC `p:(real)list =[]`) THENL
274 [ (ASM_SIMP_TAC [poly_diff;LENGTH]) THEN (ARITH_TAC);
275 (ASM_MESON_TAC [POLY_DIFF_LENGTH_LT;LT_SUC_LE;LTE_TRANS])
278 let PDI_LENGTH_AUX = prove(
279 `! n p. (LENGTH p <= n) ==> poly_diff_iter p n = []`,
281 [ MESON_TAC [PDI_DEF;LENGTH_EQ_NIL;ARITH_RULE `n <= 0 <=> n = 0`];
282 ASM_MESON_TAC [PDI_DEF;PDI_POLY_DIFF_COMM;POLY_DIFF_LENGTH_LE_SUC] ]
284 let PDI_LENGTH_NIL = prove(
285 `! p . poly_diff_iter p (LENGTH p) = []`,
286 SIMP_TAC [PDI_LENGTH_AUX;LE_REFL]
288 let SOD_POLYDIFF_THEOREM = prove(
289 `!f .(SOD (poly_diff f)) = (poly_diff (SOD f))`,
291 `0 INSERT (0..0) = (0..0)`,
292 (SIMP_TAC [NUMSEG_SING]) THEN
293 (SIMP_TAC [INSERT_DEF;NOT_IN_EMPTY;IN])) in
294 let SUC_LENGTH_CONS = prove(
295 `SUC (LENGTH (t:(real)list)) = (LENGTH (CONS h t))`,
296 (SIMP_TAC [LENGTH])) in
297 (ONCE_REWRITE_TAC [SOD]) THEN
298 (ONCE_REWRITE_TAC [SODN_POLY_DIFF_COMM]) THEN
299 (ONCE_REWRITE_TAC [SODN]) THEN
301 (CONV_TAC (RAND_CONV (ONCE_REWRITE_CONV [NUMSEG_LENGTH_POLYDIFF_LEMMA]))) THEN
302 (SPEC_TAC (`f:(real)list`,`f:(real)list`)) THEN
303 (LIST_INDUCT_TAC) THENL
304 [ (SIMP_TAC [poly_diff]) THEN
305 (SIMP_TAC [LENGTH]) THEN
306 (SIMP_TAC [SUM_SING_NUMSEG ]) THEN
309 (SIMP_TAC [LENGTH_POLY_DIFF]) THEN
310 (SIMP_TAC [LENGTH;PRE]) THEN
311 (CONV_TAC (RAND_CONV (ONCE_REWRITE_CONV [SUC_ITERATE_POLYADD_LEMMA]))) THEN
312 (SIMP_TAC [LENGTH;PRE]) THEN
313 (SIMP_TAC [GSYM SODN]) THEN
314 (ONCE_REWRITE_TAC [GSYM SODN]) THEN
315 (ONCE_REWRITE_TAC [SUC_LENGTH_CONS]) THEN
316 (ONCE_REWRITE_TAC [PDI_LENGTH_NIL]) THEN
317 (SIMP_TAC [POLY_ADD_CLAUSES ]);
320 let SOD_SOD_DIFF_LEMMA = prove(
321 `!f x.(poly (SOD f) x) - (poly (poly_diff (SOD f)) x) = poly f x`,
322 MESON_TAC [SOD_SOD_POLYDIFF; POLY_ADD ; POLY_SUB;SOD_POLYDIFF_THEOREM;
323 REAL_ARITH `((x:real) + y) -y = x`]
326 let PLANETMATH_EQN_1_1_2 = prove(
328 ((exp (--x)) * ((poly (poly_diff (SOD f)) x) - (poly (SOD f) x)))
329 = (-- (exp (--x))) * (poly f x)`,
330 let lem17 = prove(`!x y.(x - y) = (-- (y - x))`,REAL_ARITH_TAC) in
331 (REPEAT STRIP_TAC) THEN
332 (ONCE_REWRITE_TAC [lem17]) THEN (ONCE_REWRITE_TAC [SOD_SOD_DIFF_LEMMA])
336 let PLANETMATH_EQN_1_1_3 = prove(
337 `! x f.((Phi f) diffl (-- (exp (--x)) * (poly f x)))(x)`,
338 (ONCE_REWRITE_TAC [GSYM PLANETMATH_EQN_1_1_2]) THEN (ACCEPT_TAC PLANETMATH_EQN_1_1_1)
341 let lem0 = SPECL [`Phi f`;`-- (exp (--x)) * (poly f x)`;`x:real`] DIFF_CONT in
342 GEN_ALL (MP lem0 (SPEC_ALL PLANETMATH_EQN_1_1_3))
344 let PHI_DIFFERENTIABLE = prove(
345 `!f x.(Phi f) differentiable x`,
346 (SIMP_TAC [differentiable]) THEN (REPEAT STRIP_TAC) THEN
347 (EXISTS_TAC `((exp (--x)) * ((poly (poly_diff (SOD f)) x) - (poly (SOD f) x)))`)
348 THEN (SIMP_TAC [PLANETMATH_EQN_1_1_1])
350 let PLANETMATH_EQN_1_2 =
351 (* this one's a bit nasty *)
352 let FO_LEMMA2 = GEN_ALL (prove(
353 `((! l z. (C (l:real) (z:real)) ==> l = (l' z))) ==> ((? (l:real) (z:real) .(A z) /\ (B z) /\ (C l z) /\ (D l) ) ==> (? (z:real).((A z) /\ (B z) /\ (D (l' z)))))`,
354 let lem0 = prove(`(! (l:real) z.(C l (z:real)) ==> l = (l' z)) ==> ((C l z) = ((C l z) /\ l = (l' z)))`, MESON_TAC[]) in
355 let lem1 = UNDISCH lem0 in
356 (STRIP_TAC THEN (ONCE_REWRITE_TAC [lem1]) THEN (MESON_TAC[]))
358 let PROP_LEMMA = TAUT `! a b c d.((a /\ b /\ c) ==> d) = (b ==> c ==> a ==> d)` in
359 let MVT_SPEC = SPECL [`Phi f`;`&0`;`x:real`] MVT in
360 let MVT_SPEC2 = ONCE_REWRITE_RULE [PROP_LEMMA] MVT_SPEC in
361 let MVT_SPEC3 = UNDISCH MVT_SPEC2 in
362 let MVT_SPEC4 = UNDISCH MVT_SPEC3 in
363 let MVT_SPEC5 = UNDISCH MVT_SPEC4 in
364 let lem0 = prove(`! x. x - &0 = x`,REAL_ARITH_TAC) in
365 let MVT_SPEC6 = ONCE_REWRITE_RULE [lem0] MVT_SPEC5 in
366 let DIFF_UNIQ_SPEC1 = SPEC `Phi f` DIFF_UNIQ in
367 let DIFF_UNIQ_SPEC2 = SPEC `l:real` DIFF_UNIQ_SPEC1 in
368 let DIFF_UNIQ_SPEC3 = SPEC ` (-- (exp (--x)) * (poly f x)) ` DIFF_UNIQ_SPEC2 in
369 let DIFF_UNIQ_SPEC4 = SPEC `x:real` DIFF_UNIQ_SPEC3 in
370 let lem8 = SIMP_RULE [PLANETMATH_EQN_1_1_3] DIFF_UNIQ_SPEC4 in
371 let lem9 = GENL [`l:real`;`x:real`] lem8 in
372 let lem10 = SPECL [`\l x.((Phi f diffl l) x)`;`\z.(&0)<z`;`\z.z < (x:real)`;`\l. (Phi f x) - (Phi f (&0)) = x * l`] FO_LEMMA2 in
373 let lem12 = SPEC `\x.(--(exp (--x))) * (poly f x)` lem10 in
374 let lem13 = BETA_RULE lem12 in
375 let lem14 = MP lem13 lem9 in
376 let lem15 = MP lem14 MVT_SPEC6 in
377 let lem70 = SPECL [`f:(real)list`;`x':real`] PHI_DIFFERENTIABLE in
378 let lem71 = ADD_ASSUM `(&0) < x' /\ x' < x` lem70 in
379 let lem72 = GEN `x':real` (DISCH_ALL lem71) in
380 let lem73 = MP (DISCH (concl lem72) lem15) lem72 in
381 let lem80 = SPECL [`f:(real)list`;`x':real`] PHI_CONTL in
382 let lem81 = ADD_ASSUM `(&0) <= x' /\ x' <= x` lem80 in
383 let lem82 = GEN `x':real` (DISCH_ALL lem81) in
384 let lem83 = MP (DISCH (concl lem82) lem73) lem82 in
387 let xi_DEF = new_specification ["xi"]
389 ` (! x f.(P x) ==> ? z. (Q z x f))
390 = (! (x:real) (f:(real)list). ? (z:real). (P x) ==> (Q z x f))`,
392 ((CONV_RULE SKOLEM_CONV)
393 (ONCE_REWRITE_RULE [FO_LEM]
394 (GEN_ALL (DISCH_ALL PLANETMATH_EQN_1_2)))))
396 let PLANETMATH_LEMMA_1 = prove(
398 ==> poly (SOD f) (&0) * exp x =
399 poly (SOD f) x + x * exp (x - xi x f) * poly f (xi x f)`,
400 let lemA = CONJUNCT2 (CONJUNCT2 (UNDISCH (SPEC_ALL xi_DEF))) in
401 let lemB = ONCE_REWRITE_RULE [PHI] lemA in
402 let lemC = ONCE_REWRITE_RULE [REAL_ARITH `((A:real) - B = C) = (B = A - C)`] lemB in
403 let lemD = SIMP_RULE [REAL_NEG_0;REAL_EXP_0;REAL_MUL_LID] lemC in
404 let lem01 = ASSUME `A = ((exp (-- x))*B - (C *( -- (exp (-- y))) * D))` in
405 let lem02 = DISJ2 `exp x = &0` lem01 in
406 let lem03 = REWRITE_RULE [GSYM (SPEC `exp x` REAL_EQ_MUL_LCANCEL)] lem02 in
407 let lem04 = SIMP_RULE [REAL_EXP_NEG_MUL;REAL_EXP_ADD_MUL] lem03 in
408 let lem05 = SIMP_RULE [REAL_SUB_LDISTRIB] lem04 in
409 let lem07 = SIMP_RULE [REAL_MUL_ASSOC;REAL_EXP_NEG_MUL;REAL_MUL_LID] lem05 in
410 let fact00 = REAL_ARITH `(B:real) - ((expx * C) * (--expy)) * D = B + C * (expx * expy) * D` in
411 let lem08 = ONCE_REWRITE_RULE [fact00] lem07 in
412 let lem09 = SIMP_RULE [GSYM REAL_EXP_ADD] lem08 in
413 let lem10 = SIMP_RULE [prove(`(x:real) + -- y = x - y`, REAL_ARITH_TAC)] lem09 in
414 let lem11 = GEN_ALL (DISCH_ALL lem10) in
415 let lem12 = SPECL [`poly (SOD f) (&0)`;
420 `poly f (xi x f)`] lem11 in
421 let lem13 = MP lem12 lemD in
422 let lem14 = SPECL [`exp x`;`poly (SOD f) (&0)`] REAL_MUL_SYM in
423 ACCEPT_TAC (GEN_ALL (DISCH_ALL (ONCE_REWRITE_RULE [lem14] lem13)))
428 module Pm_lemma2 = struct
430 let POLY_MCLAURIN = prove(
432 psum (0, LENGTH p) (\m.poly (poly_diff_iter p m) (&0) / &(FACT m) * x pow m)`,
433 let lem002 = SPECL [`poly p`;`\n.poly (poly_diff_iter p n)`] MCLAURIN_ALL_LE in
434 let lem003 = SIMP_RULE [Pm_lemma1.PDI_DEF;POLY_DIFF] lem002 in
435 let lem004 = REWRITE_RULE [ETA_CONV `(\x.poly l x)`] POLY_DIFF in
436 let lem005 = MATCH_MP lem003 (GEN `m:num` (SPECL [`poly_diff_iter p m`] lem004)) in
437 let lem007 = SPECL [`x:real`;`LENGTH (p:(real)list)`] lem005 in
438 let lem008 = ONCE_REWRITE_RULE [Pm_lemma1.PDI_LENGTH_NIL] lem007 in
439 let lem009 = ONCE_REWRITE_RULE [poly] lem008 in
440 let lem010 = SIMP_RULE [REAL_ARITH `!x. ((&0)/x) = &0`] lem009 in
441 let lem011 = SIMP_RULE [REAL_MUL_LZERO;REAL_ADD_RID] lem010 in
442 let lem012 = prove(`(? t . (A t) /\ B) ==> B`, MESON_TAC []) in
443 ACCEPT_TAC (GEN_ALL (MATCH_MP lem012 lem011))
445 let DIFF_ADD_CONST_COMMUTE = prove(
446 `!f a l x . (f diffl l) (x + a) ==> ((\x. f (x + a)) diffl l) x`,
447 let lem01 = CONJ (SPEC_ALL DIFF_X) (SPECL [`a:real`;`x:real`] DIFF_CONST) in
448 let lem02 = BETA_RULE (MATCH_MP DIFF_ADD lem01) in
449 let lem03 = ONCE_REWRITE_RULE [REAL_ARITH `&1 + &0 = &1`] lem02 in
450 let lem04 = SPECL [`f:real->real`;`\(x:real).((x + a)):real`;`l:real`;`&1`] DIFF_CHAIN in
451 let MUL_ONE = REAL_ARITH `! x.(&1) * x = x /\ x * (&1) = x` in
452 let lem05 = ONCE_REWRITE_RULE [MUL_ONE] (BETA_RULE lem04) in
453 let lem06 = GEN_ALL (SIMP_RULE [lem03] lem05) in
456 let POLY_DIFF_ADD_CONST_COMMUTE = prove(
457 `! p1 p2 a.(!x.(poly p2 x) = (poly p1 (x-a)))
458 ==> (!x . ((poly (poly_diff p2) x) = (poly (poly_diff p1) (x-a))))`,
460 [`\x.poly p1 x`;`-- a:real`;`l:real`;`x:real`]
461 DIFF_ADD_CONST_COMMUTE in
462 let lem02 = ONCE_REWRITE_RULE [REAL_ARITH `w + --v = w - v`] (BETA_RULE lem01) in
463 let lem03 = SPECL [`p1:(real)list`;`(x:real) -a`] POLY_DIFF in
464 let lem04 = MATCH_MP lem02 lem03 in
465 let lem05 = ASSUME `!x.poly p2 x = poly p1 (x - a)` in
466 let lem06 = ONCE_REWRITE_RULE [GSYM lem05] lem04 in
467 let lem07 = SPECL [`p2:(real)list`;`x:real`] POLY_DIFF in
468 let lem08 = MATCH_MP DIFF_UNIQ (CONJ lem07 lem06) in
469 (REPEAT STRIP_TAC) THEN (ACCEPT_TAC lem08)
472 let HARD_WON = prove(
473 `! p1 p2 a n.(!x.(poly p2 x) = (poly p1 (x-a)))
474 ==> ((\x.poly (poly_diff_iter p2 n) x) = (\x.(poly (poly_diff_iter p1 n) (x - a)))) `,
475 let lem = SPECL [`poly_diff_iter p1 n`;`poly_diff_iter p2 n`;`a:real`] POLY_DIFF_ADD_CONST_COMMUTE in
476 let tm = `(!x . poly p2 x = poly p1 (x -a )) ==>
477 (\x.poly (poly_diff_iter p2 n) x) = (\x. poly (poly_diff_iter p1 n) (x - a))` in
478 (STRIP_TAC THEN STRIP_TAC THEN STRIP_TAC ) THEN
480 [ SIMP_TAC [Pm_lemma1.PDI_DEF] ;
481 STRIP_TAC THEN (ONCE_REWRITE_TAC [Pm_lemma1.PDI_DEF]) THEN (UNDISCH_TAC tm) THEN
482 (ASM_REWRITE_TAC[FUN_EQ_THM]) THEN (ACCEPT_TAC lem)
485 (* if f:real->real is a function, let us call the function g x = f (x+a),
486 * where a is a constant, a "shifting" of f by a. if f is defined by a poly,
487 * i.e. a (real)list, then (poly_shift f a) is the (real)list defining
488 * the shifting of f by a.
490 let POLY_SHIFT_DEF = new_recursive_definition list_RECURSION
491 ` (poly_shift [] a = [])
492 /\ (poly_shift (CONS c t) a =
493 (CONS c (poly_shift t a)) ++ (a ## (poly_shift t a)))`
495 (* POLY_SHIFT simply says that poly_shift does what is supposed to do
497 let POLY_SHIFT = prove(
498 `! p a x .(poly p (x + a)) = (poly (poly_shift p a) x)`,
499 let lem01 = ASSUME `! a x . poly t (x + a) = poly (poly_shift t a ) x` in
500 LIST_INDUCT_TAC THENL
502 (ONCE_REWRITE_TAC [POLY_SHIFT_DEF;poly]) THEN (SIMP_TAC [poly]);
503 (REPEAT STRIP_TAC) THEN (ONCE_REWRITE_TAC [POLY_SHIFT_DEF]) THEN
504 (ONCE_REWRITE_TAC [POLY_ADD]) THEN (ONCE_REWRITE_TAC [POLY_CMUL]) THEN
505 (ONCE_REWRITE_TAC [poly;GSYM lem01]) THEN
506 (ONCE_REWRITE_TAC [GSYM lem01]) THEN (REAL_ARITH_TAC)
509 let POLY_SHIFT_LENGTH = prove(
510 `! p a . (LENGTH (poly_shift p a)) = (LENGTH p)`,
512 (LIST_INDUCT_TAC) THENL
513 [ (SIMP_TAC [POLY_SHIFT_DEF]);
514 (SIMP_TAC [POLY_SHIFT_DEF]) THEN
516 [LENGTH;POLY_CMUL_LENGTH;POLY_ADD_LENGTH;
517 ARITH_RULE `MAX (x:num) y = if (x > y) then x else y`;
518 ARITH_RULE `! n. SUC n >n`])
521 let POLY_TAYLOR = prove(
523 psum (0,LENGTH p) (\m.poly (poly_diff_iter p m) a/ &(FACT m) * (x - a) pow m)`,
524 let lem01 = SPEC `poly_shift p a` POLY_MCLAURIN in
525 let lem02 = SPECL [`p:(real)list`;`poly_shift p a`;`-- a:real`;`n:num`] HARD_WON in
526 let lem03 = GSYM ( SPECL [`p:(real)list`;`a:real`] POLY_SHIFT) in
527 let lem04 = SIMP_RULE [REAL_ARITH `a - --b = a + b`] lem02 in
528 let lem05 = ONCE_REWRITE_RULE [ETA_AX] (MP lem04 lem03) in
529 let lem06 = BETA_RULE (ONCE_REWRITE_RULE [lem05] lem01) in
530 let lem07 = ONCE_REWRITE_RULE [REAL_ARITH `&0 + a = a`] lem06 in
531 let lem08 = ONCE_REWRITE_RULE [GSYM POLY_SHIFT] lem07 in
532 let lem09 = ONCE_REWRITE_RULE [POLY_SHIFT_LENGTH] lem08 in
533 let lem10 = RATOR_CONV (ONCE_REWRITE_CONV [REAL_ARITH `(x:real) = (x + a) - a`]) `x pow m` in
534 let lem11 = ONCE_REWRITE_RULE [lem10] lem09 in
535 let lem12 = SPEC `(x - a):real` lem11 in
536 let lem13 = ONCE_REWRITE_RULE [REAL_ARITH `(x:real) - a + a = x`] lem12 in
537 ACCEPT_TAC (GEN_ALL lem13 )
539 let PLANETMATH_LEMMA_2_A = prove(
540 `! p a x . poly p x =
541 ((\s .psum (0,LENGTH p) ((\m.poly (poly_diff_iter p m) a/ &(FACT m) * (s m))))
542 (\m.(x - a) pow m))`,
543 BETA_TAC THEN (MATCH_ACCEPT_TAC POLY_TAYLOR)
545 let ITERATE_SUC_REC = prove(
546 `!(op:D -> D -> D) m n (f:num -> D) .
549 iterate op (m..(SUC n)) f
550 = op (f (SUC n)) (iterate op (m..n) f)`,
551 let lem0 = UNDISCH_ALL (SPEC_ALL (GSYM NUMSEG_REC)) in
552 let lem1 = ISPEC `op:D -> D -> D` ITERATE_CLAUSES_GEN in
553 let lem2 = CONJUNCT2 (UNDISCH lem1) in
554 let lem3 = ISPECL [`f:(num -> D)`;`SUC n`;`m..n`] lem2 in
555 let lem4 = SIMP_RULE [] (DISCH_ALL lem3) in
557 `!m n. ~((SUC n) IN (m..n))`,
558 STRIP_TAC THEN (ONCE_REWRITE_TAC [IN_NUMSEG]) THEN ARITH_TAC) in
559 let lem5 = SIMP_RULE [lem50;FINITE_SUPPORT;FINITE_NUMSEG] lem4 in
560 let lem6 = ADD_ASSUM `m <= SUC n` lem5 in
561 let lem7 = ONCE_REWRITE_RULE [lem0] lem6 in
564 let ITERATE_POLY_ADD_PRE_REC = prove(
566 ==> iterate (++) (0..n) f = (f n) ++ (iterate (++) (0..n-1) f)`,
567 MESON_TAC [ITERATE_CLAUSES_NUMSEG; MONOIDAL_POLY_ADD; POLY_ADD_SYM;
568 ARITH_RULE `0 <= x`; ARITH_RULE `n > 0 ==> n = SUC (n - 1)`]
570 let PSUM_ITERATE = prove(
571 `! n m f. psum (m,n) f
572 = if (n > 0) then (iterate (+) (m..((n+m)-1)) f) else &0`,
573 let lem01 = ARITH_RULE `~(n+m=0) ==> (SUC n + m) -1 = SUC ((n + m) -1)` in
574 let lem02 = MP (ISPEC `(+)` ITERATE_SING) MONOIDAL_REAL_ADD in
576 `iterate (+) (m..SUC ((n + m) - 1)) f
577 = f (SUC ((n+m)-1)) + iterate (+) (m..(n+m)-1) f`,
578 MESON_TAC [ARITH_RULE `m <= SUC ((n+m)-1)`;ITERATE_CLAUSES_NUMSEG;
579 MONOIDAL_REAL_ADD;REAL_ADD_SYM]) in
580 let lem04 = UNDISCH (UNDISCH (ARITH_RULE `~(n+m=0) ==> n=0 ==> m-1 < m`)) in
581 let lem05 = SIMP_RULE [lem04] (SPECL [`m:num`;`m-1`] NUMSEG_EMPTY) in
583 [ SIMP_TAC [ARITH_RULE `~(0 > 0)`;sum_DEF];
584 (SIMP_TAC [ARITH_RULE `(SUC n) > 0`]) THEN (REPEAT STRIP_TAC) THEN
585 (ASM_CASES_TAC `n + m =0`) THENL
586 [ (REWRITE_TAC [UNDISCH (ARITH_RULE `n + m = 0 ==> n = 0`)]) THEN
587 (REWRITE_TAC [lem02;NUMSEG_SING;ARITH_RULE `(SUC 0 +m) -1 = m`]) THEN
588 (MESON_TAC [sum_DEF; ADD_CLAUSES;REAL_ARITH `&0 + x = x`]) ;
589 (ONCE_REWRITE_TAC [sum_DEF;UNDISCH lem01]) THEN
590 (REWRITE_TAC [lem03]) THEN (ASM_CASES_TAC `n = 0`) THEN
592 [ARITH_RULE `~(0 > 0)`;ADD_CLAUSES;REAL_ADD_LID;REAL_ADD_RID;
593 lem05;ITERATE_CLAUSES_GEN; MONOIDAL_REAL_ADD;NEUTRAL_REAL_ADD;
594 REAL_ADD_SYM;ADD_SYM;ARITH_RULE `~(n=0) ==> n>0 /\ SUC (n-1) = n`])
598 let FACT_DIV_RCANCELS = prove(
599 `!n x. x / &(FACT n) * &(FACT n) = x`,
600 MESON_TAC [REAL_ARITH `!x. &0 < x ==> ~(x = &0)`;
601 REAL_DIV_RMUL;FACT_LT;REAL_OF_NUM_LT]
603 let PLANETMATH_LEMMA_2_B = prove(
604 `! p (x:real) a . poly (SOD p) a =
605 ((\s .psum (0,LENGTH p) ((\m.poly (poly_diff_iter p m) a/ &(FACT m) * (s m))))
607 let lem6 = ISPECL [`(\i.poly_diff_iter p i)`;`LENGTH (p:(real)list)`]
608 ITERATE_POLY_ADD_PRE_REC in
609 let lem7 = UNDISCH lem6 in
610 let lem8 = UNDISCH (ARITH_RULE `~(LENGTH (p:(real)list) > 0) ==> (LENGTH p = 0)`) in
611 let lem9 = ONCE_REWRITE_RULE [LENGTH_EQ_NIL] lem8 in
612 BETA_TAC THEN (REPEAT STRIP_TAC) THEN (ONCE_REWRITE_TAC [FACT_DIV_RCANCELS]) THEN
613 (ONCE_REWRITE_TAC [PSUM_ITERATE]) THEN (ASM_CASES_TAC `LENGTH (p:(real)list) > 0`) THENL
614 [ (ASM_SIMP_TAC [Pm_lemma1.SOD;Pm_lemma1.SODN;ITERATE_RADD_POLYADD;ARITH_RULE `x + 0 = x`]) THEN
615 (AP_THM_TAC) THEN (AP_TERM_TAC) THEN (SIMP_TAC [lem7;Pm_lemma1.PDI_LENGTH_NIL;POLY_ADD_CLAUSES]);
616 (ASM_SIMP_TAC []) THEN
618 [lem9;poly;Pm_lemma1.SOD;Pm_lemma1.SODN;NUMSEG_SING;MONOIDAL_POLY_ADD;ITERATE_SING;LENGTH;Pm_lemma1.PDI_DEF])
624 module Pm_eqn4 = struct
626 let N_IS_INT = prove(
630 let NEG_N_IS_INT = prove(
631 `!n . integer (--(&n))`,
634 let PLANETMATH_EQN_3 = prove(
636 ==> poly (SOD f) (&0) * exp (&nu) =
638 &nu * exp (&nu - xi (&nu) f) * poly f (xi (&nu) f)`,
639 let RW = SPECL [`0`;`nu:num`] REAL_OF_NUM_LT in
640 ACCEPT_TAC (ONCE_REWRITE_RULE [RW] (SPEC `(&nu):real` Pm_lemma1.PLANETMATH_LEMMA_1))
642 (* the RHS of PLANETMATH_EQN_4
643 * TBD: mentioned in paper
645 let LHS = new_definition
646 `LHS c f = sum (0..(PRE (LENGTH c))) (\i.(EL i c)*(poly (SOD f) (&i)))`
648 (* the LHS of PLANETMATH_EQN_4
649 * TBD: mentioned in paper
651 let RHS = new_definition
652 `RHS c f = -- sum (1..(PRE (LENGTH c)) )
655 * (exp ((&i) - (xi (&i) f)))
656 * (poly f (xi (&i) f))
660 `!n.(exp (real_of_num 1)) pow n = exp(&n)`,
661 SIMP_TAC [GSYM REAL_EXP_N;REAL_MUL_RID])
664 (* The proof was originally done with a slightly different transcendental
665 * predicate than found in Harrison's 100/liouville.ml it turns out the difference
666 * is that &0 satisfies my transcendental! Thankfully, it is easy to show that
667 * e != 0, and hence the two notions of transcendence are equivalent for e.
668 * So that I could eliminate even brining my muddled definition of
669 * transcendental into the proof, this file ultimately proves
670 * E_TRANSCENDENTAL_EQUIV, which allows the main proof to only mention
671 * Harrison's transcendental predicate.
674 let NO_CONST_TERM_POLY_ROOT = prove(
675 `!p . (~(x = &0) /\ ((HD p) = &0) /\ (poly p x = &0) /\ ~(p = []))
676 ==> ((poly (TL p) x) = &0)`,
678 (ASM_SIMP_TAC [HD;TL;NOT_CONS_NIL;poly]) THEN
679 (MESON_TAC [REAL_ARITH `((&0):real) + x = x`;REAL_ENTIRE])
682 let NEGATED_POLY_ROOT = prove(
683 `!p . (poly p x = &0) ==> (poly ((-- &1) ## p) x = &0)`,
684 MESON_TAC [POLY_CMUL;REAL_ARITH `(-- &1) * ((&0):real) = &0`]
687 (* changes a polynomial p to p/x^k, where k is the lowest power
688 * of x where p has a non-zero coefficient. This amounts to
689 * just stripping off all leading zeros from the head of the list p.
691 let POLY_NUKE = new_recursive_definition list_RECURSION
693 /\ (poly_nuk (CONS (c:real) t) =
694 (if (c = &0) then (poly_nuk t) else (CONS c t)))`
696 let POLY_NUKE_ROOT = prove(
697 `!p . ((~(x = &0)) /\ (poly p x = &0)) ==> (poly (poly_nuk p) x = &0)`,
698 LIST_INDUCT_TAC THENL
699 [ SIMP_TAC[POLY_NUKE];
700 (ASM_CASES_TAC `(h:real) = &0`) THEN
701 (ASM_MESON_TAC [HD;TL;POLY_NUKE;NOT_CONS_NIL;NO_CONST_TERM_POLY_ROOT])
704 let POLY_NUKE_ZERO = prove(
705 `!p . (poly p = poly []) <=> (poly (poly_nuk p) = poly [])`,
706 LIST_INDUCT_TAC THEN (ASM_MESON_TAC [POLY_ZERO;ALL;POLY_NUKE])
708 let POLY_CONST_NO_ROOTS = prove(
709 `! c. ~(poly [c] = poly []) ==> ~(poly [c] x = &0)`,
710 (MESON_TAC [poly;REAL_ENTIRE;POLY_ZERO;ALL;
711 REAL_ARITH `(x:real) + &0 = x`;
712 REAL_ARITH `(x:real) * &0 = &0`])
714 let LENGTH_1 = prove(
715 `! lst . (LENGTH lst = 1) <=> (? x. lst = [x])`,
717 (MESON_TAC [LENGTH;ARITH_RULE `SUC x = 1 <=> x = 0`;NOT_CONS_NIL;LENGTH_EQ_NIL])
719 let SOUP_LEMMA = prove(
720 `!p . ~(x = &0) /\ ~(poly p = poly []) /\ (poly p x = &0)
721 ==> LENGTH (poly_nuk p) > 1`,
722 let l0 = ARITH_RULE `(~(n = 0) /\ ~(n = 1)) <=> n > 1` in
723 let l1 = UNDISCH (UNDISCH (BRW1 (SPEC_ALL POLY_NUKE_ROOT))) in
724 (ONCE_REWRITE_TAC [GSYM l0]) THEN (REPEAT STRIP_TAC) THENL
725 [ (ASM_MESON_TAC [LENGTH;LENGTH_EQ_NIL;POLY_NUKE_ZERO]);
726 (ASM_MESON_TAC [l1;POLY_CONST_NO_ROOTS;LENGTH_1;LENGTH;POLY_NUKE_ZERO]) ]
729 let POLY_NUKE_HD_NONZERO = prove(
730 `!p . ~(poly p = poly []) ==> ~((HD (poly_nuk p)) = &0)`,
731 LIST_INDUCT_TAC THEN (ASM_CASES_TAC `(h:real) = &0`) THEN
732 (ASM_SIMP_TAC [HD;POLY_ZERO;ALL;POLY_NUKE])
735 let IS_INT_POLY_NUKE = prove(
736 `!p . (ALL integer p) ==> (ALL integer (poly_nuk p))`,
737 LIST_INDUCT_TAC THEN (ASM_MESON_TAC [ALL;POLY_NUKE;N_IS_INT])
740 let POLY_X_NOT_POLY_NIL = prove(
741 `~(poly [&0;&1] = poly [])`,
742 (SIMP_TAC [FUN_EQ_THM;POLY_X;poly;prove(`(~ ! x .P x) <=> (? x. ~ P x)`,MESON_TAC[])] )
743 THEN (EXISTS_TAC `real_of_num 1`) THEN (REAL_ARITH_TAC)
746 let NOT_TRANSCENDENTAL_ZERO = prove(
747 `~ (transcendental (&0))`,
748 (REWRITE_TAC [transcendental;algebraic]) THEN
749 (EXISTS_TAC `[&0 ; &1]:(real)list`) THEN
750 (MESON_TAC [POLY_X;POLY_X_NOT_POLY_NIL;ALL;N_IS_INT])
753 let ALL_IS_INT_POLY_CMUL = prove(
754 `! p c. (integer c) /\ (ALL integer p) ==> (ALL integer (c ## p))`,
755 (LIST_INDUCT_TAC) THEN (ASM_SIMP_TAC [poly_cmul;ALL;INTEGER_MUL])
759 * Harrison's transcendental predicate from 100/liouville.ml is equivalent
760 * to my predicate conjoined with x != 0.
762 let TRANSCENDENTAL_MY_TRANSCENDENTAL = prove(
763 `!x. transcendental x <=>
765 ~ ? c. (ALL integer c)
769 let contra_pos = TAUT `(~X ==> ~Y /\ ~Z) <=> ((Y \/ Z) ==> X)` in
770 let contra_pos2 = TAUT `((~X /\ ~Y) ==> ~Z) <=> (Z ==> ~X ==> Y)` in
771 let l0 = prove(`!c . LENGTH c > 1 ==> HD c > &0 ==> ~(poly c = poly [])`,
773 (ASM_MESON_TAC [LENGTH_EQ_NIL;ARITH_RULE `n > 1 ==> ~(n = 0)`;
774 REAL_ARITH `(x:real) > &0 ==> ~(x = &0)`;
775 HD;ALL;POLY_ZERO])) in
776 let witness = `if ((&0) <= (HD (poly_nuk p)))
778 else ((-- &1) ## (poly_nuk p))` in
779 let l2 = REAL_ARITH `!(x:real). (&0 <= x) /\ ~(x = &0) ==> x > &0` in
780 let l3 = prove( `! c p. LENGTH (c ## p) = LENGTH p`,
781 STRIP_TAC THEN LIST_INDUCT_TAC THEN
782 (ASM_SIMP_TAC [poly_cmul;LENGTH])) in
783 let POLY_CMUL_HD = prove(
784 `! x p . (~(p = [])) ==> HD (x ## p) = x * (HD p)`,
785 STRIP_TAC THEN LIST_INDUCT_TAC THEN (SIMP_TAC [NOT_CONS_NIL;poly_cmul;HD])
787 (REWRITE_TAC [transcendental;algebraic]) THEN
788 (STRIP_TAC THEN EQ_TAC) THENL
789 [ (ONCE_REWRITE_TAC [contra_pos]) THEN STRIP_TAC THENL
790 [ASM_MESON_TAC [transcendental;algebraic; NOT_TRANSCENDENTAL_ZERO];
791 (EXISTS_TAC `c:(real)list`) THEN
792 (ASM_MESON_TAC [l0; NOT_TRANSCENDENTAL_ZERO ])];
793 (REWRITE_TAC [contra_pos2]) THEN
794 (STRIP_TAC THEN STRIP_TAC) THEN (ASM_SIMP_TAC [IS_INT_POLY_NUKE]) THEN
795 (EXISTS_TAC witness) THEN
796 (ASM_CASES_TAC `((&0) <= (HD (poly_nuk p)))`) THEN
797 (ASM_MESON_TAC [ IS_INT_POLY_NUKE;ALL_IS_INT_POLY_CMUL;NEG_N_IS_INT;
798 l2;POLY_NUKE_HD_NONZERO;NEGATED_POLY_ROOT;SOUP_LEMMA;
799 l3;POLY_NUKE_ROOT;POLY_NUKE_ZERO;POLY_CMUL_HD;
800 REAL_ARITH `~(&0 <= (x:real)) <=> ((-- &1) * x) > &0`])
804 let E_TRANSCENDENTAL_EQUIV = prove(
805 `(transcendental (exp (&1))) <=>
806 (~ ? c. (ALL integer c)
808 /\ ((poly c (exp (&1))) = &0)
810 MESON_TAC[TRANSCENDENTAL_MY_TRANSCENDENTAL;
811 REAL_EXP_POS_LT; REAL_ARITH `&0 < (x:real) ==> ~(&0 = x)`]
814 (* TBD mentionedin paper *)
815 let PLANETMATH_EQN_4 = prove(
816 `(~ (transcendental (exp (&1)))) ==> ? c .
817 ((ALL integer c) /\ ((LENGTH c) > 1) /\ ((EL 0 c) > &0) /\ (! f .((LHS c f) = (RHS c f))))`,
818 let foo2 = prove( `(HD c) > (real_of_num 0) ==> EL 0 c > &0`,SIMP_TAC [EL]) in
819 let lem01 = SPECL [`f:num->real`;`0`;`0`;`PRE (LENGTH (c:(real)list))`] SUM_COMBINE_R in
820 let lem02 = ARITH_RULE `(0 <= 0 + 1 /\ 0 <= (PRE (LENGTH (c:(real)list))))` in
821 let lem03 = GSYM (MP lem01 (lem02) ) in
822 let lem06 = ISPECL [`f1:num->real`;
824 `1`;`(PRE (LENGTH (c:(real)list)))`] SUM_ADD in
825 let new0 = SPECL [`f:num->real`;`1`;`PRE (LENGTH (c:(real)list))`] PSUM_SUM_NUMSEG in
826 let new1 = SIMP_RULE [ARITH_RULE `~(1 = 0)`;ARITH_RULE `(1 + x) -1 = x`] new0 in
827 let new2 = ONCE_REWRITE_RULE [new1] lem06 in
828 let lem001 = REAL_ARITH `((A:real) * B * C * D + B * E) = (B * (A * C * D + E))` in
829 let lem0 = REAL_ARITH `(x:real) = x * (&1) - (&0) * y` in
830 let lem1 = GEN_ALL (ONCE_REWRITE_RULE [GSYM REAL_EXP_0] lem0) in
831 let lem2 = SPECL [`poly (SOD f) (&0)`;
832 ` exp (&0 - xi (&0) f) * poly f (xi (&0) f)`] lem1 in
833 let PLANETMATH_EQN_3_TWEAKED =
835 [REAL_ARITH `((A:real) = B+C) <=> (B = A -C)`]
838 let lem21 = GEN `nu:num` (SPEC_ALL PLANETMATH_EQN_3_TWEAKED) in
839 let lem3 = CONJ lem21 lem2 in
840 let NUM_CASES_LEMMA = prove(
841 ` !P .((! n .(0 < n) ==> (P n)) /\ (P 0) ==> ! n . P n)`,
842 (REPEAT STRIP_TAC) THEN (SPEC_TAC (`n:num`,`n:num`)) THEN
843 INDUCT_TAC THEN (ASM_SIMP_TAC[]) THEN
844 (ASM_SIMP_TAC [ARITH_RULE `0 < (SUC n)`])) in
845 let lem4 = SPEC `(\nu.poly (SOD f) (&nu) = poly (SOD f) (&0) * exp (&nu) - &nu * (exp ((&nu) - xi (&nu) f)) * poly f (xi (&nu) f))` NUM_CASES_LEMMA in
846 let lem5 = BETA_RULE lem4 in
847 let lem6 = MP lem5 lem3 in
850 [ARITH_RULE `!n.0 <= n`;ARITH_RULE `(0:num) + 1 = 1`]
851 (ISPECL [`f:num->real`;`0`;`0`;`PRE (LENGTH (c:(real)list))`] SUM_COMBINE_R) in
852 let lem0001 = ASSUME `LENGTH (c:(real)list) > 1` in
853 let lem0002 = MATCH_MP (ARITH_RULE `(x:num) > 1 ==> ~(x=0)`) lem0001 in
854 let lem0003 = REWRITE_RULE [LENGTH_EQ_NIL] lem0002 in
855 let lem0004 = MATCH_MP POLY_SUM_EQUIV lem0003 in
856 let SUM_LMUL_NUMSEG = GEN_ALL (ISPECL [`f:num->real`;`c:real`;`n..m`] SUM_LMUL) in
857 (ONCE_REWRITE_TAC [E_TRANSCENDENTAL_EQUIV]) THEN
858 (ONCE_REWRITE_TAC [LHS;RHS]) THEN
859 (REPEAT STRIP_TAC) THEN
860 (EXISTS_TAC `c:(real)list`) THEN
861 (ONCE_REWRITE_TAC [GSYM REAL_RNEG_UNIQ]) THEN
862 (ONCE_REWRITE_TAC [lem03]) THEN
863 (ONCE_REWRITE_TAC [NUMSEG_CONV `0..0`]) THEN
864 (ONCE_REWRITE_TAC [SUM_SING] ) THEN
865 (ASM_SIMP_TAC[foo2]) THEN
867 (ONCE_REWRITE_TAC [ARITH_RULE `0 + 1 = 1`] ) THEN
868 (ONCE_REWRITE_TAC [REAL_ARITH `(A:real) + B + C = (A + C) + B`] ) THEN
869 (ONCE_REWRITE_TAC [GSYM new2]) THEN
871 (ONCE_REWRITE_TAC [lem001]) THEN
872 (CONV_TAC ((RAND_CONV o ABS_CONV o RATOR_CONV o RAND_CONV o RATOR_CONV) (PURE_ONCE_REWRITE_CONV [lem6]))) THEN
873 (ONCE_REWRITE_TAC [REAL_ARITH `(A:real) + B - A = B`]) THEN
874 (ONCE_REWRITE_TAC [REAL_ARITH `(EL 0 c) * (poly (SOD f) (&0)) = (EL 0 c) * (poly (SOD f) (&0)) * (&1)`]) THEN
875 (ONCE_REWRITE_TAC [GSYM REAL_EXP_0]) THEN
876 (ONCE_REWRITE_TAC [GSYM (BETA_CONV `(\x.(EL x c) * (poly (SOD f) (&0)) * exp (&x)) (0)`)]) THEN
877 (ONCE_REWRITE_TAC [GSYM (ISPEC `\x.(EL x c) * (poly (SOD f) (&0)) * exp (&x)` SUM_SING)]) THEN
878 (ONCE_REWRITE_TAC [GSYM (NUMSEG_CONV `0..0`)]) THEN
879 (ONCE_REWRITE_TAC [REAL_ADD_AC]) THEN
880 (ONCE_REWRITE_TAC [lem100]) THEN
881 (ONCE_REWRITE_TAC [REAL_ARITH `(A:real) * B * C = B * A * C`]) THEN
882 (ONCE_REWRITE_TAC [ SUM_LMUL_NUMSEG ]) THEN
883 (ONCE_REWRITE_TAC [GSYM E_POW_N]) THEN
884 (ONCE_REWRITE_TAC [GSYM lem0004]) THEN
885 (ASM_SIMP_TAC[]) THEN
891 module Pm_eqn5 = struct
893 let POLY_MUL_ITER = new_recursive_definition num_RECURSION
894 `(poly_mul_iter f 0 = [&1]) /\
895 (!n . poly_mul_iter f (SUC n) = (f (SUC n)) ** (poly_mul_iter f n))`
897 let PLANETMATH_EQN_5 =
899 `g n p = (&1/(&(FACT (p -1)))) ##
900 ((poly_exp [&0;&1] (p-1)) **
901 (poly_exp (poly_mul_iter (\i.[-- &i; &1]) n) p))`
907 module Pm_eqn4_rhs = struct
909 let ABS_LE_MUL2 = prove(
910 `!(w:real) x y z. abs(w) <= y /\ abs(x) <= z ==> abs(w * x) <= (y * z)`,
911 REPEAT GEN_TAC THEN DISCH_TAC THEN
912 REWRITE_TAC[ABS_MUL] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
913 ASM_REWRITE_TAC[ABS_POS])
915 let SEPTEMBER_2009_LEMMA = prove(
917 (!i.(0 <= i /\ i <= n) ==> (abs (poly (f i) x)) <= &(n')) ==>
918 (abs (poly (poly_mul_iter f n) x)) <= (&(n') pow n)`,
919 let lem0 = ASSUME `!i. 0 <= i /\ i <= SUC n ==> abs (poly (f i) x) <= &n'` in
920 let lem1 = SPEC `SUC n` lem0 in
921 let lem2 = SIMP_RULE [ARITH_RULE `0 <= SUC n /\ SUC n <= SUC n`] lem1 in
922 let lem3 = prove(`(!i:num.(P0 i) ==> (P1 i)) ==> (!i:num.((P1 i) ==> (Q i))) ==> (!i:num.((P0 i) ==> (Q i)))`, MESON_TAC[]) in
923 let lem4 = ARITH_RULE `!i.(0 <= i /\ i <= n) ==> (0 <= i /\ i <= SUC n)` in
924 let lem5 = GEN `Q:num->bool` (MATCH_MP lem3 lem4) in
925 let lem6 = ASSUME `!n'. (!i. 0 <= i /\ i <= n ==> abs (poly (f i) x) <= &n') ==> abs (poly (poly_mul_iter f n) x) <= &n' pow n` in
926 let lem7 = SPEC `n':num` lem6 in
927 let lem9 = UNDISCH (BETA_RULE (SPEC `\i. abs (poly (f (i:num)) x) <= &n'` lem5)) in
928 let lem11 = MP (lem7) (lem9) in
929 STRIP_TAC THEN STRIP_TAC THEN INDUCT_TAC THENL
930 [ (REWRITE_TAC ([Pm_eqn5.POLY_MUL_ITER;poly;real_pow]@rewrites0))
931 THEN (REAL_ARITH_TAC);
932 (STRIP_TAC) THEN (STRIP_TAC) THEN
933 (REWRITE_TAC [Pm_eqn5.POLY_MUL_ITER;POLY_MUL;real_pow]) THEN
934 (MATCH_MP_TAC ABS_LE_MUL2) THEN
935 (SIMP_TAC [lem2;lem11])
938 let SEPTEMBER_2009_LEMMA_2 = prove(
940 ==> (!i. 0 <= i /\ i <= n ==> abs(poly [-- &i; &1] x) <= &n)`,
941 (REWRITE_TAC [GSYM REAL_LE]) THEN (REPEAT STRIP_TAC) THEN
942 (REWRITE_TAC ([poly]@rewrites0)) THEN
943 (REWRITE_TAC [REAL_ARITH `&0 <= -- &i + (x:real) <=> &i <= x`;real_abs]) THEN (ASM_CASES_TAC `&i <= (x:real)`) THENL
944 [ (ASM_SIMP_TAC []) THEN
945 (REWRITE_TAC [REAL_ARITH `-- &i + (x:real) = x - &i `]) THEN
946 (ASM_REAL_ARITH_TAC);
947 (ASM_SIMP_TAC []) THEN
948 (REWRITE_TAC [REAL_ARITH `--(-- &i + (x:real)) = &i - x `]) THEN
953 let FACT_DIV_LCANCELS = prove(
954 `!n x. &(FACT n) * x / &(FACT n) = x`,
955 let lem0 = SPECL [`0`;`FACT n`] REAL_OF_NUM_LT in
956 let lem1 = ONCE_REWRITE_RULE [GSYM lem0] FACT_LT in
957 let lem2 = SPECL [`x:real`;`(&(FACT n)):real`] REAL_DIV_LMUL in
958 let lem3 = REAL_ARITH `!x:real. &0 < x ==> ~(x = &0)` in
959 let lem4 = MATCH_MP lem3 (SPEC_ALL lem1) in
960 ACCEPT_TAC (GEN_ALL (MP lem2 lem4))
962 let NOVEMBER_LEMMA_1 = prove(
965 (abs(poly (g n p) x)) <=
966 (&1/(&(FACT (p -1)))) * ((&n) pow (p - 1)) * ((&n pow n) pow p)`,
967 let l0 = SPECL [`0`;`FACT (p-1)`] REAL_OF_NUM_LT in
968 let l2 = snd (EQ_IMP_RULE l0) in
969 let l3 = MP l2 (SPEC `(p:num) - 1` FACT_LT) in
970 let l4 = SPEC `(&(FACT (p - 1))):real` REAL_LE_LCANCEL_IMP in
971 let l5 = SIMP_RULE [l3] l4 in
972 let ll0 = snd (EQ_IMP_RULE (SPEC_ALL REAL_ABS_REFL)) in
973 let ll1 = IMP_TRANS (REAL_ARITH `(&0):real < x ==> &0 <= x`) ll0 in
974 let ll2 = UNDISCH ll1 in
975 let asses = [`(p:num) > 1`;`&0 < (x:real)`; `(x:real) < &n`] in
976 let j0 = SPECL [`p - 1`;`x:real`;`(&n):real`] REAL_POW_LE2 in
977 let j1 = REAL_ARITH `(&0) < (x:real) /\ x < (&n) ==> (&0 <=x /\ x <= (&n))` in
978 let j2 = UNDISCH_ALL (BRW1 (IMP_TRANS j1 j0)) in
979 let ll4 = SPECL [`(x:real) pow (p - 1)`;`((&n):real) pow (p - 1)`;`(abs (r:real)) pow p`] REAL_LE_MUL2 in
980 let ll5 = (SPECL [`x:real`;`(p:num) - 1`] REAL_POW_LE) in
981 let ll50 = UNDISCH (IMP_TRANS (REAL_ARITH `&0 < x ==> (&0) <= (x:real)`) ll5;) in
982 let ll6 = ADD_ASSUMS asses ll4 in
983 let ll7 = REAL_ARITH `(x:real) < y ==> x <= y` in
984 let ll8 = SIMP_RULE [j2;ll50;ll7;REAL_POW_LE;REAL_ABS_POS] ll6 in
985 let ll9 = ADD_ASSUM `p > 1` (SPEC `p:num` REAL_POW_LE2) in
986 let ll10 = UNDISCH (ARITH_RULE `p > 1 ==> ~(p = 0)`) in
987 let ll11 = SIMP_RULE [ll10] ll9 in
988 let ll12 = SPEC `abs (r:real)` ll11 in
989 let ll13 = SIMP_RULE [REAL_ABS_POS] ll12 in
990 let lem0 = UNDISCH (UNDISCH (BRW1 SEPTEMBER_2009_LEMMA_2)) in
991 let lem1 = MATCH_MP SEPTEMBER_2009_LEMMA lem0 in
992 let lem2 = DISCH_ALL (DISCH `(&0) < (x:real)` lem1) in
993 let lem3 = SPEC `SUC n` (GEN (`n:num`) lem2) in
994 (STRIP_TAC) THEN (STRIP_TAC) THEN
995 (ONCE_REWRITE_TAC [Pm_eqn5.PLANETMATH_EQN_5]) THEN
996 (ONCE_REWRITE_TAC [POLY_CMUL]) THEN
997 (ONCE_REWRITE_TAC [POLY_MUL]) THEN
998 (ONCE_REWRITE_TAC [POLY_EXP]) THEN
999 (ONCE_REWRITE_TAC [poly]) THEN
1000 (ONCE_REWRITE_TAC [poly]) THEN
1001 (ONCE_REWRITE_TAC [poly]) THEN
1002 (REWRITE_TAC rewrites0) THEN
1003 (ONCE_REWRITE_TAC [REAL_ABS_MUL]) THEN
1004 (ONCE_REWRITE_TAC [REAL_ABS_MUL]) THEN
1005 (ONCE_REWRITE_TAC [REAL_ABS_POW]) THEN
1006 (ONCE_REWRITE_TAC [REAL_ABS_DIV]) THEN
1007 (ONCE_REWRITE_TAC [ABS_N]) THEN
1008 (MATCH_MP_TAC l5) THEN
1009 (ONCE_REWRITE_TAC [REAL_MUL_ASSOC]) THEN
1010 (SIMP_TAC [FACT_DIV_LCANCELS;REAL_ARITH `&1 * (x:real) = x`]) THEN
1011 (SIMP_TAC [ll2]) THEN
1012 (MATCH_MP_TAC ll8) THEN
1013 (MATCH_MP_TAC ll13) THEN
1014 (UNDISCH_TAC `&0 < (x:real)`) THEN
1015 (UNDISCH_TAC `(x:real) < &n`) THEN
1016 (SPEC_TAC (`n:num`,`n:num`)) THEN
1017 INDUCT_TAC THENL [(REAL_ARITH_TAC); (ACCEPT_TAC lem3)]
1020 let NOVEMBER_LEMMA_2 = prove(
1022 ==> ((&0) < ( xi (&v) f) /\ (xi (&v) f) < (&n))`,
1023 let l0 = SPECL [`(&v):real`;`f:(real)list`] Pm_lemma1.xi_DEF in
1024 let l1 = UNDISCH (ONCE_REWRITE_RULE [REAL_OF_NUM_LT] l0) in
1025 let [l2;l3;_] = CONJUNCTS l1 in
1026 let l4 = GEN_ALL (REAL_ARITH `(&v) <= y ==> z < (&v) ==> (z:real) < y`) in
1027 let l6 = SPECL [`v:num`;`z:real`;`(&n):real`] l4 in
1028 let l7 = UNDISCH l6 in
1029 (ONCE_REWRITE_TAC [ TAUT `(X /\ Y ==> Z) <=> (X ==> Y ==> Z)`;ARITH_RULE `1 <= v <=> 0 < v` ]) THEN
1030 (ONCE_REWRITE_TAC [GSYM REAL_OF_NUM_LE;GSYM REAL_OF_NUM_LT]) THEN
1031 (STRIP_TAC) THEN (STRIP_TAC) THEN (SIMP_TAC [l2]) THEN
1032 (MATCH_MP_TAC l7) THEN (ACCEPT_TAC l3)
1035 let REAL_LE_MUL3 = prove(
1036 `! w0 x0 y0 w1 x1 (y1:real).
1037 (&0 <= w0) ==> (&0 <= x0) ==> (&0 <= y0) ==>
1038 (w0 <= w1) ==> (x0 <= x1) ==> (y0 <= y1) ==>
1039 (w0 * x0 * y0) <= (w1 * x1 * y1)`,
1040 let lst = [`w0:real`;`w1:real`;`(x0 * y0):real`;`(x1 * y1):real`] in
1041 let c0 = SPECL lst REAL_LE_MUL2 in
1042 MESON_TAC [c0;REAL_LE_MUL2;REAL_LE_MUL]
1046 new_recursive_definition list_RECURSION
1048 /\ (max_abs (CONS h t) = real_max (real_abs h) (max_abs t))`
1050 let MAX_ABS_LE = prove(
1052 (0 <= i /\ i < (LENGTH cs) ==>
1053 (real_abs (EL i cs)) <= (max_abs cs))`,
1054 let l0 = UNDISCH (REAL_ARITH `~((abs h) <= max_abs t) ==> x <= (max_abs t) ==> x <= (abs h)`) in
1055 LIST_INDUCT_TAC THENL
1056 [ (SIMP_TAC [LENGTH]) THEN ARITH_TAC;
1058 [ (SIMP_TAC [HD;EL;MAX_ABS_DEF;REAL_MAX_MAX]);
1059 (SIMP_TAC [TL;EL;MAX_ABS_DEF;REAL_MAX_MAX;LENGTH;LT_SUC]) THEN
1060 (ASM_CASES_TAC `(real_abs h) <= (max_abs t)`) THEN
1061 (ASM_SIMP_TAC [real_max;ARITH_RULE `0 <= y`;l0])
1065 let KEATS_PART_1 = prove(
1066 `1 <= i /\ i <= PRE (LENGTH c) ==> ( &i * abs (EL i c) <= &i * max_abs c)`,
1067 let keats12 = ARITH_RULE `1 <= i /\ i <= (PRE (LENGTH (c:(real)list))) ==> (0 <= i /\ i < LENGTH c)` in
1068 let keats13 = IMP_TRANS keats12 (SPECL [`c:(real)list`;`i:num`] MAX_ABS_LE) in
1069 let keats14 = SPECL [`real_of_num i`] REAL_LE_LMUL in
1070 let keats15 = ARITH_RULE `(&0) <= (real_of_num i)` in
1071 let keats16 = SIMP_RULE [keats15] keats14 in
1072 let keats17 = UNDISCH keats13 in
1073 let keats18 = MATCH_MP keats16 keats17 in
1074 ACCEPT_TAC (DISCH_ALL keats18)
1076 let KEATS_PART_2 = prove(
1077 `(1 <= v /\ v <= PRE (LENGTH (c:(real)list))) ==>
1078 abs (exp ((&v) - xi (&v) (g (PRE (LENGTH c)) p))) <= abs (exp (&(PRE (LENGTH (c:(real)list)))))`,
1079 let j0 = ASSUME `1 <= v /\ (v:num) <= (PRE (LENGTH (c:(real)list)))` in
1080 let j00 = ONCE_REWRITE_RULE [GSYM REAL_OF_NUM_LE] (CONJUNCT2 j0) in
1081 let j1 = REAL_ARITH `!n .(real_of_num v <= &n) ==> (&0 > --xi (&v) (g n p)) ==> (&n) > (&v) - (xi (&v) (g n p))` in
1082 let j2 = MP (SPEC `PRE (LENGTH (c:(real)list))` j1) j00 in
1083 let g_term = `g (PRE (LENGTH (c:(real)list))) p` in
1084 let k33 = SPEC `PRE (LENGTH (c:(real)list))` (GEN `n:num` NOVEMBER_LEMMA_2) in
1085 let k34 = SPEC g_term (GEN `f:(real)list` k33) in
1086 let k35 = DISCH `1 <= v /\ v <= (PRE (LENGTH (c:(real)list)))` (CONJUNCT1 (UNDISCH k34)) in
1087 let k36 = UNDISCH (SPEC `PRE (LENGTH (c:(real)list))` (GEN `n:num` k35)) in
1088 let k37 = REAL_ARITH `!x. (real_of_num 0) < x ==> (real_of_num 0) > -- x` in
1089 let k38 = MATCH_MP k37 k36 in
1090 let k40 = MP j2 k38 in
1091 let k41 = REAL_ARITH `!x (y:real).x > y ==> y <= x` in
1092 let k42 = MATCH_MP k41 k40 in
1093 let k42 = ONCE_REWRITE_RULE [GSYM REAL_EXP_MONO_LE] k42 in
1094 let k43 = REAL_ARITH `!(x:real) . (&0) <= x ==> abs x = x` in
1095 let k44 = GEN `x:real` (MATCH_MP k43 (SPEC `x:real` REAL_EXP_POS_LE)) in
1096 let k45 = ONCE_REWRITE_RULE [GSYM k44] k42 in
1097 let k46 = DISCH_ALL k45 in
1098 let k47 = BRW0 (SIMP_RULE [ARITH_RULE `0 < v <=> 1 <= v`] k46) in
1104 `p > 1 ==> (1 <= i /\ i <= PRE (LENGTH (c:(real)list)))
1105 ==> abs (poly (g (PRE (LENGTH c)) p) (xi (&i) (g (PRE (LENGTH c)) p))) <=
1106 &1 / &(FACT (p - 1)) *
1107 &(PRE (LENGTH c)) pow (p - 1) *
1108 &(PRE (LENGTH c)) pow PRE (LENGTH c) pow p`,
1109 let k0 = UNDISCH NOVEMBER_LEMMA_2 in
1110 let k1 = UNDISCH NOVEMBER_LEMMA_1 in
1111 let k2 = GEN `x:real` k1 in
1112 let k3 = SPEC `xi (real_of_num i) f` k2 in
1113 let k5 = MATCH_MP k3 k0 in
1114 let g_term = `g (PRE (LENGTH (c:(real)list))) p` in
1115 let k6 = SPEC g_term (GEN `f:(real)list` k5) in
1116 let k7 = SPEC `PRE (LENGTH (c:(real)list))` (GEN `n:num` (DISCH `1 <= v /\ v <= n` k6)) in
1117 let k8 = DISCH `0 < v` k7 in
1118 let k9 = BRW0 (SIMP_RULE [ARITH_RULE `0 < v <=> 1 <= v`] k8) in
1119 MATCH_ACCEPT_TAC (DISCH_ALL k9)
1122 let RHS_4_F5_LE_SUM = prove(
1123 `abs (RHS c (g (PRE (LENGTH c)) p)) <=
1124 sum (1..PRE (LENGTH c))
1127 abs (exp (&i - xi (&i) (g (PRE (LENGTH c)) p))) *
1129 (poly (g (PRE (LENGTH c)) p) (xi (&i) (g (PRE (LENGTH c)) p))))`,
1130 let keats4 = REFL `abs (RHS c f)` in
1131 let keats5 = (CONV_RULE (RAND_CONV (REWRITE_CONV [Pm_eqn4.RHS]))) keats4 in
1132 let keats6 = REWRITE_RULE [REAL_ABS_NEG] keats5 in
1134 SPECL [`(\i.(&i) * (EL i c) * (exp (&i - (xi (&i) f))) * (poly f (xi
1135 (&i) f)))`;`1`;`PRE (LENGTH (c:(real)list))`] SUM_ABS_NUMSEG in
1136 let keats8 = ONCE_REWRITE_RULE [GSYM keats6] keats7 in
1137 let keats9 = REWRITE_RULE [REAL_ABS_NUM;REAL_ABS_MUL] keats8 in
1138 let g_term = `g (PRE (LENGTH (c:(real)list))) p` in
1139 let keats10 = SPEC g_term (GEN `f:(real)list` keats9) in
1144 let RHS_4_BOUND_PRE = prove(
1145 `abs (RHS c (g (PRE (LENGTH c)) p)) <=
1146 (sum (1..PRE (LENGTH c)) &) *
1148 abs (exp (&(PRE (LENGTH c)))) *
1149 &1 / &(FACT (p - 1)) *
1150 &(PRE (LENGTH c)) pow (p - 1) *
1151 &(PRE (LENGTH c)) pow PRE (LENGTH c) pow p)`,
1152 let w0 = `(real_of_num i) * (real_abs (EL i c))` in
1153 let w1 = `(real_of_num i) * (max_abs c)` in
1154 let x0 = `abs (exp (&v - xi (&v) (g (PRE (LENGTH (c:(real)list))) p)))`
1156 let x1 = `abs (exp (&(PRE (LENGTH (c:(real)list)))))` in
1157 let y0 = `abs (poly (g (PRE (LENGTH (c:(real)list))) p) (xi (&i) (g (PRE
1158 (LENGTH c)) p)))` in
1159 let y1 = ` &1 / &(FACT (p - 1)) * &(PRE (LENGTH (c:(real)list))) pow (p -
1160 1) * &(PRE (LENGTH c)) pow PRE (LENGTH c) pow p` in
1161 let rename_free_var oo nn tt = SPEC nn (GEN oo tt) in
1162 let v2i tt = rename_free_var `v:num` `i:num` tt in
1163 let josh0 = SPECL [w0;x0;y0;w1;x1;y1] REAL_LE_MUL3 in
1164 let josh2 = SPECL [`real_of_num i`;`real_abs (EL i c)`] REAL_LE_MUL in
1165 let josh3 = SIMP_RULE [REAL_ABS_POS;REAL_ARITH `(real_of_num 0) <= &i`] josh2
1167 let josh4 = v2i (SIMP_RULE [josh3;REAL_ABS_POS] josh0) in
1168 let josh5 = SIMP_RULE [UNDISCH KEATS_PART_1] josh4 in
1169 let josh6 = SIMP_RULE [UNDISCH (v2i KEATS_PART_2)] josh5 in
1170 let josh7 = SIMP_RULE [UNDISCH KEATS_PART_3] josh6 in
1171 let josh8 = DISCH `1 <= i /\ i <= (PRE (LENGTH (c:(real)list)))` josh7 in
1175 abs (exp (&i - xi (&i) (g (PRE (LENGTH c)) p))) *
1176 abs (poly (g (PRE (LENGTH c)) p) (xi (&i) (g (PRE (LENGTH c))
1180 abs (exp (&(PRE (LENGTH c)))) *
1181 &1 / &(FACT (p - 1)) *
1182 &(PRE (LENGTH c)) pow (p - 1) *
1183 &(PRE (LENGTH c)) pow PRE (LENGTH c) pow p)` in
1184 let josh9 = SPECL [f0;f1;`1`;`PRE (LENGTH (c:(real)list))`] SUM_LE_NUMSEG
1186 let josh10 = REWRITE_RULE [GSYM REAL_MUL_ASSOC] (BETA_RULE josh9) in
1187 let josh11 = REWRITE_RULE [GSYM REAL_MUL_ASSOC] (GEN `i:num` josh8) in
1188 let josh12 = MP josh10 josh11 in
1189 let josh13 = CONJ RHS_4_F5_LE_SUM josh12 in
1190 let josh14 = MATCH_MP REAL_LE_TRANS josh13 in
1191 let josh15 = ONCE_REWRITE_RULE [SUM_RMUL] josh14 in
1195 (* A reviewer of the Journal of Formalized Reasoning paper for this proof
1196 * pointed out that the "abs" in "abs (exp (&(PRE (LENGTH c))))" of
1197 * RHS_4_BOUND_PRE is redundant. So here that theorem is rewritten to
1201 let l1 = MATCH_MP (SPEC `&0:real` REAL_LT_IMP_LE)
1202 (SPEC `x:real` REAL_EXP_POS_LT) in
1203 let l2 = REWRITE_RULE [GSYM REAL_ABS_REFL] l1 in
1204 ONCE_REWRITE_RULE [l2] RHS_4_BOUND_PRE
1207 let JESSE_POW_LEMMA = prove(
1208 `(p:num) > 1 ==> !x.real_pow x p = x * (real_pow x (p-1))`,
1209 let c0 = UNDISCH (ARITH_RULE `(p:num) > 1 ==> p = SUC (p - 1) `) in
1210 STRIP_TAC THEN STRIP_TAC THEN
1211 (CONV_TAC (RATOR_CONV (ONCE_REWRITE_CONV [c0]))) THEN
1212 (SIMP_TAC [real_pow])
1214 let JESSE_REAL_ABS_LE = prove(
1215 `!(x:real) y.(abs x) <= y ==> (abs x) <= (abs y)`,
1216 let int10 = UNDISCH (REAL_ARITH `(real_abs x) <= y ==> y = real_abs y`) in
1217 (REPEAT STRIP_TAC) THEN (ASM_SIMP_TAC [GSYM int10])
1219 let OLDGERMAN_LEMMA = prove(
1222 ==> (?N . !n. n >= N ==>
1223 abs (C2 * inv (&(FACT n)) * C pow n - &0) < e)`,
1224 let w0 = MATCH_MP SUM_SUMMABLE (SPEC `C:real` REAL_EXP_CONVERGES) in
1225 let w1 = MATCH_MP SER_ZERO w0 in
1226 let w2 = BETA_RULE w1 in
1227 let w3 = SPEC `C2:real` SEQ_CONST in
1228 let w4 = CONJ w3 w2 in
1229 let w5 = BETA_RULE (MATCH_MP SEQ_MUL w4) in
1230 let w6 = ONCE_REWRITE_RULE [REAL_ARITH `(C2:real) * (&0) = &0`] w5 in
1231 let w7 = ONCE_REWRITE_RULE [SEQ] w6 in
1232 let w8 = GEN_ALL (BETA_RULE w7) in
1233 (REPEAT STRIP_TAC) THEN
1234 (CHOOSE_TAC (UNDISCH (SPEC_ALL w8))) THEN
1235 (EXISTS_TAC `SUC N`) THEN
1236 (ASM_SIMP_TAC [ARITH_RULE `n' >= SUC n ==> n' >= n`])
1239 let RHS_4_LT_ONE_MESSY = prove(
1240 `?p0. !p. p > 1 ==> p> p0 ==> abs (RHS c (g (PRE (LENGTH c)) p)) < &1`,
1241 let c1 = ONCE_REWRITE_RULE [ UNDISCH JESSE_POW_LEMMA ] RHS_4_BOUND in
1242 let c2 = SPECL [`real_pow (&(PRE (LENGTH (c:(real)list)))) (p-1)`]
1244 let c3 = ONCE_REWRITE_RULE [ c2] c1 in
1245 let c4 = ONCE_REWRITE_RULE [ GSYM REAL_MUL_ASSOC ] c3 in
1246 let c5 = ONCE_REWRITE_RULE [ GSYM REAL_POW_MUL ] c4 in
1247 let c6 = ONCE_REWRITE_RULE [REAL_MUL_SYM] (CONJUNCT2 real_pow) in
1248 let c7 = ONCE_REWRITE_RULE [GSYM c6] c5 in
1249 let c8 = REAL_ARITH `!x. (real_of_num 1)/x = inv x` in
1250 let c9 = ONCE_REWRITE_RULE [c8] c7 in
1251 let c10 = REAL_ARITH `!x y z.(inv x) * y * z = y * inv x * z` in
1252 let c11 = ONCE_REWRITE_RULE [c10] c9 in
1254 `sum (1..PRE (LENGTH c)) & *
1256 (exp (&(PRE (LENGTH c)))) *
1257 &(PRE (LENGTH c)) pow PRE (LENGTH c)` in
1258 let t1 = `real_of_num (PRE (LENGTH (c:(real)list))) pow SUC (PRE (LENGTH c))`
1260 let int0 = SPECL [t0;t1;`real_of_num 1`] OLDGERMAN_LEMMA in
1261 let int1 = SIMP_RULE [REAL_ARITH `(real_of_num 0) < &1`] int0 in
1262 let int2 = SIMP_RULE [REAL_ARITH `x - (real_of_num 0) = x`] int1 in
1263 let t8 = `!n. n >= N
1265 ((sum (1..PRE (LENGTH c)) & *
1267 (exp (&(PRE (LENGTH c)))) *
1268 &(PRE (LENGTH c)) pow PRE (LENGTH c)) *
1270 &(PRE (LENGTH c)) pow SUC (PRE (LENGTH c)) pow n) <
1272 let int5 = ASSUME t8 in
1273 let int50 = REAL_ARITH `((x:real) * y * z * w) * (a * b) = x * y * z * w * a *
1275 let int51 = ONCE_REWRITE_RULE [int50] int5 in
1276 let int6 = SPEC `p - 1` int51 in
1277 let int7 = ARITH_RULE ` (p > N ==> p - 1 >= N)` in
1278 let int8 = UNDISCH (IMP_TRANS int7 int6) in
1279 let int9 = ARITH_RULE `(x:real) <= y ==> y < (real_of_num 1) ==> x < (&1)` in
1280 let int10 = MATCH_MP JESSE_REAL_ABS_LE c11 in
1281 let int11 = MATCH_MP int9 int10 in
1282 let int12 = MP int11 int8 in
1283 (CHOOSE_TAC int2) THEN
1284 (EXISTS_TAC `N:num`) THEN
1287 (ONCE_REWRITE_TAC [ARITH_RULE `p > 0 ==> ((p:num) > N <=> p - 1 >= N)`]) THEN
1289 (MATCH_ACCEPT_TAC int12)
1292 `!c. ?p0. !p. p> p0 ==> abs (RHS c (g (PRE (LENGTH c)) p)) < &1`,
1293 STRIP_TAC THEN (CHOOSE_TAC RHS_4_LT_ONE_MESSY) THEN (EXISTS_TAC `SUC p0`) THEN
1294 (ASM_MESON_TAC [ARITH_RULE `p > SUC p0 ==> (p > p0 /\ p > 1)`])
1301 module Pm_eqn4_lhs = struct
1303 let N_IS_INT = prove(
1304 `!n . integer (&n)`,
1307 let NEG_N_IS_INT = prove(
1308 `!n . integer (--(&n))`,
1311 let INT_OF_REAL_ADD = prove(
1312 `!x y.(integer x) /\ (integer y)
1313 ==> (int_of_real (x + y)) =
1314 (int_of_real x) + (int_of_real y)`,
1315 SIMP_TAC[integer;int_add;int_rep;N_IS_INT;NEG_N_IS_INT]
1317 let INT_OF_REAL_MUL = prove(
1318 `!x y.(integer x) /\ (integer y)
1319 ==> (int_of_real (x * y)) =
1320 (int_of_real x) * (int_of_real y)`,
1321 SIMP_TAC[is_int;int_mul;int_rep;N_IS_INT;NEG_N_IS_INT]
1324 let rec INT_OF_REAL_CONV_helper t =
1325 let real_op_2_int_op t =
1326 if (t = `real_add`) then `int_add`
1327 else if (t = `real_sub`) then `int_sub`
1328 else if (t = `real_mul`) then `int_mul`
1329 else if (t = `real_pow`) then `int_pow`
1330 else if (t = `real_neg`) then `int_neg`
1333 if (is_var t) then (mk_comb (`int_of_real`,t),[],[t])
1334 else if ((rator t) = `real_of_num`) then
1335 (mk_comb (`int_of_real`, t),[t],[])
1336 else if ((rator t) = `real_neg`) then
1337 let rand1 = rand t in
1338 let (expr1,lst1,lst2) = INT_OF_REAL_CONV_helper rand1 in
1339 let lst = lst1 @ [t] in
1340 let expr = mk_comb (`int_neg`, expr1) in
1342 else if ((rator (rator t)) = `real_pow`) then
1343 let rand1 = rand (rator t) in
1344 let exponent = rand t in
1345 let (expr1,lst1,lst2) = INT_OF_REAL_CONV_helper rand1 in
1346 let lst = lst1 @ [t] in
1347 let expr = mk_comb (mk_comb (`int_pow`,expr1),exponent) in
1349 else if ( ((rator (rator t)) = `real_add`)
1350 or ((rator (rator t)) = `real_mul`)
1351 or ((rator (rator t)) = `real_sub`) ) then
1352 let int_op = real_op_2_int_op (rator (rator t)) in
1353 let rand1 = rand (rator t) in
1354 let rand2 = rand t in
1355 let (expr1,lst11,lst12) = INT_OF_REAL_CONV_helper rand1 in
1356 let (expr2,lst21,lst22) = INT_OF_REAL_CONV_helper rand2 in
1357 let lst1 = lst11 @ lst21 @ [t] in
1358 let lst2 = lst12 @ lst22 in
1359 let expr = mk_comb (mk_comb (int_op,expr1),expr2) in
1364 (* ------------------------------------------------------------------------- *)
1365 (* I wrote an initial version of this, but John Harrison proposed this *)
1366 (* version which is faster and also requires less theorems. *)
1367 (* ------------------------------------------------------------------------- *)
1368 let INT_OF_REAL_CONV =
1369 let final_tweak = MATCH_MP(MESON[int_tybij] `real_of_int x = y ==> int_of_real y = x`) in
1371 let (exp,real_sub_terms,is_int_assumpts) = INT_OF_REAL_CONV_helper t in
1372 let is_int_assumpts = List.map (fun x -> mk_comb (`integer`,x)) is_int_assumpts in
1373 let fexp = rand(concl(PURE_REWRITE_CONV[GSYM int_of_num] exp)) in
1374 let rexp = mk_comb(`real_of_int`,fexp)
1375 and ths = map (GEN_REWRITE_RULE I [CONJUNCT2 int_tybij] o ASSUME) is_int_assumpts in
1376 let th3 = PURE_REWRITE_CONV(ths @ [int_pow_th; int_add_th; int_mul_th; int_sub_th; int_neg_th; int_of_num_th]) rexp in
1377 itlist DISCH is_int_assumpts (final_tweak th3)
1379 let ALL_IS_INT = prove(
1380 `! h t . (ALL integer (CONS h t)) ==> (integer h) /\ (ALL integer t)`,
1384 let ALL_IS_INT_POLY_ADD = prove(
1385 `! p1 p2 . (ALL integer p1) /\ (ALL integer p2) ==> (ALL integer (p1 ++ p2))`,
1386 let lem01 = UNDISCH (SPECL [`h:real`;`t:(real)list`] ALL_IS_INT) in
1387 let [lem02;lem03] = CONJUNCTS lem01 in
1388 let lem04 = UNDISCH (SPECL [`h':real`;`t':(real)list`] ALL_IS_INT) in
1389 let [lem05;lem06] = CONJUNCTS lem04 in
1390 let lem07 = CONJ lem02 lem05 in
1391 let lem08 = MATCH_MP INTEGER_ADD lem07 in
1392 let lem09 = ASSUME `! p2. ALL integer t /\ ALL integer p2 ==> ALL integer (t ++ p2)` in
1393 let lem10 = SPEC `t':(real)list` lem09 in
1394 let lem11 = CONJ lem03 lem06 in
1395 let lem12 = MP lem10 lem11 in
1396 LIST_INDUCT_TAC THENL
1397 [ (SIMP_TAC [poly_add]);
1398 LIST_INDUCT_TAC THENL
1399 [ (SIMP_TAC [poly_add]);
1400 (SIMP_TAC [poly_add]) THEN (ONCE_REWRITE_TAC [NOT_CONS_NIL]) THEN
1401 (SIMP_TAC []) THEN (SIMP_TAC [HD;TL]) THEN (STRIP_TAC) THEN
1402 (SIMP_TAC [ALL]) THEN
1403 (CONJ_TAC) THENL [(ACCEPT_TAC lem08); (ACCEPT_TAC lem12)]
1407 let ALL_IS_INT_POLY_CMUL = prove(
1408 `! p c. (integer c) /\ (ALL integer p) ==> (ALL integer (c ## p))`,
1409 (LIST_INDUCT_TAC) THEN (ASM_SIMP_TAC [poly_cmul;ALL;INTEGER_MUL])
1412 let ALL_IS_INT_POLY_MUL = prove(
1413 `! p1 p2 . (ALL integer p1) /\ (ALL integer p2) ==> (ALL integer (p1 ** p2))`,
1414 let lem01 = UNDISCH (SPECL [`h:real`;`t:(real)list`] ALL_IS_INT) in
1415 let lem02 = UNDISCH (SPECL [`h':real`;`t':(real)list`] ALL_IS_INT) in
1416 let [lem03;lem04] = CONJUNCTS lem01 in
1417 let [lem05;lem06] = CONJUNCTS lem02 in
1418 let lem07 = MATCH_MP INTEGER_MUL (CONJ lem03 lem05) in
1419 let lem08 = MATCH_MP ALL_IS_INT_POLY_CMUL (CONJ lem03 lem06) in
1420 let lem09 = ASSUME `! p2. ALL integer t /\ ALL integer p2 ==> ALL integer (t ** p2)` in
1421 let lem10 = SPEC `(CONS h' t'):(real)list` lem09 in
1422 LIST_INDUCT_TAC THENL
1423 [ (LIST_INDUCT_TAC THENL [(SIMP_TAC [ALL;poly_mul]);(SIMP_TAC [poly_mul])]);
1424 LIST_INDUCT_TAC THENL
1425 [ (SIMP_TAC [poly_mul]) THEN
1426 ((ASM_CASES_TAC `(t:(real)list) = []`) THENL
1427 [ (ASM_SIMP_TAC [ALL;poly_cmul]) THEN (SIMP_TAC [poly_cmul]);
1428 (ASM_SIMP_TAC [ALL;poly_cmul;poly_add]) THEN (SIMP_TAC [SPEC `0` N_IS_INT])
1430 (STRIP_TAC) THEN (ONCE_REWRITE_TAC [poly_mul] ) THEN
1431 (ASM_CASES_TAC `(t:(real)list) = []`) THENL
1432 [ (ASM_SIMP_TAC [ALL;poly_cmul]) THEN STRIP_TAC THENL
1433 [(ACCEPT_TAC lem07) ;(ACCEPT_TAC lem08)];
1434 (ASM_SIMP_TAC []) THEN (MATCH_MP_TAC ALL_IS_INT_POLY_ADD) THEN
1436 [ (MATCH_MP_TAC ALL_IS_INT_POLY_CMUL) THEN (CONJ_TAC) THENL
1437 [(ACCEPT_TAC lem03) ; (ASM_SIMP_TAC[])];
1438 (SIMP_TAC [ALL]) THEN (CONJ_TAC) THENL
1439 [(ACCEPT_TAC (SPEC `0` N_IS_INT)); (ASM_SIMP_TAC [lem04;lem10])]
1445 let NOT_POLY_MUL_ITER_NIL = prove(
1446 `! n . ~((poly_mul_iter (\i.[ -- &i; &1]) n) = [])`,
1447 let lem02 = SIMP_RULE [NOT_CONS_NIL] (ISPEC `[ -- &(SUC n); &1]` NOT_POLY_MUL_NIL ) in
1448 let lem03 = ISPEC `(poly_mul_iter (\i.[ -- &i; &1]) n)` lem02 in
1449 let lem04 = UNDISCH lem03 in
1451 [ (SIMP_TAC [Pm_eqn5.POLY_MUL_ITER;NOT_CONS_NIL]);
1452 (SIMP_TAC [Pm_eqn5.POLY_MUL_ITER;lem04])
1456 let ALL_IS_INT_POLY_MUL_ITER = prove(
1457 `! n. (ALL integer (poly_mul_iter (\i.[-- &i; &1]) n))`,
1458 let FOOBAR_LEMMA = prove(
1459 `ALL integer [-- &(SUC n); &1]`,
1460 (SIMP_TAC [ALL]) THEN (SIMP_TAC [N_IS_INT;NEG_N_IS_INT])) in
1462 [ (ONCE_REWRITE_TAC [Pm_eqn5.POLY_MUL_ITER]) THEN
1463 (ONCE_REWRITE_TAC [ALL]) THEN (SIMP_TAC [ALL;N_IS_INT]);
1464 (ONCE_REWRITE_TAC [Pm_eqn5.POLY_MUL_ITER]) THEN (BETA_TAC) THEN
1465 (MATCH_MP_TAC ALL_IS_INT_POLY_MUL) THEN (CONJ_TAC) THENL
1466 [(ACCEPT_TAC (FOOBAR_LEMMA)); (ASM_SIMP_TAC [])]
1470 let ALL_IS_INT_POLY_EXP = prove(
1471 `!n p. (ALL integer p) ==> (ALL integer (poly_exp p n))`,
1472 let lem01 = ASSUME `! p. ALL integer p ==> ALL integer (poly_exp p n)` in
1473 let lem02 = ASSUME ` ALL integer p` in
1474 let lem03 = MP (SPEC_ALL lem01) lem02 in
1475 let lem04 = CONJ lem02 lem03 in
1476 let lem05 = MATCH_MP ALL_IS_INT_POLY_MUL lem04 in
1478 [ (ONCE_REWRITE_TAC [poly_exp]) THEN (ONCE_REWRITE_TAC [ALL]) THEN
1479 (ONCE_REWRITE_TAC [ALL]) THEN (SIMP_TAC [SPEC `1` N_IS_INT]);
1480 (ONCE_REWRITE_TAC [poly_exp]) THEN (REPEAT STRIP_TAC) THEN (ACCEPT_TAC lem05)
1484 let BLAHBLAH = prove(
1485 `! p1 p2. (LENGTH p1 <= LENGTH p2) ==> (&0 ## p1 ++ p2) = p2`,
1486 LIST_INDUCT_TAC THENL
1487 [ (SIMP_TAC [LENGTH;poly_cmul;poly_add]);
1488 LIST_INDUCT_TAC THENL
1489 [ (SIMP_TAC [LENGTH]) THEN ARITH_TAC;
1490 (ASM_SIMP_TAC [poly_cmul;poly_add;NOT_CONS_NIL;HD;TL;
1491 REAL_ARITH `&0 * h + h' = h'`;LENGTH;
1492 ARITH_RULE `(SUC x) <= (SUC y) <=> x <= y`]) ]
1496 let BLAHBLAH3 = prove(
1497 `! n h t. (LENGTH t) <= LENGTH (poly_exp [&0;&1] n ** CONS h t)`,
1498 let lem04 = ASSUME `! h t . LENGTH t <= LENGTH (poly_exp [&0;&1] n ** CONS h t)` in
1499 let lem05 = SPECL [`h:real`;`t:(real)list`] lem04 in
1500 let lem06 = ARITH_RULE `!(x:num) y . x <= y ==> x <= SUC y` in
1501 let lem07 = MATCH_MP lem06 lem05 in
1502 let lem08 = GEN_ALL lem07 in
1504 [ (SIMP_TAC [poly_exp;poly_mul;poly_cmul;POLY_CMUL_LID;LENGTH]) THEN ARITH_TAC;
1505 (SIMP_TAC [POLY_EXP_X_REC;poly_mul;NOT_POLY_EXP_X_NIL;poly_cmul;poly_add;NOT_CONS_NIL;LENGTH;TL]) THEN
1506 (ASM_SIMP_TAC [BLAHBLAH]) THEN (ACCEPT_TAC lem08)
1509 let TELEVISION = prove (
1510 `!n p.(~ (p = [])) ==> EL n (poly_exp [&0;&1] n ** p) = HD p`,
1511 let lem = MATCH_MP BLAHBLAH (SPEC_ALL BLAHBLAH3) in
1513 [ (SIMP_TAC [EL;poly_exp;POLY_MUL_CLAUSES]) THEN (LIST_INDUCT_TAC) THENL
1514 [ (SIMP_TAC[]); (SIMP_TAC [NOT_CONS_NIL;POLY_CMUL_LID])];
1515 (SIMP_TAC [EL;POLY_EXP_X_REC;poly_mul;NOT_POLY_EXP_X_NIL]) THEN
1516 LIST_INDUCT_TAC THENL
1518 (SIMP_TAC [poly_cmul;poly_add;NOT_CONS_NIL;TL;HD]) THEN
1519 (ASM_SIMP_TAC [lem;NOT_CONS_NIL;HD])
1524 `!i n p.(~ (p = [])) /\ (i < n) ==> EL i (poly_exp [&0;&1] n ** p) = &0`,
1525 let lem0000 = SPECL [`t:(real)list`;`poly_exp [&0;&1] n ** (CONS h t)`] BLAHBLAH in
1526 let lem0001 = MATCH_MP lem0000 (SPEC_ALL BLAHBLAH3) in
1527 let lem0002 = ASSUME `! n p . ~(p = []) /\ i < n ==> EL i (poly_exp [&0;&1] n ** p) = &0` in
1528 let lem0003 = SIMP_RULE [NOT_CONS_NIL] (SPECL [`n:num`;`(CONS (h:real) t)`] lem0002) in
1532 LIST_INDUCT_TAC THENL
1534 (SIMP_TAC [POLY_EXP_X_REC;EL;HD;poly_mul;NOT_POLY_EXP_NIL;NOT_CONS_NIL;HD_POLY_ADD;poly_cmul]) THEN
1540 (SIMP_TAC [EL;POLY_EXP_X_REC;poly_mul;NOT_POLY_EXP_NIL;NOT_CONS_NIL]) THEN
1541 LIST_INDUCT_TAC THENL
1543 (SIMP_TAC [poly_cmul;poly_add;NOT_CONS_NIL;TL;lem0001]) THEN
1544 (SIMP_TAC [ARITH_RULE `(SUC i) < (SUC n) <=> i < n`;lem0003])
1549 let POLY_MUL_HD = prove(
1550 `! p1 p2. (~(p1 = []) /\ ~(p2 = [])) ==> (HD (p1 ** p2)) = (HD p1) * (HD p2)`,
1551 LIST_INDUCT_TAC THENL
1553 (LIST_INDUCT_TAC) THENL
1555 (SIMP_TAC [NOT_CONS_NIL]) THEN (ONCE_REWRITE_TAC [poly_mul]) THEN
1556 (ASM_CASES_TAC `(t:(real)list) = []`) THENL
1557 [ (ASM_SIMP_TAC [HD;poly_cmul]);
1558 (ASM_SIMP_TAC [HD;poly_cmul;poly_add]) THEN
1559 (SIMP_TAC [NOT_CONS_NIL;HD]) THEN (REAL_ARITH_TAC)
1564 let POLY_MUL_ITER_HD_FACTORIAL = prove(
1565 `! n. (HD (poly_mul_iter (\i.[-- &i; &1]) n)) = ((-- &1) pow n) * (&(FACT n))`,
1566 let lem01 = prove(`~([-- &(SUC n); &1] = [])`,SIMP_TAC [NOT_CONS_NIL]) in
1568 [`[-- &(SUC n); &1]`;`poly_mul_iter (\i.[-- &i; &1]) n`]
1570 let lem03 = CONJ lem01 (SPEC_ALL NOT_POLY_MUL_ITER_NIL) in
1571 let lem04 = MP lem02 lem03 in
1573 `!n. ((-- &1) pow n) = -- ((-- &1) pow (SUC n))`,
1574 STRIP_TAC THEN (ONCE_REWRITE_TAC [pow]) THEN REAL_ARITH_TAC
1577 [ (ONCE_REWRITE_TAC [Pm_eqn5.POLY_MUL_ITER]) THEN (SIMP_TAC [HD;FACT]) THEN REAL_ARITH_TAC;
1578 (ONCE_REWRITE_TAC [Pm_eqn5.POLY_MUL_ITER]) THEN BETA_TAC THEN
1579 (ONCE_REWRITE_TAC [lem04]) THEN (ONCE_REWRITE_TAC [HD]) THEN
1580 (ASM_SIMP_TAC []) THEN (ONCE_REWRITE_TAC [FACT]) THEN
1581 (ONCE_REWRITE_TAC [GSYM REAL_OF_NUM_MUL]) THEN
1582 (CONV_TAC (RATOR_CONV (ONCE_REWRITE_CONV [lem05]))) THEN REAL_ARITH_TAC
1585 let PLANETMATH_THM_5_1 = prove(
1590 ((g n p) = (&1/(&(FACT (p - 1)))) ## As)
1591 /\ (! i. i< (p-1) ==> (EL i As) = &0)
1592 /\ ((EL (p-1) As) = ((-- &1) pow (n * p)) * ((&(FACT n)) pow p))
1593 /\ (ALL integer As)`,
1594 let lem01 = SPECL [`poly_exp [&0;&1] (p - 1)`;`poly_exp (poly_mul_iter (\i.[-- &i; &1]) n) p`] ALL_IS_INT_POLY_MUL in
1595 let lem02 = SPECL [`p-1`;`[&0;&1]`] ALL_IS_INT_POLY_EXP in
1596 let lem03 = prove(`ALL integer [&0;&1]`, (REWRITE_TAC [ALL]) THEN (SIMP_TAC [N_IS_INT])) in
1597 let lem04 = MP lem02 lem03 in
1598 let lem05 = SPECL [`p:num`;`poly_mul_iter (\i.[-- &i; &1]) n`] ALL_IS_INT_POLY_EXP in
1599 let lem06 = MP lem05 (SPEC_ALL ALL_IS_INT_POLY_MUL_ITER) in
1600 let lem07 = MP lem01 (CONJ lem04 lem06) in
1601 let lem08 = SPECL [`p-1`;`poly_exp (poly_mul_iter (\i.[-- &i; &1]) n) p`] TELEVISION in
1602 let lem09 = SIMP_RULE [ NOT_POLY_EXP_NIL;NOT_POLY_MUL_ITER_NIL] lem08 in
1603 let lem10 = SPECL [`i:num`;`p - 1`;`poly_exp (poly_mul_iter (\i. [ -- &i; &1]) n ) p`] JOSHUA in
1604 let lem11 = SIMP_RULE [NOT_POLY_MUL_ITER_NIL;NOT_POLY_EXP_NIL] lem10 in
1605 (REPEAT STRIP_TAC) THEN
1606 (EXISTS_TAC `((poly_exp [&0;&1] (p-1)) ** (poly_exp (poly_mul_iter (\i.[-- &i; &1]) n) p))`) THEN
1608 [ (ONCE_REWRITE_TAC [Pm_eqn5.PLANETMATH_EQN_5]) THEN (SIMP_TAC[]);
1610 [ (SIMP_TAC [lem11]);
1612 [ (ONCE_REWRITE_TAC [lem09]) THEN
1613 (SPEC_TAC (`n:num`,`n:num`)) THEN
1615 [ (SIMP_TAC [NOT_CONS_NIL;HD_POLY_EXP;HD;Pm_eqn5.POLY_MUL_ITER;FACT;pow;
1616 REAL_POW_ONE;ARITH_RULE `0 * p = 0`;REAL_ARITH `&1 * &1 = &1`]);
1617 (SIMP_TAC [HD_POLY_EXP; NOT_POLY_MUL_ITER_NIL; POLY_MUL_ITER_HD_FACTORIAL]) THEN
1618 (SIMP_TAC [REAL_POW_MUL;REAL_POW_POW;BLAHBLAH3]) ];
1624 let ll01 = SPEC_ALL PLANETMATH_THM_5_1 in
1625 let FO_LEMMA1 = prove(`((p > 0) ==> (n > 0) ==> (? z. C p n z))
1626 <=> (? z. (p > 0) ==> (n > 0) ==> C p n z)`,MESON_TAC[]) in
1627 let ll02 = GEN_ALL (SIMP_RULE [FO_LEMMA1] ll01) in
1628 let ll03 = ONCE_REWRITE_RULE [SKOLEM_CONV (concl ll02)] ll02 in
1629 new_specification ["As"] ll03
1630 (* split up def of As into its four conjuncts *)
1632 = (GEN_ALL o DISCH_ALL o CONJUNCT1 o UNDISCH o UNDISCH o SPEC_ALL) as_def
1634 = (GEN_ALL o DISCH_ALL o CONJUNCT1 o CONJUNCT2 o UNDISCH o UNDISCH o SPEC_ALL) as_def
1636 = (GEN_ALL o DISCH_ALL o CONJUNCT1 o CONJUNCT2 o CONJUNCT2 o UNDISCH o UNDISCH o SPEC_ALL) as_def
1638 = (GEN_ALL o DISCH_ALL o CONJUNCT2 o CONJUNCT2 o CONJUNCT2 o UNDISCH o UNDISCH o SPEC_ALL) as_def
1640 let POLY_DIFF_AUX_LEM1 = prove(
1641 `! i p k. i < (LENGTH p) ==> EL i (poly_diff_aux k p) = (EL i p) * &(i + k)`,
1642 let lem0001 = ASSUME `! p k . i < LENGTH p ==> EL i (poly_diff_aux k p ) = EL i p * &(i + k)` in
1643 let lem0002 = SPECL [` t:(real)list`;`SUC k`] lem0001 in
1644 let lem0003 = prove(`SUC i < LENGTH (CONS (h:real) t) <=> i < LENGTH t`,(SIMP_TAC [LENGTH]) THEN ARITH_TAC) in
1646 [ LIST_INDUCT_TAC THENL
1647 [ (SIMP_TAC [poly_diff_aux;LENGTH]) THEN ARITH_TAC;
1648 (SIMP_TAC [poly_diff_aux;ARITH_RULE `0 + k = k`;poly_diff;LENGTH;EL;HD;TL]) THEN REAL_ARITH_TAC ];
1649 LIST_INDUCT_TAC THENL
1650 [ (SIMP_TAC [LENGTH]) THEN ARITH_TAC;
1651 (SIMP_TAC [poly_diff_aux;EL;TL]) THEN STRIP_TAC THEN
1652 (SIMP_TAC [lem0003;lem0002;ARITH_RULE `i + SUC k = SUC i + k`]) ]
1655 let EL_POLY_DIFF = prove(
1656 `! i p. i < (LENGTH (poly_diff p)) ==> EL i (poly_diff p) = (EL (SUC i) p) * &(SUC i)`,
1657 let lem01 = SPECL [`SUC i`;`t:(real)list`;`1`] POLY_DIFF_AUX_LEM1 in
1659 [ LIST_INDUCT_TAC THENL
1660 [ ((SIMP_TAC [LENGTH;poly_diff]) THEN ARITH_TAC);
1661 (SIMP_TAC [LENGTH;PRE;EL;HD;TL;ARITH_RULE `SUC 0 = 1`;REAL_ARITH `x * &1 = x`;poly_diff;NOT_CONS_NIL]) THEN
1662 (SPEC_TAC (`t:(real)list`,`t:(real)list`)) THEN
1663 LIST_INDUCT_TAC THENL [(SIMP_TAC [LENGTH;poly_diff_aux]) THEN ARITH_TAC;
1664 (SIMP_TAC [HD;poly_diff_aux;REAL_ARITH `&1 * h = h`])]
1666 LIST_INDUCT_TAC THENL
1667 [ ((SIMP_TAC [LENGTH;HD;poly_diff;REAL_ARITH `&1 * h = h`])) THEN ARITH_TAC;
1668 (SIMP_TAC [poly_diff;NOT_CONS_NIL;TL;LENGTH_POLY_DIFF_AUX ]) THEN (SIMP_TAC [lem01;EL;TL]) THEN ARITH_TAC ]
1671 let POLY_AT_ZERO = prove(
1672 `!p .(~(p = [])) ==> poly p (&0) = HD p`,
1673 LIST_INDUCT_TAC THENL [ SIMP_TAC []; (SIMP_TAC [poly;HD]) THEN REAL_ARITH_TAC ]
1675 let PDI_POLY_DIFF_COMM = prove(
1676 `! p n.(poly_diff_iter (poly_diff p) n) = (poly_diff (poly_diff_iter p n))`,
1677 STRIP_TAC THEN INDUCT_TAC THENL
1678 [(SIMP_TAC [Pm_lemma1.PDI_DEF]);
1679 (ONCE_REWRITE_TAC [Pm_lemma1.PDI_DEF]) THEN (ASM_SIMP_TAC [])]
1681 let EL_PDI_AT_ZERO = prove(
1682 `!i p. (i < (LENGTH p))
1683 ==> ( poly (poly_diff_iter p i) (&0)) = ((EL i p) * (&(FACT i)))`,
1684 let lem03 = prove(`SUC i < LENGTH (CONS (h:real) t) <=> i < LENGTH t`,(SIMP_TAC [LENGTH]) THEN ARITH_TAC) in
1685 let lem04 = ASSUME `!p . i < LENGTH p ==> poly (poly_diff_iter p i) (&0) = EL i p * &(FACT i)` in
1686 let lem05 = SIMP_RULE [LENGTH_POLY_DIFF;LENGTH;PRE] (SPEC `poly_diff (CONS h t)` lem04) in
1687 let lem06 = prove(`i < LENGTH t ==> i < LENGTH (poly_diff (CONS h t))`,SIMP_TAC [LENGTH_POLY_DIFF;PRE;LENGTH]) in
1689 [ (LIST_INDUCT_TAC THENL
1690 [(SIMP_TAC [LENGTH]) THEN ARITH_TAC; (SIMP_TAC [Pm_lemma1.PDI_DEF;FACT;EL;NOT_CONS_NIL;POLY_AT_ZERO]) THEN REAL_ARITH_TAC]);
1691 LIST_INDUCT_TAC THENL
1692 [ (SIMP_TAC [LENGTH]) THEN ARITH_TAC;
1693 (SIMP_TAC [Pm_lemma1.PDI_DEF;GSYM PDI_POLY_DIFF_COMM;lem03;lem05]) THEN
1694 (SIMP_TAC [lem06;EL_POLY_DIFF;FACT;REAL_OF_NUM_MUL;GSYM REAL_MUL_ASSOC])
1698 let EL_PDI_AT_ZERO2 = prove(
1699 `!i p. ((~ (p = [])) /\ (i <= (LENGTH p) - 1)) ==> ( poly (poly_diff_iter p i) (&0)) = ((EL i p) * (&(FACT i)))`,
1700 STRIP_TAC THEN LIST_INDUCT_TAC THEN
1701 (SIMP_TAC [NOT_CONS_NIL;LENGTH;ARITH_RULE `(i <= (SUC x) -1) <=> (i < (SUC x))`;EL_PDI_AT_ZERO])
1703 let POLY_CMUL_PDI = prove(
1704 `!p c i. (poly_diff_iter (c ## p) i) = c ##(poly_diff_iter p i)`,
1705 STRIP_TAC THEN STRIP_TAC THEN INDUCT_TAC THEN (ASM_SIMP_TAC [Pm_lemma1.PDI_DEF;POLY_CMUL_POLY_DIFF])
1707 let LENGTH_g = prove(
1708 `! n p . (LENGTH (g n p)) >= p `,
1709 let lem00 = ARITH_RULE `SUC ((SUC p ) - 1) = SUC p` in
1710 let lem01 = prove(`! n p. ~((poly_exp (poly_mul_iter (\i.[-- &i; &1]) n ) (SUC p)) = [])`,
1711 SIMP_TAC [NOT_POLY_EXP_NIL; NOT_POLY_MUL_ITER_NIL]) in
1712 let lem02 = MATCH_MP POLY_MUL_LENGTH2 (SPEC_ALL lem01) in
1713 let lem03 = SPECL [`poly_exp [&0;&1] (SUC p - 1)`] lem02 in
1714 let lem04 = SIMP_RULE [POLY_EXP_X_LENGTH] lem03 in
1715 let lem05 = SIMP_RULE [lem00] lem04 in
1716 (SIMP_TAC [Pm_eqn5.PLANETMATH_EQN_5;POLY_CMUL_LENGTH]) THEN STRIP_TAC THEN INDUCT_TAC THENL
1717 [ ARITH_TAC; SIMP_TAC [lem05]]
1719 let LENGTH_As = prove(
1720 `! n p . p > 0 ==> n > 0 ==> LENGTH (As n p) >= p`,
1721 let lem50 = ADD_ASSUM `p > 0` (ADD_ASSUM `n > 0` (SPEC_ALL LENGTH_g)) in
1722 let lem51 = ONCE_REWRITE_RULE [UNDISCH_ALL (SPEC_ALL g_eq_As)] lem50 in
1723 let lem52 = ONCE_REWRITE_RULE [POLY_CMUL_LENGTH] lem51 in
1726 let REAL_MUL_RDIV = prove(
1727 `!x y. ~(y = &0) ==> ((x * y) / y = x)`,
1728 SIMP_TAC[real_div; GSYM REAL_MUL_ASSOC; REAL_MUL_RINV; REAL_MUL_RID]
1730 let REAL_MUL_DIV_ASSOC = prove(
1731 `!x y z.((x * z) / y = x * (z / y))`,
1732 SIMP_TAC [real_div;GSYM REAL_MUL_ASSOC]
1734 let IS_INT_FACT_DIV = prove(
1735 `! n m. n >= m ==> integer ( (&(FACT n))/(&(FACT m)) )`,
1736 let lem0 = SPEC_ALL (ONCE_REWRITE_RULE [GSYM (SPECL [`FACT n`;`0`] REAL_OF_NUM_EQ)] FACT_NZ) in
1737 let lem1 = SPECL [`&(SUC n)`;`&(FACT n)`] REAL_MUL_RDIV in
1738 let lem2 = MP lem1 lem0 in
1739 let lem4 = ASSUME `! m. n >= m ==> integer (&(FACT n)/ &(FACT m))` in
1740 let lem5 = UNDISCH (SPEC_ALL lem4) in
1741 let lem6 = prove(`integer(&(SUC n))`,SIMP_TAC [N_IS_INT]) in
1742 let lem7 = CONJ lem6 lem5 in
1743 let lem8 = MATCH_MP INTEGER_MUL lem7 in
1744 let lem9 = UNDISCH_ALL (ARITH_RULE `(~(n >= m)) ==> (SUC n >= m) ==> m = SUC n`) in
1746 [ (SIMP_TAC [ARITH_RULE `0 >= m ==> m = 0`;FACT_NZ;REAL_OF_NUM_EQ;REAL_DIV_REFL;N_IS_INT]);
1747 (STRIP_TAC) THEN (ASM_CASES_TAC `(n:num) >= m`) THENL
1748 [ (ASM_SIMP_TAC [FACT;GSYM REAL_OF_NUM_MUL;lem2;N_IS_INT]) THEN
1749 (SIMP_TAC [FACT;GSYM REAL_OF_NUM_MUL;REAL_MUL_DIV_ASSOC;lem8]);
1751 (SIMP_TAC [lem9;FACT_NZ;REAL_OF_NUM_EQ;REAL_DIV_REFL;N_IS_INT])
1755 let SATURDAY_LEMMA = prove(
1756 `!x. p > 1 ==> m >= p ==> x * ((&(FACT m))/(&(FACT (p-1)))) = x * (&p) * ((&(FACT m))/(&(FACT p)))`,
1757 let lem01 = UNDISCH (ARITH_RULE `p > 1 ==> SUC (p -1) = p`) in
1758 let lem02 = ADD_ASSUM `p > 1` (SPEC `p - 1` (CONJUNCT2 FACT)) in
1759 let lem03 = GSYM (ONCE_REWRITE_RULE [lem01] lem02) in
1760 let lem04 = SPEC `&p` REAL_DIV_REFL in
1761 let lem05 = ADD_ASSUM `p > 1` (SPECL [`p:num`;`0`] REAL_OF_NUM_EQ) in
1762 let lem06 = SIMP_RULE [UNDISCH (ARITH_RULE `p > 1 ==> ~(p = 0)`)] lem05 in
1763 let lem07 = GSYM (MP lem04 lem06) in
1764 (REPEAT STRIP_TAC) THEN
1765 (CONV_TAC (RATOR_CONV (ONCE_REWRITE_CONV [GSYM REAL_MUL_LID]))) THEN
1766 (ONCE_REWRITE_TAC [lem07]) THEN
1767 (ONCE_REWRITE_TAC [real_div]) THEN
1768 (ONCE_REWRITE_TAC [REAL_ARITH `((x1:real) * x2) * x * (x3 * x4) = x * x1 * (x3 * (x2 * x4))`]) THEN
1769 (ONCE_REWRITE_TAC [GSYM REAL_INV_MUL]) THEN
1770 (ONCE_REWRITE_TAC [REAL_OF_NUM_MUL]) THEN
1771 (SIMP_TAC [REAL_MUL_ASSOC;GSYM REAL_INV_MUL]) THEN
1772 (ONCE_REWRITE_TAC [lem03]) THEN
1773 (SIMP_TAC [REAL_MUL_ASSOC;GSYM REAL_OF_NUM_MUL])
1775 let SHRIVER = prove(
1776 `!f0. (!i. m <= i /\ i <= SUC n ==> (f0 i))
1777 ==> (!i. m <= i /\ i <= n ==> (f0 i)) `,
1778 let lem01 = UNDISCH_ALL (ARITH_RULE `i <= n ==> i <= SUC n`) in
1779 let lem02 = CONJ (ASSUME `(m:num) <= (i:num)`) lem01 in
1780 let lem03 = ASSUME `!i. m <= i /\ i <= SUC n ==> (f0 i)` in
1781 let lem04 = SPEC_ALL lem03 in
1782 let lem05 = MP lem04 lem02 in
1783 (REPEAT STRIP_TAC) THEN (ACCEPT_TAC lem05)
1785 let IS_INT_SUM = prove(
1786 `!f n m.(!i.m <= i /\ i <= n ==> integer (f i)) ==> integer (sum (m..n) f)`,
1787 let l0 = SPECL [`m:num`;`n:num`;`i:num`] IN_NUMSEG in
1788 let l1 = SPECL [`m:num`;`SUC n`] NUMSEG_EMPTY in
1789 let l2 = ADD_ASSUM `SUC n < m` l1 in
1790 let l3 = ASM_REWRITE_RULE [] l2 in
1791 let l4 = (UNDISCH o ARITH_RULE) `~(SUC n < m) ==> m <= SUC n` in
1792 let l5 = ONCE_REWRITE_RULE [GSYM IN_NUMSEG] SHRIVER in
1793 let l6 = SPEC `\(i:num).(integer (f i))` l5 in
1794 let l7 = BETA_RULE l6 in
1795 let l8 = ASSUME `! m. (!i. i IN m..n ==> integer (f i)) ==> integer (sum (m..n) f)` in
1796 let l9 = SPEC_ALL l8 in
1797 let l10 = UNDISCH (IMP_TRANS l7 l9) in
1798 let jj0 = ARITH_RULE `(~(SUC n < m)) ==> m <= SUC n /\ (SUC n) <= SUC n` in
1799 let jj1 = UNDISCH (ONCE_REWRITE_RULE [GSYM IN_NUMSEG] jj0) in
1800 let jj2 = SPEC `SUC n` (ASSUME `!i. i IN m.. SUC n ==> integer (f i)`) in
1801 let jj3 = (MP jj2 jj1) in
1802 let l18 = CONJ l10 jj3 in
1803 let l19 = MATCH_MP INTEGER_ADD l18 in
1804 let l20 = DISCH `!i. i IN m..SUC n ==> integer (f i)` l19 in
1805 let l21 = ASSUME `!i . i = 0 ==> integer (f 0)` in
1806 let l22 = SIMP_RULE [] (SPEC `0` l21) in
1807 (ONCE_REWRITE_TAC [GSYM l0]) THEN STRIP_TAC THEN
1810 (ASM_CASES_TAC `m = 0`) THENL
1811 [ (ASM_SIMP_TAC []) THEN
1812 (ONCE_REWRITE_TAC [NUMSEG_CONV `0..0`]) THEN
1813 (ONCE_REWRITE_TAC [ SUM_SING]) THEN
1814 (SIMP_TAC [IN_SING]) THEN (DISCH_TAC) THEN (SIMP_TAC [l22]);
1815 (ASM_SIMP_TAC [NUMSEG_CLAUSES;SUM_CLAUSES;N_IS_INT])
1817 STRIP_TAC THEN (ASM_CASES_TAC `SUC n < m`) THENL
1818 [ (ASM_SIMP_TAC [l3;SUM_CLAUSES;N_IS_INT]);
1819 (ASM_SIMP_TAC [l4;SUM_CLAUSES_NUMSEG]) THEN
1824 let ALL_IMP_EL = prove(
1825 `! (l:(a)list) i P. (ALL P l) ==> (i < LENGTH l) ==> P (EL i l)`,
1826 SIMP_TAC[GSYM ALL_EL]
1828 let KEY_LEMMA = prove(
1831 ! i . p <= i /\ i <= (LENGTH (As n p) - 1) ==> integer ((&(FACT i)/ &(FACT p)) * (EL i (As n p)))`,
1832 let jem0 = ISPECL [`(As n p)`;`i:num`;`integer`] ALL_IMP_EL in
1833 let jem1 = MP jem0 (UNDISCH (UNDISCH (SPEC_ALL ALL_integer_As))) in
1834 let jem3 = ARITH_RULE `LENGTH (As n p) > 0 ==> ((i < LENGTH (As n p)) <=> i <= LENGTH (As n p) - 1)` in
1835 let jem4 = UNDISCH_ALL ((SPEC_ALL LENGTH_As)) in
1836 let jem5 = UNDISCH (ARITH_RULE `p > 0 ==> (LENGTH (As n p) >= p) ==> (LENGTH (As n p) > 0)`) in
1837 let jem6 = MP jem5 jem4 in
1838 let jem7 = MP jem3 jem6 in
1839 let jem8 = ONCE_REWRITE_RULE [jem7] jem1 in
1840 let kem0 = SPECL [`i:num`;`p:num`] IS_INT_FACT_DIV in
1841 let kem1 = ADD_ASSUM `p <= (i:num)` (ADD_ASSUM `i <= (LENGTH (As n p) - 1)` kem0) in
1842 let kem2 = SIMP_RULE [UNDISCH_ALL (ARITH_RULE `p <= i ==> i <= LENGTH (As n p) -1 ==> i >= p`)] kem1 in
1843 (REPEAT STRIP_TAC) THEN (SIMP_TAC[UNDISCH jem8;kem2;INTEGER_MUL])
1846 let KEY_LEMMA2 = prove(
1850 /\ (&1 / &(FACT ( p - 1))) * (sum (p.. LENGTH (As n p) -1) (\m. EL m (As n p) * &(FACT m))) = (&p) * K0`,
1851 let lem0000 = SPEC `EL m (As n p)` SATURDAY_LEMMA in
1852 let lem1000 = DISCH `m <= LENGTH (As n p) -1` (ADD_ASSUM `m <= LENGTH (As n p) -1` (UNDISCH_ALL lem0000)) in
1853 let lem2000 = DISCH `(m:num) >= p` lem1000 in
1854 let lem3000 = ONCE_REWRITE_RULE [ARITH_RULE `(m:num) >= p <=> p <= m`] lem2000 in
1855 let lem4000 = ONCE_REWRITE_RULE [TAUT `(a ==> b ==> c) <=> ((a /\ b) ==> c)`] (GEN `m:num` lem3000) in
1856 let lem5000 = MATCH_MP SUM_EQ_NUMSEG lem4000 in
1857 let nem2 = SPECL [`\x.(&(FACT x)/ &(FACT p)) * (EL x (As n p))`;`LENGTH (As n p) - 1`;`p:num`] IS_INT_SUM in
1858 let nem3 = BETA_RULE nem2 in
1859 let nem4 = SIMP_RULE [UNDISCH (UNDISCH KEY_LEMMA)] nem3 in
1860 let nem5 = ADD_ASSUM `p > 1` (DISCH `p > 0` nem4) in
1861 let nem6 = SIMP_RULE [(UNDISCH o ARITH_RULE) `(p:num) > 1 ==> p > 0`] nem5 in
1862 STRIP_TAC THEN STRIP_TAC THEN (ONCE_REWRITE_TAC [GSYM SUM_LMUL]) THEN
1863 (BETA_TAC) THEN (ONCE_REWRITE_TAC [real_div]) THEN (ONCE_REWRITE_TAC [REAL_MUL_LID]) THEN
1864 (ONCE_REWRITE_TAC [REAL_ARITH `(x1:real) * x2 * x3 = x2 * (x3 * x1)`]) THEN
1865 (ONCE_REWRITE_TAC [GSYM real_div]) THEN (ONCE_REWRITE_TAC [lem5000]) THEN
1866 (ONCE_REWRITE_TAC [REAL_ARITH `(x1:real) * x2 * x3 = x2 * (x3 * x1)`]) THEN
1867 (ONCE_REWRITE_TAC [SUM_LMUL]) THEN
1868 (EXISTS_TAC `sum (p .. LENGTH (As n p) -1) (\x. &(FACT x) / &(FACT p) * EL x (As n p))`) THEN
1871 let NOT_g_NIL = prove(
1872 `!n p . ~ ((g n p ) = [])`,
1873 SIMP_TAC [Pm_eqn5.PLANETMATH_EQN_5; NOT_CONS_NIL; NOT_POLY_EXP_NIL; NOT_POLY_CMUL_NIL;
1874 NOT_POLY_MUL_NIL;NOT_POLY_MUL_ITER_NIL]
1876 let FACT_DIV_RCANCELS = prove(
1877 `!n x. x / &(FACT n) * &(FACT n) = x`,
1878 MESON_TAC [REAL_ARITH `!x. &0 < x ==> ~(x = &0)`;
1879 REAL_DIV_RMUL;FACT_LT;REAL_OF_NUM_LT]
1882 let PSUM_ITERATE = prove(
1883 `! n m f. psum (m,n) f
1884 = if (n > 0) then (iterate (+) (m..((n+m)-1)) f) else &0`,
1885 let lem01 = ARITH_RULE `~(n+m=0) ==> (SUC n + m) -1 = SUC ((n + m) -1)` in
1886 let lem02 = MP (ISPEC `(+)` ITERATE_SING) MONOIDAL_REAL_ADD in
1888 `iterate (+) (m..SUC ((n + m) - 1)) f
1889 = f (SUC ((n+m)-1)) + iterate (+) (m..(n+m)-1) f`,
1890 MESON_TAC [ARITH_RULE `m <= SUC ((n+m)-1)`;ITERATE_CLAUSES_NUMSEG;
1891 MONOIDAL_REAL_ADD;REAL_ADD_SYM]) in
1892 let lem04 = UNDISCH (UNDISCH (ARITH_RULE `~(n+m=0) ==> n=0 ==> m-1 < m`)) in
1893 let lem05 = SIMP_RULE [lem04] (SPECL [`m:num`;`m-1`] NUMSEG_EMPTY) in
1895 [ SIMP_TAC [ARITH_RULE `~(0 > 0)`;sum_DEF];
1896 (SIMP_TAC [ARITH_RULE `(SUC n) > 0`]) THEN (REPEAT STRIP_TAC) THEN
1897 (ASM_CASES_TAC `n + m =0`) THENL
1898 [ (REWRITE_TAC [UNDISCH (ARITH_RULE `n + m = 0 ==> n = 0`)]) THEN
1899 (REWRITE_TAC [lem02;NUMSEG_SING;ARITH_RULE `(SUC 0 +m) -1 = m`]) THEN
1900 (MESON_TAC [sum_DEF; ADD_CLAUSES;REAL_ARITH `&0 + x = x`]) ;
1901 (ONCE_REWRITE_TAC [sum_DEF;UNDISCH lem01]) THEN
1902 (REWRITE_TAC [lem03]) THEN (ASM_CASES_TAC `n = 0`) THEN
1904 [ARITH_RULE `~(0 > 0)`;ADD_CLAUSES;REAL_ADD_LID;REAL_ADD_RID;
1905 lem05;ITERATE_CLAUSES_GEN; MONOIDAL_REAL_ADD;NEUTRAL_REAL_ADD;
1906 REAL_ADD_SYM;ADD_SYM;ARITH_RULE `~(n=0) ==> n>0 /\ SUC (n-1) = n`])
1912 let PLANETMATH_EQN_5_2 = prove(
1916 /\ poly (SOD (g n p)) (&0) =
1917 &(FACT n) pow p * -- &1 pow (n * p) + &p * K0)`,
1918 let lem01 = SPECL [`g n p`;`x:real`;`(&0):real`] Pm_lemma2.PLANETMATH_LEMMA_2_B in
1919 let lem02 = GEN_ALL lem01 in
1920 let lem03 = SPEC_ALL (BETA_RULE lem02) in
1921 let lem04 = SIMP_RULE [FACT_DIV_RCANCELS] lem03 in
1922 let lem05 = SIMP_RULE [PSUM_ITERATE] lem04 in
1923 let lem06 = SIMP_RULE [ARITH_RULE `(n:num) + 0 = n`] lem05 in
1924 let lem07 = ADD_ASSUM `n > 0` (ADD_ASSUM `p > 0` lem06) in
1925 let lem08 = REWRITE_RULE [GSYM LENGTH_EQ_NIL;ARITH_RULE `~(x = 0) <=> x > 0`] NOT_g_NIL in
1926 let lem09 = SIMP_RULE [lem08] lem07 in
1927 let lem10 = CONV_RULE (RAND_CONV (REWRITE_CONV [UNDISCH_ALL (SPEC_ALL g_eq_As)])) lem09 in
1928 let lem11 = SIMP_RULE [POLY_CMUL_LENGTH] lem10 in
1929 let lem12 = SPECL [`m:num`;`(As n p)`] EL_PDI_AT_ZERO in
1930 let lem13 = SIMP_RULE [POLY_CMUL_PDI;POLY_CMUL;lem12] lem11 in
1931 let lem14 = GSYM (BETA `(\m. poly (poly_diff_iter (As n p) m) (&0)) m`) in
1932 let lem15 = ISPECL [`(\m. poly (poly_diff_iter (As n p) m) (&0))`;`&1/ &(FACT (p - 1))`;`0..LENGTH (As n p) -1`] SUM_LMUL in
1933 let lem16 = ONCE_REWRITE_RULE [lem14] lem13 in
1934 let lem17 = ONCE_REWRITE_RULE [GSYM sum] lem16 in
1935 let lem18 = SIMP_RULE [GSYM lem17] lem15 in
1936 let lem20 = SPECL [`(\m. poly (poly_diff_iter (As n p) m) (&0))`;`(\m. EL m (As n p) * &(FACT m))`;`0`;`LENGTH (As n p) - 1`] SUM_EQ_NUMSEG in
1937 let lem21 = ONCE_REWRITE_RULE [ARITH_RULE `0 <= i`] (BETA_RULE lem20) in
1938 let lem22 = ADD_ASSUM `~(As n p = [])` (ONCE_REWRITE_RULE [EL_PDI_AT_ZERO2] lem21) in
1939 let lem30 = SPECL [`i:num`;`As n p`] EL_PDI_AT_ZERO2 in
1940 let lem31 = ASM_REWRITE_RULE [] (ADD_ASSUM `~(As n p = [])` lem30) in
1941 let lem23 = ONCE_REWRITE_RULE [lem31] lem22 in
1942 let lem24 = REWRITE_RULE [GSYM lem16] lem23 in
1943 let lem25 = ONCE_REWRITE_RULE [lem24] lem18 in
1944 let lem30 = ISPECL [`\m. EL m (As n p) * &(FACT m)`;`0`;`p-1`;`(LENGTH (As n p) - 1) - (p - 1)`] SUM_ADD_SPLIT in
1945 let lem31 = SIMP_RULE [ARITH_RULE `0 <= x`] lem30 in
1946 let lem32 = UNDISCH_ALL (ARITH_RULE `! x. x >= p ==> (p - 1) + (x - 1) - (p -1)= x - 1`) in
1947 let lem33 = UNDISCH_ALL (SPEC_ALL LENGTH_As) in
1948 let lem34 = SPEC `LENGTH (As n p)` lem32 in
1949 let lem35 = MP lem34 lem33 in
1950 let lem36 = ONCE_REWRITE_RULE [UNDISCH (ARITH_RULE `p > 1 ==> (p - 1) + 1 = p`);lem35] lem31 in
1951 let lem37 = ONCE_REWRITE_RULE [lem36] lem25 in
1952 let lem38 = SIMP_RULE [UNDISCH (ARITH_RULE `p > 1 ==> p > 0`)] (DISCH `p > 0` lem37) in
1953 let lem39 = ISPECL [`\m. EL m (As n p) * &(FACT m)`;`0`;`p-2`;`1`] SUM_ADD_SPLIT in
1954 let lem40 = ADD_ASSUM `n > 0` (ADD_ASSUM `p > 1` lem39) in
1955 let lem41 = SIMP_RULE (map (UNDISCH o ARITH_RULE) [`p > 1 ==> p - 2 + 1 = p-1`;`p > 1 ==> (p - 2) + 1 = p - 1`]) lem40 in
1956 let lem42 = SIMP_RULE [SUM_SING_NUMSEG;ARITH_RULE `0 <= x`] lem41 in
1957 let lem45 = ADD_ASSUM `p > 1` (SPEC_ALL prefix_As_zero) in
1958 let lem46 = SIMP_RULE [UNDISCH_ALL (ARITH_RULE `p > 1 ==> p > 0`)] lem45 in
1959 let lem47 = UNDISCH (ONCE_REWRITE_RULE [UNDISCH_ALL (ARITH_RULE `p > 1 ==> (i < p-1 <=> i <= p-2)`)] lem46) in
1960 let lem48 = SIMP_RULE [REAL_ARITH `((&0):real) + x = x`; SUM_EQ_0_NUMSEG;REAL_ARITH `((&0):real) * x = &0`;lem47] lem42 in
1961 let lem49 = SIMP_RULE [UNDISCH (ARITH_RULE `p > 1 ==> p > 0`)] (ADD_ASSUM `p > 1` (SPEC_ALL fact_As)) in
1962 let lem50 = SIMP_RULE [UNDISCH lem49] lem48 in
1963 let lem51 = ONCE_REWRITE_RULE [lem50] lem38 in
1964 let lem52 = SPECL [`p - 1`;`(&1):real`] FACT_DIV_RCANCELS in
1965 let lem53 = SIMP_RULE [REAL_ARITH `(x:real) * (y * z) = (x * z) * y`;lem52;REAL_ARITH `(x:real) * (y + z) = (x * y) + (x * z)`] lem51 in
1966 let lem54 = SIMP_RULE [REAL_ARITH `&1 * x = (x:real)`] lem53 in
1967 let josh0 = UNDISCH_ALL KEY_LEMMA2 in
1968 let josh1 = REAL_ARITH `!(y:real) x1 x2 . x1 = x2 <=> y + x1 = y + x2` in
1969 let josh2 = SPEC `(&(FACT n) pow p * -- &1 pow (n * p)):real` josh1 in
1970 let josh3 = ONCE_REWRITE_RULE [josh2] josh0 in
1971 let josh4 = ONCE_REWRITE_RULE [GSYM lem54] josh3 in
1972 let josh5 = DISCH `~ (As n p = [])` josh4 in
1973 let jem4 = ADD_ASSUM `p > 1` ((SPEC_ALL LENGTH_As)) in
1974 (* JOHN: the UNDISCH here is necessary... i don't think it should be *)
1975 let jem5 = UNDISCH (SIMP_RULE [UNDISCH (ARITH_RULE `(p:num) > 1 ==> p > 0`)] jem4) in
1976 let jem6 = UNDISCH (ARITH_RULE `p > 1 ==> (LENGTH (As n p) >= p) ==> ~((LENGTH (As n p) = 0))`) in
1977 let jem7 = MP jem6 jem5 in
1978 let jem8 = SIMP_RULE [LENGTH_EQ_NIL] jem7 in
1979 let josh6 = MP josh5 jem8 in
1980 let josh7 = DISCH_ALL josh6 in
1981 let josh11 = ONCE_REWRITE_RULE [GSYM OLD_SUM] lem17 in
1982 let josh12 = REWRITE_RULE [GSYM josh11] josh7 in
1983 let josh13 = SIMP_RULE [] (DISCH_ALL josh12) in
1984 let josh14 = BRW `(X ==> Y ==> Z ==> W) <=> ((X /\ Y /\ Z) ==> W)` josh13 in
1985 let josh15 = ONCE_REWRITE_RULE [ARITH_RULE `(p > 0 /\ n > 0 /\ p > 1) <=> (p > 1 /\ n > 0)`] (DISCH_ALL josh14) in
1986 let josh16 = BRW1 josh15 in
1987 let josh17 = SIMP_RULE [PSUM_ITERATE;ARITH_RULE `~(0 > 0)`] josh16 in
1990 let PLANETMATH_DIVIDES_FACT_PRIME_1 = prove (
1991 `!p n. (prime p) /\ p > n ==> ~(num_divides p (FACT n))`,
1992 (SIMP_TAC [DIVIDES_FACT_PRIME]) THEN ARITH_TAC
1994 let INT_OF_REAL_NEG_NUM = prove(
1995 `!(n:num).int_of_real (-- (real_of_num n)) = -- (int_of_real (real_of_num n))`,
1996 SIMP_TAC [GSYM int_of_num;GSYM int_of_num_th;GSYM int_neg]
1998 let ABS_EQ_ONE = prove(
1999 `!(x:real) .((abs x) = &1) ==> ((x = &1) \/ (x = -- &1))`,
2002 let POW_NEG_1 = prove(
2003 `!(x:num). (((-- (&1 :real)) pow x) = -- &1) \/ (((-- (&1 : real)) pow x) = &1)`,
2004 let lem00 = ONCE_REWRITE_RULE [TAUT `x \/ y <=> y \/ x`] ABS_EQ_ONE in
2005 let lem01 = (SPEC `(-- (&1 :real)) pow x` lem00) in
2006 let lem02 = (SPEC `x:num` POW_M1) in
2007 let lem03 = MP lem01 lem02 in
2008 STRIP_TAC THEN (ACCEPT_TAC lem03)
2010 let NUM_DIVIDES_INT_DIVIDES = prove(
2011 `!(x:num) (y:num).(x divides y) <=> ((&x):int divides ((&y):int))`,
2012 (ONCE_REWRITE_TAC [num_divides]) THEN (SIMP_TAC [])
2014 let SON_OF_A_GUN = prove(
2015 `! (p:num) (n:num) .
2018 ==> ~(int_divides (& p) (&(FACT n) pow p * -- &1 pow (n * p) ))`,
2019 let POW_INT_NEG_1 = INT_OF_REAL_THM POW_NEG_1 in
2020 let lem0000 = TAUT `(A /\ B ==> C) <=> (A ==> B ==> C)` in
2021 let lem0001 = ONCE_REWRITE_RULE [lem0000] PLANETMATH_DIVIDES_FACT_PRIME_1 in
2022 let lem0002 = UNDISCH_ALL (SPEC_ALL lem0001) in
2023 let lem0008 = ONCE_REWRITE_RULE [TAUT `(x /\ y ==> z) <=> (x ==> ~z ==> ~y)`] PRIME_DIVEXP in
2024 let lem0009 = SPECL [`p:num`;`p:num`;`FACT n`] lem0008 in
2025 let lem0010 = UNDISCH lem0009 in
2026 let lem0011 = MP lem0010 lem0002 in
2027 STRIP_TAC THEN STRIP_TAC THEN STRIP_TAC THEN STRIP_TAC THEN
2028 (DISJ_CASES_TAC (SPEC `(n * p):num` POW_INT_NEG_1)) THENL
2029 [ (ASM_SIMP_TAC [INT_OF_NUM_POW; ARITH_RULE `x * (--(&1):int) = -- x`;ARITH_RULE `x * ((&1):int) = x`]) THEN
2030 (ONCE_REWRITE_TAC [GSYM INT_DIVIDES_RNEG]) THEN
2031 (ONCE_REWRITE_TAC [ARITH_RULE `-- -- (x:int) = x`]) THEN
2032 (ONCE_REWRITE_TAC [GSYM NUM_DIVIDES_INT_DIVIDES]) THEN
2033 (ACCEPT_TAC lem0011);
2034 (ASM_SIMP_TAC [INT_OF_NUM_POW; ARITH_RULE `x * (--(&1):int) = -- x`;ARITH_RULE `x * ((&1):int) = x`]) THEN
2035 (ONCE_REWRITE_TAC [GSYM NUM_DIVIDES_INT_DIVIDES]) THEN
2036 (ACCEPT_TAC lem0011)
2039 let MAY_LEMMA = prove(
2042 ==> ~(int_divides (& p) ((int_of_num (FACT n)) pow p * -- &1 pow (n * p) + &p * K0))`,
2043 let lem00 = BRW `(x /\ y ==> z) <=> (x ==> ~z ==> ~y)` INT_DIVIDES_ADD_REVR in
2044 let lem0 = prove(`int_divides ((&p):int) (&p * K0)`,INTEGER_TAC) in
2045 let lem1 = (UNDISCH_ALL o SPEC_ALL) SON_OF_A_GUN in
2046 let lem2 = SPECL [`(&p):int`;`((&p):int) * K0`; `(&(FACT n) pow p):int *
2047 -- &1 pow (n * p)` ] lem00 in
2048 let lem3 = MP (MP lem2 lem0) lem1 in
2049 let lem4 = (DISCH_ALL lem3) in
2050 let lem5 = ONCE_REWRITE_RULE [ARITH_RULE `(x:int) + y = y + x`] lem4 in
2053 let PLANET_MATH_alpha_1 = prove(
2054 `n > 0 ==> p > n ==> prime p ==> (integer (poly (SOD (g n p )) (&0)))`,
2055 let a1 = UNDISCH (UNDISCH (ARITH_RULE `n > 0 ==> p > n ==> p > 1`)) in
2056 let a2 = UNDISCH (SIMP_RULE [] (DISCH `n > 0` (MP PLANETMATH_EQN_5_2 a1))) in
2057 let t1 = `integer K0 /\
2058 poly (SOD (g n p)) (&0) =
2059 &(FACT n) pow p * -- &1 pow (n * p) + &p * K0` in
2060 (STRIP_TAC THEN STRIP_TAC THEN STRIP_TAC) THEN (CHOOSE_TAC a2) THEN
2061 (SPLIT_CONJOINED_ASSUMPT_TAC t1) THEN (ASM_REWRITE_TAC[]) THEN
2062 (ASM_SIMP_TAC [N_IS_INT;INTEGER_ADD;NEG_N_IS_INT;INTEGER_POW;INTEGER_MUL])
2064 let PLANET_MATH_alpha_2 = prove(
2065 `n > 0 ==> p > n ==> prime p ==>
2066 ( ~((&p) divides (int_of_real (poly (SOD (g n p )) (&0)))))`,
2067 let t1 = `integer K0 /\
2068 poly (SOD (g n p)) (&0) =
2069 &(FACT n) pow p * -- &1 pow (n * p) + &p * K0` in
2070 let t = `((real_of_num (FACT n)) pow p) * (-- &1 pow (n * p)) + (&p * K0)` in
2071 let arch0 = INT_OF_REAL_CONV t in
2072 let a1 = UNDISCH (UNDISCH (ARITH_RULE `n > 0 ==> p > n ==> p > 1`)) in
2073 let a2 = UNDISCH (SIMP_RULE [] (DISCH `n > 0` (MP PLANETMATH_EQN_5_2 a1))) in
2074 let a3 = SPEC `int_of_real K0` (GEN `K0:int` MAY_LEMMA) in
2075 let a4 = GSYM (UNDISCH arch0) in
2076 let a5 = ONCE_REWRITE_RULE [a4] a3 in
2077 STRIP_TAC THEN STRIP_TAC THEN STRIP_TAC THEN (CHOOSE_TAC a2) THEN
2078 (SPLIT_CONJOINED_ASSUMPT_TAC t1) THEN (ASM_SIMP_TAC [a5])
2080 let INT_OF_REAL_NEG_INT_OF_NUM = prove(
2081 `!n. int_of_real(-- (real_of_num n)) = -- int_of_num n`,
2082 SIMP_TAC [int_of_num;INT_OF_REAL_NEG_NUM]
2084 let PLANET_MATH_alpha_3 = prove(
2085 `n > 0 ==> p > n ==> prime p ==>
2086 (~((poly (SOD (g n p)) (&0)) = &0))`,
2091 (~(&x divides (int_of_real y))) ==>
2093 MESON_TAC [is_int;INT_OF_NUM_GT;INT_DIVIDES_RNEG;REAL_OF_NUM_EQ;int_of_num;INT_OF_REAL_NEG_INT_OF_NUM;INT_OF_NUM_EQ;INT_DIVIDES_0]) in
2094 let lem1 = ARITH_RULE `n > 0 ==> p > n ==> p > 0` in
2095 MESON_TAC [lem0;lem1; PLANET_MATH_alpha_1; PLANET_MATH_alpha_2]
2097 let PLANET_MATH_alpha = prove(
2098 `n > 0 ==> p > n ==> prime p ==>
2099 ( (integer (poly (SOD (g n p )) (&0)))
2100 /\ ~((&p) divides (int_of_real (poly (SOD (g n p )) (&0))))
2101 /\ ~((poly (SOD (g n p)) (&0)) = &0))`,
2102 SIMP_TAC [PLANET_MATH_alpha_1; PLANET_MATH_alpha_2; PLANET_MATH_alpha_3]
2104 let REAL_FACT_NZ = prove(
2105 `~((&(FACT n)) = (real_of_num 0))`,
2106 let l0 = GSYM (SPECL [`FACT n`;`0`] REAL_OF_NUM_EQ) in
2107 ACCEPT_TAC (SPEC_ALL (ONCE_REWRITE_RULE [l0] FACT_NZ))
2110 let IS_INT_FACT_DIV_FACT_DIV_FACT = prove(
2111 `! i k.integer ((&(FACT (i+k)))/(&(FACT i))/(&(FACT k)))`,
2112 let l0 = MATCH_MP (ARITH_RULE `(~(x=0)) ==> 0 < x`) (SPEC `k:num` FACT_NZ) in
2113 let l1 = ONCE_REWRITE_RULE [GSYM REAL_OF_NUM_LT] l0 in
2114 let l2 = MATCH_MP REAL_EQ_LDIV_EQ l1 in
2115 (REPEAT STRIP_TAC) THEN (REWRITE_TAC [is_int;l2]) THEN
2116 (EXISTS_TAC ` (binom(i+k,k))`) THEN DISJ1_TAC THEN
2117 (MESON_TAC [BINOM_FACT;MULT_SYM;MULT_ASSOC;REAL_OF_NUM_MUL;REAL_OF_NUM_EQ])
2120 (* if you replace the second SIMP_TAC with MESON_TAC, it fails!!
2121 * (i alwasy thought MESON_TAC was strictly stronger than SIMP_TAC
2123 let POLY_CMUL_EL = prove(
2124 `!p c i.(i < (LENGTH p)) ==> (EL i (c ## p)) = c * (EL i p)`,
2125 let l0 = ARITH_RULE `(SUC i) < (SUC j) <=> i < j` in
2126 LIST_INDUCT_TAC THENL
2127 [ (SIMP_TAC [LENGTH;ARITH_RULE `~(n < (0:num))`]);
2128 STRIP_TAC THEN INDUCT_TAC THENL
2129 [ (SIMP_TAC [poly_cmul;HD;EL]);
2130 (ASM_SIMP_TAC [LENGTH;poly_cmul;TL;EL;l0])
2134 let PDI_COEFF_FACT = prove(
2135 `! k q i.(i < LENGTH (poly_diff_iter q k)) ==>
2136 (EL i (poly_diff_iter q k)) = ((&(FACT (i+k)))/(&(FACT i))) * (EL (i+k) q)`,
2137 let t0 = `!q i. i < LENGTH (poly_diff_iter q k)
2138 ==> EL i (poly_diff_iter q k) = &(FACT (i + k)) / &(FACT i) * EL (i + k) q` in
2139 let l0 = SPECL [`q:(real)list`;`SUC i`] ( ASSUME t0) in
2140 let l1 = ONCE_REWRITE_RULE [ARITH_RULE `(SUC i) < x <=> i < (PRE x)`] l0 in
2141 let l2 = ONCE_REWRITE_RULE [GSYM LENGTH_POLY_DIFF] l1 in
2142 let l3 = ONCE_REWRITE_RULE [FACT;GSYM REAL_OF_NUM_MUL] l2 in
2143 let l4 = ONCE_REWRITE_RULE [GSYM REAL_OF_NUM_MUL] l3 in
2144 let l5 = REWRITE_RULE [real_div;REAL_INV_MUL] l4 in
2145 let l6 = REAL_ARITH `(w * (inv x) * y ) * z = (w * y * z) * (inv x)` in
2146 let l9 = ONCE_REWRITE_RULE [GSYM REAL_OF_NUM_LT] (ARITH_RULE `0 < SUC i`) in
2147 let l10 = MATCH_MP REAL_EQ_RDIV_EQ l9 in
2148 let l11 = ONCE_REWRITE_RULE [l6] l5 in
2149 let l12 = ONCE_REWRITE_RULE [real_div] l10 in
2150 let l13 = ONCE_REWRITE_RULE [l12] l11 in
2152 [ (REWRITE_TAC [Pm_lemma1.PDI_DEF;ARITH_RULE `i + 0 = i`]) THEN
2153 (MESON_TAC [REAL_DIV_REFL;FACT_NZ;REAL_OF_NUM_EQ;REAL_ARITH `(real_of_num 1) * x = x`]);
2154 (ONCE_REWRITE_TAC [Pm_lemma1.PDI_DEF]) THEN (SIMP_TAC [EL_POLY_DIFF]) THEN
2155 (ONCE_REWRITE_TAC [ARITH_RULE `i + (SUC k) = (SUC i) + k`]) THEN
2156 (ONCE_REWRITE_TAC [FACT]) THEN (ONCE_REWRITE_TAC [real_div]) THEN
2157 (SIMP_TAC [l13;real_div;REAL_MUL_ASSOC])
2160 (* I think this should hold if we replace [--a;&1] with an arbitrary polynomial q,
2161 * however the existing ORDER* theorems would not be sufficient to prove it and
2162 * I don't feel like putting in the effort right now
2164 let POLY_DIVIDES_POLY_DIFF = prove(
2166 (poly_divides (poly_exp [--a;&1] (SUC n)) p)
2167 ==> (poly_divides (poly_exp [--a;&1] n) (poly_diff p))`,
2168 let l0 = ARITH_RULE `op = SUC odp ==> SUC n <= op ==> n <= odp` in
2169 let l1 = ARITH_RULE `(SUC n <= m ) ==> ~(m = 0)` in
2170 MESON_TAC [l0;l1;POLY_DIFF_ZERO;ORDER_DIVIDES;ORDER_DIFF]
2172 let POLY_DIVIDES_MUL = prove(
2173 `!p1 p2 p3.poly_divides p1 p2 ==> poly_divides p1 (p2 ** p3)`,
2174 (ONCE_REWRITE_TAC [divides]) THEN (REPEAT STRIP_TAC) THEN
2175 (EXISTS_TAC `q ** p3`) THEN
2176 (ASM_MESON_TAC [FUN_EQ_THM;POLY_MUL;POLY_MUL_ASSOC])
2178 let POLY_DIVIDES_MUL3 = prove(
2179 `!p1 p2 p3.(poly_divides p1 p2) ==> (poly_divides p1 (p3 ** p2))`,
2180 (ONCE_REWRITE_TAC [divides]) THEN (REPEAT STRIP_TAC) THEN
2181 (EXISTS_TAC `p3 ** q`) THEN (UNDISCH_TAC `poly (p2) = poly (p1 ** q)`) THEN
2182 (ONCE_REWRITE_TAC [FUN_EQ_THM]) THEN (REWRITE_TAC [POLY_MUL]) THEN
2183 (MESON_TAC [REAL_MUL_ASSOC;REAL_MUL_SYM])
2185 let POLY_DIVIDES_POLY_MUL_ITER = prove(
2186 `!f n v. 1 <= v ==> v <= n ==> poly_divides (f v) (poly_mul_iter f n)`,
2187 let l1 = ARITH_RULE `~(v <= n) ==> (v <= SUC n) ==> v = SUC n` in
2188 let l2 = UNDISCH (UNDISCH l1) in
2189 STRIP_TAC THEN INDUCT_TAC THENL
2191 (ONCE_REWRITE_TAC [Pm_eqn5.POLY_MUL_ITER]) THEN STRIP_TAC THEN
2192 (ASM_CASES_TAC `v <= (n:num)`) THENL
2193 [ ASM_MESON_TAC [POLY_DIVIDES_MUL3];
2194 STRIP_TAC THEN STRIP_TAC THEN
2195 (MESON_TAC [l2;POLY_DIVIDES_MUL;POLY_DIVIDES_REFL]) ]
2199 * This one was suprisingly tricky to prove...
2201 let POLY_DIVIDES_POLY_EXP2 = prove(
2202 `!n p1 p2.(poly_divides p1 p2) ==> poly_divides (poly_exp p1 n) (poly_exp p2 n)`,
2204 (?q. poly p2 = poly (p1 ** q))
2205 ==> (?q. poly (poly_exp p2 n) = poly (poly_exp p1 n ** q))` in
2206 let l0 = ASSUME t0 in
2207 let l1 = UNDISCH (REWRITE_RULE [divides] (SPEC_ALL l0)) in
2209 `(x2 = x5 * x6 /\ x1 = x4 * x7) ==> (x1:real) * x2 = (x4 * x5) * x6 * x7`,
2210 MESON_TAC [REAL_MUL_SYM;REAL_MUL_ASSOC]) in
2211 (ONCE_REWRITE_TAC [divides]) THEN INDUCT_TAC THENL
2212 [ (MESON_TAC [divides;poly_exp;POLY_DIVIDES_REFL]);
2213 (STRIP_TAC THEN STRIP_TAC THEN DISCH_TAC) THEN (CHOOSE_TAC l1) THEN
2214 (UNDISCH_TAC `?q. poly p2 = poly (p1 ** q)`) THEN STRIP_TAC THEN
2215 (ONCE_REWRITE_TAC [poly_exp]) THEN (EXISTS_TAC `q ** q'`) THEN
2216 (REWRITE_TAC [poly_exp;FUN_EQ_THM;POLY_MUL]) THEN
2217 (ASM_MESON_TAC [l3;FUN_EQ_THM;POLY_MUL])
2220 let POLY_EXP_ONE = prove(
2221 `!p .p = poly_exp p 1`,
2222 MESON_TAC [poly_exp;ARITH_RULE `1 = SUC 0`;POLY_MUL_RID]
2224 let POLY_DIVIDES_ROOT = prove(
2225 `!p a.poly_divides [--a;&1] p ==> (poly p a) = &0`,
2226 MESON_TAC [ORDER_ROOT;ORDER_DIVIDES;POLY_EXP_ONE;
2227 ARITH_RULE `1 <= ord ==> ~(ord = 0)`]
2230 let POLY_DIVIDES_PDI = prove(
2232 (poly_divides (poly_exp [--a;&1] (SUC n)) p)
2233 ==> (poly_divides [--a;&1] (poly_diff_iter p n))`,
2234 let t0 = `!p a. poly_divides (poly_exp [--a; &1] (SUC n)) p
2235 ==> poly_divides [--a; &1] (poly_diff_iter p n)` in
2236 let l0 = ASSUME t0 in
2237 let l1 = SPEC `poly_diff p` l0 in
2238 let l2 = SPECL [`p:(real)list`;`SUC n`;`a:real`] POLY_DIVIDES_POLY_DIFF in
2239 let l3 = UNDISCH l2 in
2240 let l4 = MATCH_MP l1 l3 in
2242 [ (SIMP_TAC [poly_exp;POLY_MUL_RID;Pm_lemma1.PDI_DEF]);
2243 (REPEAT STRIP_TAC) THEN (ASM_MESON_TAC [l4;Pm_lemma1.PDI_DEF;PDI_POLY_DIFF_COMM])
2246 let POLY_DIVIDES_PDI2 = prove(
2249 ==> (poly_divides (poly_exp [--a;&1] m) p)
2250 ==> (poly_divides [--a;&1] (poly_diff_iter p n))`,
2251 MESON_TAC [POLY_EXP_DIVIDES;POLY_DIVIDES_PDI;
2252 ARITH_RULE `m > n <=> (SUC n) <= m`]
2254 let TAIL_GUNNER = prove(
2255 ` x < p ==> 1 <= v ==> v <= n ==>
2256 poly (poly_diff_iter
2257 (poly_exp [&0; &1] (p - 1) **
2258 poly_exp (poly_mul_iter (\i. [-- &i; &1]) n) p)
2262 MESON_TAC [POLY_DIVIDES_ROOT; ARITH_RULE `x < p <=> (p:num) > x`;
2263 POLY_DIVIDES_PDI2; POLY_DIVIDES_MUL3; POLY_DIVIDES_POLY_EXP2;
2264 POLY_DIVIDES_POLY_MUL_ITER]
2267 let IS_INT_POLY = prove(
2268 `!p x.(integer x) ==> (ALL integer p) ==> integer (poly p x)`,
2269 LIST_INDUCT_TAC THEN
2270 (ASM_MESON_TAC [N_IS_INT;ALL;poly;INTEGER_ADD;INTEGER_MUL])
2272 (* surprising the MESON needs so much help with the rewrites here
2273 * (i.e. i though i could just hit it with ASM_MESON_TAC with all four thms
2275 let INV_POLY_CMUL = prove(
2276 `!y x . (~(x = &0)) ==> (x) ## (inv x) ## y = y`,
2277 LIST_INDUCT_TAC THENL
2278 [ ASM_MESON_TAC [poly_cmul];
2279 (REPEAT STRIP_TAC) THEN
2280 (REWRITE_TAC [poly_cmul;REAL_MUL_ASSOC]) THEN
2281 (ASM_MESON_TAC [REAL_MUL_RINV;REAL_MUL_LID])
2284 let INV_POLY_CMUL2 = prove(
2285 `!y x . (~(x = &0)) ==> (inv x) ## (x) ## y = y`,
2286 MESON_TAC [INV_POLY_CMUL;REAL_INV_INV;REAL_INV_EQ_0]
2288 (* the final ASM_MESON_TAC fails if poly_cmul is rolled into the thm list *)
2289 let POLY_CMUL_EQUALS = prove(
2290 `!z x y. (~(z = &0)) ==> ((x = y) <=> (z ## x = z ## y))`,
2291 (REPEAT STRIP_TAC) THEN EQ_TAC THENL
2293 (SPEC_TAC (`x:(real)list`,`x:(real)list`)) THEN
2294 (SPEC_TAC (`y:(real)list`,`y:(real)list`)) THEN
2295 (LIST_INDUCT_TAC) THENL
2296 [ LIST_INDUCT_TAC THENL
2297 [ (SIMP_TAC [POLY_CMUL_CLAUSES]);
2298 (ASM_MESON_TAC [POLY_CMUL_CLAUSES;NOT_CONS_NIL])];
2299 LIST_INDUCT_TAC THENL [
2300 (ASM_MESON_TAC [POLY_CMUL_CLAUSES;NOT_CONS_NIL]);
2301 (ONCE_REWRITE_TAC [poly_cmul]) THEN
2302 (ASM_MESON_TAC [REAL_EQ_LCANCEL_IMP;CONS_11])]
2306 let PDI_LENGTH_THM = prove(
2307 `!f n. LENGTH(poly_diff_iter f n) = (LENGTH f) - n`,
2308 STRIP_TAC THEN INDUCT_TAC THENL
2309 [ (SIMP_TAC [Pm_lemma1.PDI_DEF;ARITH_RULE `(x:num) - 0 = x`]);
2310 (ONCE_REWRITE_TAC [Pm_lemma1.PDI_DEF]) THEN
2311 (ONCE_REWRITE_TAC [LENGTH_POLY_DIFF]) THEN ASM_ARITH_TAC ]
2313 let CAPTAINS_CLOTHES = prove(
2316 ? r .(ALL integer r) /\ r = (inv (&(FACT k))) ## (poly_diff_iter q k)`
2318 let e0 = `(inv (&(FACT k))) ## (poly_diff_iter q k)` in
2319 let l1 = ONCE_REWRITE_RULE [GSYM (SPEC `inv (&(FACT k))` POLY_CMUL_LENGTH)]
2321 let l2 = UNDISCH (SPEC_ALL l1) in
2322 let l3 = prove(`i < LENGTH( inv (&(FACT k)) ## poly_diff_iter q k)
2323 ==> (i + k) < LENGTH q`,
2324 MESON_TAC [PDI_LENGTH_THM;POLY_CMUL_LENGTH;
2325 ARITH_RULE `(i:num) < f -k ==> (i+k) < f`]) in
2326 (REPEAT STRIP_TAC) THEN (EXISTS_TAC e0) THEN (SIMP_TAC []) THEN
2327 (ASM_SIMP_TAC [ONCE_REWRITE_RULE [GSYM POLY_CMUL_LENGTH] POLY_CMUL_EL]) THEN
2328 (ONCE_REWRITE_TAC [GSYM ALL_EL]) THEN (REPEAT STRIP_TAC) THEN
2329 (ASM_SIMP_TAC [ONCE_REWRITE_RULE [GSYM POLY_CMUL_LENGTH] POLY_CMUL_EL]) THEN
2330 (ONCE_REWRITE_TAC [l2]) THEN (ONCE_REWRITE_TAC [REAL_MUL_ASSOC]) THEN
2331 (MATCH_MP_TAC INTEGER_MUL) THEN STRIP_TAC THENL
2332 [ (MESON_TAC [IS_INT_FACT_DIV_FACT_DIV_FACT;REAL_MUL_SYM;real_div;REAL_MUL_ASSOC]);
2333 (ASM_MESON_TAC [l3;ALL_IMP_EL]) ]
2335 let MESSY_JESSE2 = prove(
2336 `n > 0 ==> p > n ==>
2337 (? (Bs:num->num->real). ! v .
2338 (1 <= v) ==> (v <= n) ==>
2339 ( (! i . (integer (Bs v i)))
2340 /\ (poly (SOD (g n p)) (&v)) =
2341 ((real_of_num 1) / (&(FACT (p - 1)))) *
2342 (psum (0,LENGTH (g n p))
2343 (\i. (&(FACT i)) * (Bs v i)))
2344 /\ (! i. (i < p) ==> (Bs v i) = &0) ))`,
2345 let root_canal = REAL_ARITH `(x:real) * (&0) = &0` in
2346 let bs = `\(v:num) . \(x:num).
2347 if (x <= (LENGTH (g n p)) ) then
2349 ((inv (&(FACT x))) ##
2351 (poly_exp [&0; &1] (p - 1) **
2352 poly_exp (poly_mul_iter (\i. [-- &i; &1]) n) p)
2356 let l0 = prove(`ALL integer [&0;&1]`,MESON_TAC [ALL;N_IS_INT]) in
2357 let t0 = `(poly_exp [&0; &1] (p - 1) **
2358 poly_exp (poly_mul_iter (\i. [-- &i; &1]) n) p)` in
2359 let l2 = SPECL [`i:num`;t0] CAPTAINS_CLOTHES in
2360 let l3 = prove(`ALL integer (poly_exp [&0; &1] (p - 1) ** poly_exp (poly_mul_iter (\i. [-- &i; &1]) n) p)`,MESON_TAC[l0;ALL_IS_INT_POLY_MUL;ALL_IS_INT_POLY_EXP;ALL_IS_INT_POLY_MUL_ITER]) in
2361 let l4 = MP l2 l3 in
2362 let l7 = ONCE_REWRITE_RULE [GSYM REAL_OF_NUM_EQ] FACT_NZ in
2363 let l8 = (SIMP_RULE [l7]) (SPEC `(&(FACT i)):real` POLY_CMUL_EQUALS) in
2364 (* these are not true for x =0, however we only use it for x= &(FACT i) *)
2365 let l10_0 = SPECL [`y:(real)list`;`(real_of_num (FACT i))`] INV_POLY_CMUL in
2366 let l12_0 = SPECL [`y:(real)list`;`(real_of_num (FACT i))`] INV_POLY_CMUL2 in
2367 let l10 = SIMP_RULE [REAL_FACT_NZ] l10_0 in
2368 let l12 = SIMP_RULE [REAL_FACT_NZ] l12_0 in
2369 let l9 = ONCE_REWRITE_RULE [l8] l4 in
2370 let l11 = GSYM (ONCE_REWRITE_RULE [l10] l9) in
2372 (psum (0,m) (\i.(x i) * (if i <= m then (y i) else c))) =
2373 (psum (0,m) (\i.(x i) * (y i)))`,
2374 MESON_TAC [SUM_EQ;ARITH_RULE `(0 <= i /\ i < (m:num) + 0) ==> i <= m`]) in
2375 let l18 = MATCH_MP REAL_MUL_RINV (SPEC `i:num` l7) in
2376 let lass2 = SPECL [`g n p`;`x:real`;`v:real`] Pm_lemma2.PLANETMATH_LEMMA_2_B in
2377 let lass3 = BETA_RULE lass2 in
2378 let lass4 = CONV_RULE (RAND_CONV (RAND_CONV (REWRITE_CONV [Pm_eqn5.PLANETMATH_EQN_5]))) lass3 in
2379 let lass5 = REWRITE_RULE [POLY_CMUL;POLY_CMUL_PDI] lass4 in
2380 let lass6 = CONV_RULE (RAND_CONV (ONCE_REWRITE_CONV [GSYM (ISPEC `f:num->real` ETA_AX)])) (SPEC_ALL SUM_CMUL) in
2381 let lass7 = ONCE_REWRITE_RULE [GSYM REAL_MUL_ASSOC] lass5 in
2382 let lass8 = REWRITE_RULE [lass6] lass7 in
2383 let lass10 = ONCE_REWRITE_RULE [REAL_MUL_DIV_ASSOC] lass8 in
2384 let lass11 = ONCE_REWRITE_RULE [real_div] lass10 in
2385 let lass12 = REAL_ARITH `((w:real) * x * y) * z = w * x * y * z` in
2386 let lass13 = ONCE_REWRITE_RULE [lass12] lass11 in
2387 let lass14 = REWRITE_RULE [lass6] lass13 in
2388 let MUL_ONE = REAL_ARITH `! x.(&1) * x = x /\ x * (&1) = x` in
2389 let lass15 = SIMP_RULE [REAL_MUL_LINV;REAL_FACT_NZ;MUL_ONE] lass14 in
2390 STRIP_TAC THEN STRIP_TAC THEN (EXISTS_TAC bs) THEN (REPEAT STRIP_TAC) THENL
2392 (BETA_TAC THEN BETA_TAC) THEN (ASM_CASES_TAC `(i <= LENGTH (g n p))`) THENL
2393 [ (ASM_SIMP_TAC[]) THEN (ASM_CASES_TAC `((i:num) < p)`) THENL
2394 [ (ASM_MESON_TAC [POLY_CMUL;TAIL_GUNNER;
2395 N_IS_INT;REAL_ARITH `(x:real) * (&0) = &0`]);
2396 (ASSUME_TAC (UNDISCH (ARITH_RULE `~(i < (p:num)) ==> (p <= i)`))) THEN
2397 (CHOOSE_TAC l11) THEN
2398 (SPLIT_CONJOINED_ASSUMPT_TAC (snd (dest_exists (concl l11)))) THEN
2399 (ASM_REWRITE_TAC[l12]) THEN
2400 (ASM_MESON_TAC [N_IS_INT;IS_INT_POLY])
2402 (ASM_MESON_TAC [N_IS_INT])
2404 (BETA_TAC) THEN (SIMP_TAC [l133]) THEN
2405 (SIMP_TAC [POLY_CMUL;l18;REAL_MUL_ASSOC;REAL_MUL_LID]) THEN
2406 (SIMP_TAC [lass15;REAL_INV_1OVER]);
2407 BETA_TAC THEN (ASM_MESON_TAC [TAIL_GUNNER;POLY_CMUL;root_canal])
2410 let INTEGER_PSUM = prove(
2411 `!f m.(! i . i < m ==> integer (f i)) ==> (integer (psum (0,m) f))`,
2412 let l0 = ASSUME `!i. i < SUC m ==> integer (f i)` in
2413 let l1 = SPEC `m:num` l0 in
2414 let l2 = SIMP_RULE [ARITH_RULE `m < SUC m`] l1 in
2415 STRIP_TAC THEN INDUCT_TAC THENL
2416 [ (MESON_TAC [sum;int_of_num;int_of_num_th;N_IS_INT]);
2417 (SIMP_TAC [sum;ARITH_RULE `0 + (x:num) = x`]) THEN
2418 (STRIP_TAC) THEN (MATCH_MP_TAC INTEGER_ADD) THEN
2419 (ASM_MESON_TAC[l2;ARITH_RULE `(i:num) < m ==> i < SUC m`])
2422 let INT_DIVIDES_PSUM = prove(
2423 `!f m p.(! i . i < m ==>
2424 ((integer (f i)) /\ (int_divides p (int_of_real (f i)))))
2425 ==> (int_divides p (int_of_real (psum (0,m) f)))`,
2426 let l0 = ASSUME `!i. i < SUC m ==> integer (f i) /\ p divides int_of_real (f i)` in
2427 let l1 = SPEC `m:num` l0 in
2428 let l2 = SIMP_RULE [ARITH_RULE `m < SUC m`] l1 in
2429 let l3 = ASSUME `(!i. i < m ==> integer (f i)) ==> integer (psum (0,m) f)` in
2430 let l4 = SPEC `i:num` l0 in
2431 let l5 = DISCH `i < SUC m` ((CONJUNCT1 (UNDISCH l4))) in
2432 let l8 = prove(`(!i.i < SUC m
2433 ==> (integer (f i))) ==> (!i.i < m ==> (integer (f i)))`,
2434 MESON_TAC [ARITH_RULE `i < m ==> i < SUC m`]) in
2435 let ll1 = MP l8 (GEN_ALL l5) in
2436 let ll2 = MP l3 ll1 in
2437 let ll3 = MATCH_MP INT_OF_REAL_ADD (CONJ ll2 (CONJUNCT1 l2)) in
2438 STRIP_TAC THEN INDUCT_TAC THENL
2439 [ (MESON_TAC [sum;int_of_num;int_of_num_th;INT_DIVIDES_0]);
2440 (SIMP_TAC [sum;ARITH_RULE `0 + (x:num) = x`]) THEN
2441 (ASSUME_TAC (SPECL [`f:num->real`;`m:num`] INTEGER_PSUM)) THEN
2444 (ONCE_REWRITE_TAC [ll3]) THEN
2445 (MATCH_MP_TAC INT_DIVIDES_ADD) THEN
2447 [ (ASM_MESON_TAC [ARITH_RULE `i < m ==> i < SUC m`]);
2448 (ASM_MESON_TAC [ARITH_RULE `m < SUC m`])
2452 let PLANET_MATH_beta = prove(
2456 (1 <= v /\ v <= n) ==>
2457 ( (integer (poly (SOD (g n p )) (&v)))
2458 /\ ((&p) divides (int_of_real (poly (SOD (g n p )) (&v))))
2461 let l2 = GSYM (ONCE_REWRITE_RULE [REAL_MUL_SYM] real_div) in
2462 let ll3 = ARITH_RULE `(int_of_num p) * &0 = &0` in
2463 let l7 = UNDISCH (SPECL [`i:num`;`p:num`] IS_INT_FACT_DIV) in
2464 let l11 = prove(`p > 0 ==> FACT p = p * (FACT (p-1))`,
2465 MESON_TAC [FACT; ARITH_RULE `p > 0 ==> SUC (p -1) = p `]) in
2466 let l12 = UNDISCH (UNDISCH (ARITH_RULE `(p:num) > n ==> n > 0 ==> p > 0`)) in
2467 let l13 = MP l11 l12 in
2473 ==> (!i. integer (Bs v i)) /\
2474 poly (SOD (g n p)) (&v) =
2475 &1 / &(FACT (p - 1)) *
2476 psum (0,LENGTH (g n p)) (\i. &(FACT i) * Bs v i) /\
2477 (!i. i < p ==> Bs v i = &0)) ==>
2478 (integer (Bs v i))` in
2479 let lll0 = UNDISCH (UNDISCH (UNDISCH (prove(t9,MESON_TAC[])))) in
2480 let l8 = REWRITE_RULE [l13;real_div;REAL_INV_MUL] l7 in
2481 let l9 = REWRITE_RULE [N_IS_INT;GSYM REAL_OF_NUM_MUL] l8 in
2482 let l10 = REWRITE_RULE [REAL_INV_MUL] l9 in
2483 let l11 = MATCH_MP (INTEGER_MUL) (CONJ l10 lll0) in
2484 let l12 = MATCH_MP INT_OF_REAL_MUL (CONJ (SPEC `p:num` N_IS_INT) l11) in
2485 let l15 = GSYM l12 in
2486 let lll8 = ARITH_RULE `p > n ==> n > 0 ==> ~(p = 0)` in
2487 let lll9 = ONCE_REWRITE_RULE [GSYM REAL_OF_NUM_EQ] lll8 in
2488 let lll10 = UNDISCH (UNDISCH lll9) in
2490 let sc1 = prove (`(~((x:real) = &0)) ==> (x * y * inv x) = y`,
2491 MESON_TAC [REAL_MUL_RID;REAL_MUL_ASSOC;
2492 REAL_MUL_SYM;REAL_MUL_LINV;REAL_MUL_LID]) in
2493 let sc2 = prove (`(~((x:real) = &0)) ==> (x * y * (inv x) * z) = y * z`,
2494 MESON_TAC [sc1;REAL_MUL_ASSOC]) in
2495 (REPEAT STRIP_TAC) THENL
2496 [ (CHOOSE_TAC (UNDISCH (UNDISCH MESSY_JESSE2))) THEN
2497 (ASM_SIMP_TAC []) THEN
2498 (ONCE_REWRITE_TAC [GSYM SUM_CMUL]) THEN
2499 (MATCH_MP_TAC INTEGER_PSUM) THEN
2500 (REPEAT STRIP_TAC) THEN
2502 (ASM_CASES_TAC `i < (p:num)`) THENL
2503 [ (ASM_SIMP_TAC [N_IS_INT;REAL_ARITH `(x:real) * (&0) = &0`]);
2504 (ASSUME_TAC (UNDISCH (ARITH_RULE `(~((i:num) < p)) ==> i >= p-1`))) THEN
2505 (ASM_MESON_TAC [REAL_INV_1OVER;REAL_MUL_ASSOC;
2506 IS_INT_FACT_DIV; l2;INTEGER_MUL])
2508 (CHOOSE_TAC (UNDISCH (UNDISCH MESSY_JESSE2))) THEN
2509 (ASM_SIMP_TAC []) THEN
2510 (ONCE_REWRITE_TAC [GSYM SUM_CMUL]) THEN
2511 (MATCH_MP_TAC INT_DIVIDES_PSUM) THEN
2512 (REPEAT STRIP_TAC) THENL
2514 (ASM_CASES_TAC `i < (p:num)`) THENL
2515 [ (ASM_SIMP_TAC [N_IS_INT;REAL_ARITH `(x:real) * (&0) = &0`]);
2516 (ASSUME_TAC (UNDISCH (ARITH_RULE `(~((i:num) < p)) ==> i >= p-1`))) THEN
2517 (ASM_MESON_TAC [REAL_INV_1OVER;REAL_MUL_ASSOC;
2518 IS_INT_FACT_DIV; l2;INTEGER_MUL])
2520 (ONCE_REWRITE_TAC [int_divides]) THEN BETA_TAC THEN
2521 (ASM_CASES_TAC `i < (p:num)`) THENL
2522 [ (ASM_SIMP_TAC [N_IS_INT;REAL_ARITH `(x:real) * (&0) = &0`]) THEN
2523 (EXISTS_TAC `int_of_num 0`) THEN
2524 (MESON_TAC [ll3;int_of_num_th;int_of_num]);
2525 (ASSUME_TAC (UNDISCH (ARITH_RULE `(~((i:num) < p)) ==> i >= p`))) THEN
2526 (EXISTS_TAC `int_of_real (((&(FACT i))/(&(FACT p))) * (Bs (v:num) i))`) THEN
2527 (ONCE_REWRITE_TAC [int_of_num]) THEN
2528 (ONCE_REWRITE_TAC [l13]) THEN
2529 (ONCE_REWRITE_TAC [N_IS_INT;GSYM REAL_OF_NUM_MUL]) THEN
2530 (SIMP_TAC [ real_div]) THEN
2531 (ONCE_REWRITE_TAC [ REAL_INV_MUL]) THEN
2532 (ONCE_REWRITE_TAC [ REAL_MUL_LID]) THEN
2533 (ONCE_REWRITE_TAC [l15]) THEN
2534 (ASSUME_TAC lll10) THEN
2535 (ONCE_REWRITE_TAC [REAL_MUL_ASSOC]) THEN
2536 (ASM_MESON_TAC [sc2;REAL_MUL_SYM])
2542 let JUNE_LEMMA = prove(
2543 `n > 0 ==> p > n ==> v <= n ==> integer (poly (SOD (g n p)) (&v))`,
2544 let lem0 = CONJUNCT1 (UNDISCH_ALL PLANET_MATH_alpha) in
2545 let lem1 = UNDISCH_ALL (SPEC_ALL (UNDISCH_ALL PLANET_MATH_beta)) in
2546 let lem2 = DISCH `1 <= v /\ v <= n` (CONJUNCT1 lem1) in
2547 let lem3 = SPEC `SUC v` (GEN `v:num` lem2) in
2548 let lem4 = SIMP_RULE [ARITH_RULE `1 <= SUC v`] lem3 in
2549 (STRIP_TAC THEN STRIP_TAC) THEN
2550 (SPEC_TAC (`v:num`,`v:num`)) THEN
2551 (INDUCT_TAC THENL [(SIMP_TAC [lem0]);(ACCEPT_TAC lem4)])
2553 let DIVIDES_SUM_NOT_ZERO = prove(
2554 `!(x:int) (y:int) (z:int).
2555 (~(z divides x)) /\ (z divides y) ==> ~(x + y = &0)`,
2556 let l0 = ASSUME `(x:int) + y = &0` in
2557 let l1 = ONCE_REWRITE_RULE [ARITH_RULE `((x:int) + y = &0) <=> (x = --y)`] l0 in
2558 (REPEAT STRIP_TAC) THEN (UNDISCH_TAC `~((z:int) divides x)`) THEN
2559 (REWRITE_TAC [l1]) THEN (UNDISCH_TAC `((z:int) divides y)`) THEN
2562 let NUM_OF_INT_ABS = prove(
2563 `!(x:num) (y:int).num_of_int (abs y) = x <=> abs y = &x`,
2565 let j0 = UNDISCH (prove(`(num_of_int (abs y) = x) ==> x = num_of_int (abs y)`,MESON_TAC [])) in
2566 let j1 = ARITH_RULE `&0 <= ((abs y):int)` in
2567 let j2 = MATCH_MP INT_OF_NUM_OF_INT j1 in
2568 (REPEAT STRIP_TAC) THEN EQ_TAC THENL
2569 [ (STRIP_TAC THEN SIMP_TAC [j0;j2]);
2570 (ASM_SIMP_TAC [NUM_OF_INT_OF_NUM])]
2572 let INT_DIVIDES_IMP_ABS_NUM_DIVIDES = prove(
2574 (x divides (&y)) ==> ((num_of_int (abs x)) divides y)`,
2575 let w0 = ARITH_RULE `((&0):int) <= abs x` in
2576 let w1 = fst (EQ_IMP_RULE (SPEC `abs (x:int)` NUM_OF_INT)) in
2577 let w2 = MP w1 w0 in
2578 let w3 = ARITH_RULE `((&0):int) <= x ==> abs x = x` in
2579 let w4 = ARITH_RULE `(~(((&0):int) <= x)) ==> abs x = -- x` in
2580 (REWRITE_TAC [int_divides;num_divides]) THEN
2581 (REPEAT STRIP_TAC) THEN (ASM_REWRITE_TAC [w2]) THEN
2582 (ASM_CASES_TAC `((&0):int) <= x`) THENL
2583 [ (ONCE_REWRITE_TAC [UNDISCH w3]) THEN
2584 (EXISTS_TAC `x':int`) THEN (REFL_TAC);
2585 (ONCE_REWRITE_TAC [UNDISCH w4]) THEN
2586 (EXISTS_TAC `--x':int`) THEN (ARITH_TAC)
2589 let INT_PRIME_NUM_PRIME = prove(
2590 `!p. int_prime (&p) <=> prime p`,
2591 (ONCE_REWRITE_TAC [int_prime;prime]) THEN
2592 (MESON_TAC [divides;num_divides;
2593 INT_ABS;INT_POS;INT_OF_NUM_EQ;INT_LT_IMP_NE;INT_GT;
2594 ARITH_RULE `2 <= p ==> abs((&p):int) > &1`;
2595 INT_DIVIDES_IMP_ABS_NUM_DIVIDES;NUM_OF_INT_ABS;PRIME_GE_2;
2599 let DIVIDES_INT_OF_REAL_ADD = prove(
2600 `!x y p.integer x /\
2602 p divides (int_of_real x) /\
2603 p divides (int_of_real y)
2604 ==> p divides (int_of_real (x + y))`,
2605 SIMP_TAC [INT_OF_REAL_ADD;INT_DIVIDES_ADD]
2607 let ITCHY_LEMMA = prove(
2609 (!v.1<= v /\ v <= n ==>
2611 &p divides int_of_real (f v)) ==>
2612 (&p divides int_of_real (sum (1..n) f))`,
2613 let l0 = fst (EQ_IMP_RULE (SPECL [`1`;`0`] (GSYM NUMSEG_EMPTY))) in
2614 let l1 = INTEGER_RULE `&p divides ((&0))` in
2615 let l2 = SPEC `0` (GEN_ALL int_of_num) in
2616 let l3 = ONCE_REWRITE_RULE [l2] l1 in
2617 let l4 = SPECL [`f:num->real`;`n:num`;`1`] IS_INT_SUM in
2618 let l5 = prove(`(!v. 1 <= v /\ v <= SUC n ==> integer (f v)) ==> (!i. 1 <= i /\ i <= n ==> integer (f i))`,MESON_TAC [ARITH_RULE `v <= n ==> v <= SUC n`]) in
2619 let l6 = IMP_TRANS l5 l4 in
2620 let l7 = prove(`(!v. 1 <= v /\ v <= SUC n ==> (integer (f v)) /\ (&p) divides int_of_real (f v)) ==> (&p) divides int_of_real (f (SUC n))`,MESON_TAC [ARITH_RULE `1 <= (SUC n) /\ SUC n <= SUC n`]) in
2621 let l9 = prove(`(!v. 1 <= v /\ v <= SUC n ==> integer (f v)) ==> integer (f (SUC n))`,MESON_TAC [ARITH_RULE `1 <= SUC n /\ SUC n <= SUC n`]) in
2622 let tm = `\(v:num).integer (f v) /\ (&p) divides int_of_real (f v)` in
2623 let l10 = BETA_RULE (SPEC tm SHRIVER) in
2624 let l11 = UNDISCH (SPEC `1` (GEN `m:num` l10)) in
2625 STRIP_TAC THEN STRIP_TAC THEN INDUCT_TAC THENL
2626 [ SIMP_TAC [ARITH_RULE `0 < 1`;l0;SUM_CLAUSES;l3];
2628 (SIMP_TAC [SUM_CLAUSES_NUMSEG;ARITH_RULE `1 <= SUC n`]) THEN
2629 (MATCH_MP_TAC DIVIDES_INT_OF_REAL_ADD) THEN (CONJ_TAC) THENL
2630 [ ASM_SIMP_TAC [l6];
2632 [ ASM_SIMP_TAC [l9];
2634 [ ASM_SIMP_TAC [l11];
2635 ASM_SIMP_TAC [l7] ]]]]
2637 let GOTTA_DO_DISHES_LEMMA = prove(
2638 `!(x:real) (y:real).
2639 (integer x) /\ (integer y) ==>
2640 (?(z:int).(~(z divides (int_of_real x)))
2641 /\ (z divides (int_of_real y)))
2644 let lem0 = SPECL [x;y;`z:int`] DIVIDES_SUM_NOT_ZERO in
2645 let lem1 = TAUT `(X /\ Y ==> Z) <=> (X ==> Y ==> Z)` in
2646 UNDISCH (UNDISCH (ONCE_REWRITE_RULE [lem1] lem0))
2649 (ASM_REWRITE_TAC [GSYM int_of_num;INT_OF_REAL_NEG_INT_OF_NUM]) THEN
2651 (REWRITE_TAC [GSYM int_neg_th;GSYM int_eq; GSYM int_add_th;GSYM int_of_num_th]) THEN
2652 (ACCEPT_TAC (mk_lemma x y))
2654 (ONCE_REWRITE_TAC [is_int]) THEN
2655 (STRIP_TAC THEN STRIP_TAC THEN STRIP_TAC ) THENL
2656 [ mk_tac `(&n):int` `(&n'):int` ;
2657 mk_tac `(&n):int` `--(&n'):int` ;
2658 mk_tac `--(&n):int` `(&n'):int` ;
2659 mk_tac `--(&n):int` `--(&n'):int`
2663 let RAINY_DAY = prove(
2670 (((&p) divides (int_of_real (x * y)))
2671 <=> ((&p) divides int_of_real y))`,
2672 let ss3 = SPECL [`int_of_num n`;`(&p):int`] INT_PRIME_COPRIME_LT in
2673 let ss4 = ONCE_REWRITE_RULE [ARITH_RULE `abs ((&x):int) = &x`] ss3 in
2674 let ss40 = prove(`!(x:num) (y:num). (int_of_num x) < (int_of_num y) <=> (real_of_num x) < (real_of_num y)`,SIMP_TAC [INT_OF_NUM_LT;REAL_OF_NUM_LT]) in
2675 let ss5 = ONCE_REWRITE_RULE [ss40;INT_COPRIME_SYM;INT_PRIME_NUM_PRIME] ss4 in
2676 let ss6 = SPECL [`(&p):int`;`(&n):int`;`int_of_real y`] INT_COPRIME_DIVPROD in
2677 let ss7 = ONCE_REWRITE_RULE [TAUT `(X /\ Y ==> Z) <=> (Y ==> X ==> Z)`] ss6 in
2678 let ss8 = IMP_TRANS ss5 ss7 in
2679 let ss9 = ONCE_REWRITE_RULE [TAUT `(A /\ B /\ C ==> D ==> E) <=> (A ==> B ==> C ==> D ==> E)`] ss8 in
2680 let ss10 = UNDISCH ss9 in
2681 (REPEAT STRIP_TAC) THEN (ASM_SIMP_TAC [INT_OF_REAL_MUL]) THEN
2683 [ (SIMP_TAC [INT_DIVIDES_LMUL]) THEN
2684 (UNDISCH_TAC `integer x`) THEN
2685 (ONCE_REWRITE_TAC [is_int]) THEN
2687 [ (ASM_REWRITE_TAC[]) THEN
2688 (ONCE_REWRITE_TAC [GSYM int_of_num]) THEN
2689 (UNDISCH_TAC `(&(p:num)) > (x:real)`) THEN
2690 (UNDISCH_TAC `(x:real) > &0`) THEN
2691 (ASM_REWRITE_TAC []) THEN
2692 (ONCE_REWRITE_TAC [REAL_ARITH `(y:real) > z <=> z < y`]) THEN
2696 (SIMP_TAC [INT_DIVIDES_LMUL])
2699 let PLANET_MATH_gamma = prove(
2705 n = PRE (LENGTH (c)) ==>
2707 ( (integer (LHS c (g n p))) /\ ~((LHS c (g n p)) = &0))`,
2708 let lemma01 = SPECL [`\i. EL i c * poly (SOD (g n p)) (&i)`;`n:num`;`k:num` ] IS_INT_SUM in
2709 let lemma02 = BETA_RULE lemma01 in
2710 let lemma021 = UNDISCH JUNE_LEMMA in
2711 let lemma022 = UNDISCH_ALL (ARITH_RULE `n > 0 ==> p > n ==> p > 1`) in
2712 let lemma023 = DISCH_ALL (SIMP_RULE [lemma022] lemma021) in
2713 let lemma04 = UNDISCH (UNDISCH lemma023) in
2714 let lemma08 = ISPECL [`c:(real)list`;`v:num`;`integer`] ALL_IMP_EL in
2715 let lemma09 = ADD_ASSUM `n > 0` (UNDISCH lemma08) in
2716 let lemma10 = ADD_ASSUM `n = PRE (LENGTH (c:(real)list))` lemma09 in
2717 let lemma11 = ARITH_RULE `n > 0 ==> (n = PRE (LENGTH (c:(real)list))) ==> ((v < LENGTH c) <=> (v <= n))` in
2718 let lemma12 = UNDISCH (UNDISCH lemma11) in
2719 let lemma13 = ONCE_REWRITE_RULE [lemma12] lemma10 in
2720 let lemma15 = CONJ (UNDISCH (UNDISCH lemma04)) (UNDISCH lemma13) in
2721 let lemma16 = MATCH_MP INTEGER_MUL (ONCE_REWRITE_RULE [CONJ_SYM] lemma15) in
2722 let lemma17 = DISCH `v <= (n:num)` lemma16 in
2723 let lemma18 = ADD_ASSUM_DISCH `k <= (v:num)` lemma17 in
2724 let lemma19 = ONCE_REWRITE_RULE [TAUT `(X ==> Y ==> Z) <=> ((X /\ Y) ==> Z)`] lemma18 in
2725 let lemma20 = GEN `v:num` lemma19 in
2726 let lemma21 = GEN `k:num` (MATCH_MP lemma02 lemma20) in
2727 let lemma29 = SPEC `0` lemma21 in
2728 let lemma30 = GSYM (ASSUME `n = PRE (LENGTH (c:(real)list))`) in
2729 let lemma300 = SPECL [`f:(num -> real)`;`0`;`PRE (LENGTH (c:(real)list))`] SUM_CLAUSES_LEFT in
2730 let lemma31 = ADD_ASSUM `n > 0` (ADD_ASSUM `n = PRE (LENGTH (c:(real)list))` lemma300) in
2731 let lemma32 = MP lemma31 (ARITH_RULE `0 <= PRE (LENGTH (c:(real)list))`) in
2732 let lemma0000 = BRW `(X ==> Y ==> Z) <=> ((X /\ Y) ==> Z)` GOTTA_DO_DISHES_LEMMA in
2733 let lemmaa00 = UNDISCH PLANET_MATH_alpha in
2734 let lemmaa03 = ARITH_RULE `n >0 ==> ((n = PRE (LENGTH (c:(real)list))) ==> 0 < (LENGTH c))` in
2735 let lemmaa04 = ISPECL [`c:(real)list`;`0`;`integer`] ALL_IMP_EL in
2736 let lemmaa05 = MP (UNDISCH lemmaa04) (UNDISCH (UNDISCH lemmaa03)) in
2737 let c1 = ARITH_RULE `n > 0 ==> n = PRE (LENGTH (c:(real)list)) ==> 0 < (LENGTH (c:(real)list))` in
2738 let c2 = UNDISCH (UNDISCH c1) in
2739 let c3 = MP (UNDISCH lemmaa04) c2 in
2740 let c4 = CONJUNCT1 (UNDISCH (UNDISCH (UNDISCH PLANET_MATH_alpha))) in
2741 let c40 = CONJUNCT2 (UNDISCH (UNDISCH (UNDISCH PLANET_MATH_alpha))) in
2742 let c5 = SPECL [`p:num`;`(EL 0 c):real`;`poly (SOD (g n p)) (&0)`] RAINY_DAY in
2743 let c7 = ((UNDISCH (UNDISCH c5))) in
2744 let c8 = SIMP_RULE [c3] c7 in
2745 let c9 = UNDISCH c8 in
2746 let c10 = SIMP_RULE [c4] c9 in
2747 let d0 = UNDISCH PLANET_MATH_beta in
2748 let d1 = BRW `(X ==> Y ==> Z) <=> (Y ==> X ==> Z)` d0 in
2749 let d2 = SIMP_RULE [UNDISCH (ARITH_RULE `p > (n:num) ==> n > 0 ==> p > 1`)] d1 in
2750 let d3 = UNDISCH d2 in
2751 let d8 = CONJUNCT2 (UNDISCH (SPEC_ALL d3)) in
2752 let d9 = SPECL [`(&p):int`;`int_of_real (EL v c)`;`int_of_real (poly (SOD (g n p)) (&v))`] INT_DIVIDES_LMUL in
2753 let d10 = ADD_ASSUM `ALL integer c` d9 in
2754 let d11 = ADD_ASSUM `n = PRE (LENGTH (c:(real)list))` d10 in
2755 let d12 = ADD_ASSUM `1 <= v /\ v <= n` d11 in
2756 let d13 = CONJUNCT1 (UNDISCH (SPEC_ALL d3)) in
2757 let d14 = DISCH `1 <= v` (ADD_ASSUM `1 <= v` lemma13) in
2758 let d15 = BRW `(X ==> Y ==> Z) <=> (X /\ Y ==> Z)` d14 in
2759 let d16 = UNDISCH d15 in
2760 let d17 = CONJ d16 d13 in
2761 let d18 = GSYM (MATCH_MP INT_OF_REAL_MUL d17) in
2762 let d19 = ONCE_REWRITE_RULE [d18] d12 in
2763 let d20 = MP d19 d8 in
2764 let d21 = UNDISCH (SPECL [`1`;`v:num`] (GEN `k:num` lemma20)) in
2765 let d22 = CONJ d21 d20 in
2766 let d23 = DISCH `1 <=v /\ v <= n` d22 in
2767 let d24 = GEN `v:num` d23 in
2768 let d25 = MATCH_MP ITCHY_LEMMA d24 in
2769 ((REPEAT STRIP_TAC) THENL
2770 [ (ONCE_REWRITE_TAC [Pm_eqn4.LHS]) THEN (SIMP_TAC [lemma30;lemma29]);
2771 (UNDISCH_TAC `LHS c (g n p) = &0`) THEN
2772 (REWRITE_TAC [Pm_eqn4.LHS]) THEN
2773 (SIMP_TAC [lemma32;ARITH_RULE `0 + 1 = 1`]) THEN
2774 (ONCE_REWRITE_TAC [lemma30]) THEN
2775 (MATCH_MP_TAC lemma0000) THEN
2778 [ (MATCH_MP_TAC INTEGER_MUL) THEN (ASM_SIMP_TAC [lemmaa00;lemmaa05]);
2779 (ACCEPT_TAC (SPEC `1` lemma21))
2781 (EXISTS_TAC `(&p):int`) THEN (CONJ_TAC) THENL
2782 [(ONCE_REWRITE_TAC [c10]) THEN (ASM_SIMP_TAC [c40]);
2792 module Finale = struct
2794 let IS_INT_NZ_ABS_GE_1 = prove (
2795 `!x. ((integer x) /\ ~(x = &0)) ==> ~(abs x < &1)`,
2796 let lemmy0 = REAL_ARITH `(x:real) < y <=> ~(y <= x)` in
2797 let lemmy1 = ONCE_REWRITE_RULE [lemmy0] REAL_NZ_IMP_LT in
2798 let lemmy2 = REAL_ARITH `(real_neg x) = &0 <=> x = &0` in
2799 let lemmy3 = REAL_ARITH `&0 <= (real_neg x) <=> x <= &0` in
2800 (ONCE_REWRITE_TAC [is_int]) THEN
2801 (ONCE_REWRITE_TAC [TAUT `(X /\ Y ==> Z) <=> (X ==> Y ==> Z)`]) THEN
2802 (STRIP_TAC) THEN (STRIP_TAC) THENL
2803 [ (ASM_REWRITE_TAC[]) THEN (SIMP_TAC [REAL_ABS_NUM] ) THEN
2804 (ONCE_REWRITE_TAC [REAL_OF_NUM_LT;REAL_OF_NUM_EQ]) THEN
2806 (ASM_REWRITE_TAC[]) THEN (ONCE_REWRITE_TAC [real_abs]) THEN
2807 (ONCE_REWRITE_TAC [lemmy2;lemmy3]) THEN
2808 (ONCE_REWRITE_TAC [REAL_OF_NUM_EQ]) THEN
2809 (SIMP_TAC [lemmy1;REAL_NEG_NEG]) THEN
2810 (ONCE_REWRITE_TAC [REAL_OF_NUM_LT]) THEN (ARITH_TAC)
2813 let PBR_LEMMA = prove(
2814 `!n1 n2 n3 p. p > MAX n1 (MAX n2 n3) ==> (p > n1 /\ p > n2 /\ p > n3)`,
2815 (REWRITE_TAC [MAX]) THEN ARITH_TAC
2818 let BIGGER_PRIME_EXISTS = prove(
2819 `!(n:num). ?p. prime p /\ p > n`,
2820 let lem0 = prove(`{x | prime x} = prime`,SET_TAC[]) in
2821 let lem1 = ARITH_RULE `p > n <=> ~(p <= (n:num))` in
2822 MESON_TAC [PRIMES_INFINITE;lem0;lem1;IN_ELIM_THM;num_FINITE;INFINITE]
2824 let BUD_LEMMA = prove(
2825 `!(f:num->bool) (n1:num) (n2:num).((?(N:num) . !(p:num).p > N ==> f p)
2826 ==> (? (p0:num).prime p0 /\ p0 > n1 /\ p0 > n2 /\ f p0))`,
2827 let amigo3 = SPECL [`N:num`;`n1:num`;`n2:num`;`p:num`] PBR_LEMMA in
2828 let amigo4 = UNDISCH amigo3 in
2829 (REPEAT STRIP_TAC) THEN
2830 (CHOOSE_TAC (SPEC `MAX N (MAX n1 n2)` BIGGER_PRIME_EXISTS )) THEN
2831 (EXISTS_TAC `p:num`) THEN
2832 (UNDISCH_TAC `prime p /\ p > MAX N (MAX n1 n2)`) THEN
2833 (ONCE_REWRITE_TAC [TAUT `(X /\ Y ==> Z) <=> (X ==> Y ==> Z)`]) THEN
2834 (DISCH_TAC THEN DISCH_TAC) THEN
2835 (ASM_SIMP_TAC [amigo4])
2838 let ALL_IMP_EL = prove(
2839 `! (l:(a)list) i P. (ALL P l) ==> (i < LENGTH l) ==> P (EL i l)`,
2840 SIMP_TAC[GSYM ALL_EL]
2843 let HAMMS_LEMMA = prove(
2844 `~(?c. ALL integer c /\
2847 (!f. LHS c f = RHS c f))`,
2848 let erica0 = UNDISCH_ALL Pm_eqn4_lhs.PLANET_MATH_gamma in
2849 let erica1 = MATCH_MP IS_INT_NZ_ABS_GE_1 erica0 in
2850 let erica2 = ASM_REWRITE_RULE [] erica1 in
2851 let erica3 = SPEC_ALL Pm_eqn4_rhs.LT_ONE in
2852 let erica4 = MATCH_MP BUD_LEMMA erica3 in
2853 let erica5 = ADD_ASSUM `ALL integer c` erica4 in
2854 let erica8 = ARITH_RULE `(n = PRE (LENGTH (c:(real)list))) ==> n > 0 ==>
2856 let erica9 = UNDISCH (UNDISCH erica8) in
2857 let erica10 = UNDISCH (ISPECL [`c:(real)list`;`0`;`integer`] ALL_IMP_EL) in
2858 let erica11 = MP erica10 erica9 in
2859 let erica12 = ONCE_REWRITE_RULE [is_int] erica11 in
2860 let erica13 = ARITH_RULE `!n. ~(( -- (real_of_num n)) > &0)` in
2861 let erica14 = prove(
2862 `n = PRE (LENGTH c) ==>
2867 MESON_TAC [DISCH_ALL erica12;erica13]
2869 let erica15 = UNDISCH_ALL erica14 in
2870 let sim0 = SELECT_RULE (ASSUME (concl erica15)) in
2871 let sim1 = DISCH (concl erica15) sim0 in
2872 let sim2 = MP sim1 erica15 in
2873 let erica18 = SPECL [`n:num`;`@n. EL 0 c = (real_of_num n)`] erica5 in
2874 let erica19 = ONCE_REWRITE_RULE [GSYM REAL_OF_NUM_GT] erica18 in
2875 let erica20 = ONCE_REWRITE_RULE [GSYM sim2] erica19 in
2876 let erica21 = ONCE_REWRITE_RULE [REAL_OF_NUM_GT] erica20 in
2877 let erica22 = DISCH `(real_of_num p) > EL 0 c` erica2 in
2878 let erica23 = DISCH `(p:num) > n` erica22 in
2879 let erica24 = DISCH `prime (p:num)` erica23 in
2880 let erica25 = GEN `p:num` erica24 in
2881 let erica28 = UNDISCH (ARITH_RULE `n = PRE (LENGTH (c:(real)list)) ==> ((n > 0) <=> (LENGTH c) > 1)`) in
2882 let erica29 = UNDISCH (ONCE_REWRITE_RULE [erica28] (DISCH `n > 0` (erica25))) in
2883 let erica30 = UNDISCH (ONCE_REWRITE_RULE [erica28] (DISCH `n > 0` (erica21))) in
2884 (CONV_TAC NNF_CONV) THEN
2885 (REPEAT STRIP_TAC) THEN
2886 (ASM_MESON_TAC [DISCH_ALL erica29;DISCH_ALL erica30])
2889 let TRANSCENDENTAL_E = prove(
2890 `transcendental (exp (&1))`,
2891 MESON_TAC [HAMMS_LEMMA;Pm_eqn4.PLANETMATH_EQN_4]
2896 Finale.TRANSCENDENTAL_E;;