Update from HH
[hl193./.git] / Rqe / work_thms.ml
1 let rec DISJ_TAC thm = DISJ_CASES_TAC thm THENL[ALL_TAC;TRY (POP_ASSUM DISJ_TAC)];;
2
3 let INTERPSIGNS_CONJ = prove_by_refinement(
4   `!P Q eqs l.
5     interpsigns eqs (\x. P x) l /\
6     interpsigns eqs (\x. Q x) l ==>
7     interpsigns eqs (\x. P x \/ Q x) l`,
8 (* {{{ Proof *)
9
10 [
11   STRIP_TAC THEN STRIP_TAC;
12   REPEAT LIST_INDUCT_TAC THEN REWRITE_TAC[interpsigns;ALL2;interpsign];
13   REPEAT (POP_ASSUM MP_TAC);
14   DISJ_TAC (ISPEC `h':sign` SIGN_CASES) THEN ASM_REWRITE_TAC[interpsign;interpsigns] THEN REPEAT STRIP_TAC THEN ASM_MESON_TAC[];
15 ]);;
16
17 (* }}} *)
18
19 let INTERPMAT_TRIO = prove_by_refinement(
20   `!eqs x y l r t.
21     interpmat (CONS x (CONS y t)) eqs (CONS l (CONS l (CONS l r))) ==>
22     interpmat (CONS y t) eqs (CONS l r)`,
23 (* {{{ Proof *)
24
25 [
26   REWRITE_TAC[interpmat;partition_line;NOT_CONS_NIL;ALL2;HD;TL;APPEND];
27   REPEAT_N 6 STRIP_TAC;
28   DISJ_CASES_TAC (ISPEC `t:real list` list_CASES);
29   ASM_REWRITE_TAC[];
30   REPEAT STRIP_TAC;
31   MATCH_ACCEPT_TAC ROL_SING;
32   REWRITE_TAC[ALL2];
33   REWRITE_ASSUMS[TL];
34   STRIP_TAC;
35   MATCH_MP_TAC INTERPSIGNS_SUBSET;
36   EXISTS_TAC `\z. z < x \/ (z = x) \/ (x < z /\ z < y)`;
37   STRIP_TAC;
38   MATCH_MP_TAC INTERPSIGNS_CONJ;
39   ASM_REWRITE_TAC[];
40   MATCH_MP_TAC INTERPSIGNS_CONJ;
41   ASM_REWRITE_TAC[];
42   REWRITE_TAC[SUBSET;IN];
43   REAL_ARITH_TAC;
44   FIRST_ASSUM MATCH_ACCEPT_TAC;
45   POP_ASSUM MP_TAC THEN STRIP_TAC;
46   ASM_REWRITE_TAC[NOT_CONS_NIL;TL];
47   REPEAT STRIP_TAC;
48   ASM_MESON_TAC[ROL_TAIL;TL;NOT_CONS_NIL;];
49   REWRITE_TAC[ALL2];
50   ASM_REWRITE_TAC[];
51   MATCH_MP_TAC INTERPSIGNS_SUBSET;
52   EXISTS_TAC `\z. z < x \/ (z = x) \/ (x < z /\ z < y)`;
53   STRIP_TAC;
54   MATCH_MP_TAC INTERPSIGNS_CONJ;
55   ASM_REWRITE_TAC[];
56   MATCH_MP_TAC INTERPSIGNS_CONJ;
57   ASM_REWRITE_TAC[];
58   REWRITE_TAC[SUBSET;IN];
59   REAL_ARITH_TAC;
60 ]);;
61
62 (* }}} *)
63
64 let PARTITION_LINE_NOT_NIL = prove_by_refinement(
65   `!l. ~(partition_line l = [])`,
66 (* {{{ Proof *)
67
68 [
69   LIST_INDUCT_TAC;
70   REWRITE_TAC[partition_line;NOT_CONS_NIL;];
71   REWRITE_TAC[partition_line];
72   COND_CASES_TAC;
73   REWRITE_TAC[NOT_CONS_NIL];
74   ASM_MESON_TAC[APPEND_EQ_NIL;NOT_CONS_NIL];
75 ]);;
76
77 (* }}} *)
78
79 let ALL2_LENGTH = prove_by_refinement(
80   `!P l1 l2. ALL2 P l1 l2 ==> (LENGTH l1 = LENGTH l2)`,
81 (* {{{ Proof *)
82 [
83   STRIP_TAC;
84   REPEAT LIST_INDUCT_TAC THEN REWRITE_TAC[ALL2;LENGTH];
85   ASM_MESON_TAC[];
86 ]);;
87 (* }}} *)
88
89 let LENGTH_TL = prove_by_refinement(
90    `!l:A list. ~(l = []) ==> (LENGTH (TL l) = PRE (LENGTH l))`,
91 (* {{{ Proof *)
92 [
93   LIST_INDUCT_TAC;
94   REWRITE_TAC[];
95   REWRITE_TAC[NOT_CONS_NIL;TL;LENGTH;];
96   ARITH_TAC;
97 ]);;
98 (* }}} *)
99
100 let PARTITION_LINE_LENGTH = prove_by_refinement(
101   `!l. LENGTH (partition_line l) = 2 * LENGTH l + 1`,
102 (* {{{ Proof *)
103
104 [
105   LIST_INDUCT_TAC;
106   REWRITE_TAC[partition_line;LENGTH;];
107   ARITH_TAC;
108   REWRITE_TAC[partition_line;LENGTH;];
109   COND_CASES_TAC;
110   ASM_REWRITE_TAC[LENGTH;];
111   ARITH_TAC;
112   REWRITE_TAC[APPEND;LENGTH;];
113   ASM_SIMP_TAC[PARTITION_LINE_NOT_NIL;LENGTH_TL];
114   ARITH_TAC;
115 ]);;
116
117 (* }}} *)
118
119 let PARTITION_LINE_LENGTH_TL = prove_by_refinement(
120   `!l. LENGTH (TL (partition_line l)) = 2 * LENGTH l`,
121 (* {{{ Proof *)
122 [
123   STRIP_TAC;
124   REWRITE_TAC[MATCH_MP LENGTH_TL (ISPEC `l:real list` PARTITION_LINE_NOT_NIL)];
125   REWRITE_TAC[PARTITION_LINE_LENGTH];
126   ARITH_TAC;
127 ]);;
128 (* }}} *)
129
130 let PL_ALL2_LENGTH = prove_by_refinement(
131   `!eqs pts sgns. ALL2 (interpsigns eqs) (partition_line pts) sgns ==>
132      (LENGTH sgns = 2 * LENGTH pts + 1)`,
133 (* {{{ Proof *)
134
135 [
136   REPEAT_N 3 STRIP_TAC;
137   DISJ_CASES_TAC (ISPEC `pts:real list` list_CASES);
138   ASM_REWRITE_TAC[interpmat;LENGTH;ROL_NIL;partition_line;];
139   ARITH_SIMP_TAC[];
140   DISJ_CASES_TAC (ISPEC `sgns:(sign list) list` list_CASES);
141   ASM_REWRITE_TAC[ALL2];
142   POP_ASSUM MP_TAC THEN STRIP_TAC;
143   ASM_REWRITE_TAC[];
144   ASM_REWRITE_TAC[ALL2];
145   DISJ_CASES_TAC (ISPEC `t:(sign list) list` list_CASES);
146   ASM_REWRITE_TAC[ALL2;LENGTH;ONE];
147   POP_ASSUM MP_TAC THEN STRIP_TAC;
148   ASM_REWRITE_TAC[];
149   ASM_REWRITE_TAC[ALL2];
150   (* save *)
151   POP_ASSUM MP_TAC THEN STRIP_TAC;
152   ASM_REWRITE_TAC[interpmat;partition_line;];
153   COND_CASES_TAC;
154   ASM_REWRITE_TAC[ROL_SING;LENGTH;GSYM ONE];
155   ARITH_SIMP_TAC[];
156   STRIP_TAC;
157   CLAIM `LENGTH [\x. x < h; \x. x = h; \x. h < x] = LENGTH sgns`;
158   ASM_MESON_TAC[ALL2_LENGTH];
159   REWRITE_TAC[LENGTH];
160   ARITH_TAC;
161   REWRITE_ASSUMS[NOT_NIL];
162   POP_ASSUM MP_TAC THEN STRIP_TAC;
163   REWRITE_TAC[LENGTH];
164   STRIP_TAC;
165   CLAIM `LENGTH sgns = LENGTH (APPEND [\x. x < h; \x. x = h; \x. h < x /\ x < HD t] (TL (partition_line t)))`;
166   ASM_MESON_TAC[ ALL2_LENGTH];
167   DISCH_THEN SUBST1_TAC;
168   REWRITE_TAC[LENGTH_APPEND];
169   REWRITE_TAC[PARTITION_LINE_LENGTH_TL];
170   REWRITE_TAC[LENGTH];
171   ARITH_TAC;
172 ]);;
173
174 (* }}} *)
175
176 let INTERPMAT_LENGTH = prove_by_refinement(
177  `!eqs pts sgns. interpmat pts eqs sgns ==>
178     (LENGTH sgns = 2 * LENGTH pts + 1)`,
179 (* {{{ Proof *)
180
181 [
182   REPEAT_N 3 STRIP_TAC;
183   DISJ_CASES_TAC (ISPEC `pts:real list` list_CASES);
184   ASM_REWRITE_TAC[interpmat;LENGTH;ROL_NIL;partition_line;];
185   ARITH_SIMP_TAC[];
186   DISJ_CASES_TAC (ISPEC `sgns:(sign list) list` list_CASES);
187   ASM_REWRITE_TAC[ALL2];
188   POP_ASSUM MP_TAC THEN STRIP_TAC;
189   ASM_REWRITE_TAC[];
190   ASM_REWRITE_TAC[ALL2];
191   DISJ_CASES_TAC (ISPEC `t:(sign list) list` list_CASES);
192   ASM_REWRITE_TAC[ALL2;LENGTH;ONE];
193   POP_ASSUM MP_TAC THEN STRIP_TAC;
194   ASM_REWRITE_TAC[];
195   ASM_REWRITE_TAC[ALL2];
196   (* save *)
197   POP_ASSUM MP_TAC THEN STRIP_TAC;
198   ASM_REWRITE_TAC[interpmat;partition_line;];
199   COND_CASES_TAC;
200   ASM_REWRITE_TAC[ROL_SING;LENGTH;GSYM ONE];
201   ARITH_SIMP_TAC[];
202   STRIP_TAC;
203   CLAIM `LENGTH [\x. x < h; \x. x = h; \x. h < x] = LENGTH sgns`;
204   ASM_MESON_TAC[ALL2_LENGTH];
205   REWRITE_TAC[LENGTH];
206   ARITH_TAC;
207   REWRITE_ASSUMS[NOT_NIL];
208   POP_ASSUM MP_TAC THEN STRIP_TAC;
209   REWRITE_TAC[LENGTH];
210   STRIP_TAC;
211   CLAIM `LENGTH sgns = LENGTH (APPEND [\x. x < h; \x. x = h; \x. h < x /\ x < HD t] (TL (partition_line t)))`;
212   ASM_MESON_TAC[ ALL2_LENGTH];
213   DISCH_THEN SUBST1_TAC;
214   REWRITE_TAC[LENGTH_APPEND];
215   REWRITE_TAC[PARTITION_LINE_LENGTH_TL];
216   REWRITE_TAC[LENGTH];
217   ARITH_TAC;
218 ]);;
219
220 (* }}} *)
221
222 let ALL2_HD = prove_by_refinement(
223   `!b d a c. (LENGTH a = LENGTH c) ==>
224     ALL2 P (APPEND a b) (APPEND c d) ==> ALL2 P a c`,
225 (* {{{ Proof *)
226
227 [
228   REPEAT_N 2 STRIP_TAC;
229   LIST_INDUCT_TAC;
230   ONCE_REWRITE_TAC[prove(`(x = y) <=> (y = x)`,MESON_TAC[])];
231   REWRITE_TAC[LENGTH;LENGTH_EQ_NIL];
232   MESON_TAC[ALL2];
233   REWRITE_TAC[LENGTH;APPEND;];
234   LIST_INDUCT_TAC;
235   REWRITE_TAC[LENGTH];
236   ARITH_TAC;
237   REWRITE_TAC[LENGTH;APPEND;ALL2;SUC_INJ];
238   ASM_MESON_TAC[];
239 ]);;
240
241 (* }}} *)
242
243 let ALL2_TL = prove_by_refinement(
244   `!b d a c. (LENGTH a = LENGTH c) ==>
245     ALL2 P (APPEND a b) (APPEND c d) ==> ALL2 P b d`,
246 (* {{{ Proof *)
247 [
248   REPEAT_N 2 STRIP_TAC;
249   LIST_INDUCT_TAC;
250   ONCE_REWRITE_TAC[prove(`(x = y) <=> (y = x)`,MESON_TAC[])];
251   REWRITE_TAC[LENGTH;LENGTH_EQ_NIL];
252   MESON_TAC[APPEND];
253   REWRITE_TAC[LENGTH;APPEND;];
254   LIST_INDUCT_TAC;
255   REWRITE_TAC[LENGTH];
256   ARITH_TAC;
257   REWRITE_TAC[ALL2;APPEND;LENGTH;SUC_INJ];
258   ASM_MESON_TAC[];
259 ]);;
260 (* }}} *)
261
262 let ALL2_APPEND_LENGTH = prove_by_refinement(
263   `!P a c b d. (LENGTH a = LENGTH c) ==>
264     ALL2 P (APPEND a b) (APPEND c d) ==> ALL2 P a c /\ ALL2 P b d`,
265 (* {{{ Proof *)
266 [
267   ASM_MESON_TAC[ALL2_HD;ALL2_TL];
268 ]);;
269 (* }}} *)
270
271 let ALL2_APPEND = prove_by_refinement(
272   `!a c b d. ALL2 P a c /\ ALL2 P b d ==>
273       ALL2 P (APPEND a b) (APPEND c d)`,
274 (* {{{ Proof *)
275 [
276   REPEAT LIST_INDUCT_TAC THEN REWRITE_ALL[APPEND;ALL2;LENGTH;ARITH_RULE `~(0 = SUC x)`;APPEND_NIL];
277   REPEAT STRIP_TAC;
278   ASM_REWRITE_TAC[];
279   FIRST_ASSUM MATCH_MP_TAC;
280   ASM_REWRITE_TAC[];
281   ASM_REWRITE_TAC[ALL2];
282 ]);;
283 (* }}} *)
284
285 let ALL2_SPLIT = prove_by_refinement(
286   `!a c b d. (LENGTH a = LENGTH c) ==>
287     (ALL2 P (APPEND a b) (APPEND c d) <=> ALL2 P a c /\ ALL2 P b d)`,
288 (* {{{ Proof *)
289 [
290   ASM_MESON_TAC[ALL2_APPEND;ALL2_APPEND_LENGTH];
291 ]);;
292 (* }}} *)
293
294 let BUTLAST_THM = prove_by_refinement(
295   `(BUTLAST [] = []) /\
296    (BUTLAST [x] = []) /\
297    (BUTLAST (CONS h1 (CONS h2 t)) = CONS h1 (BUTLAST (CONS h2 t)))`,
298 (* {{{ Proof *)
299 [
300   ASM_MESON_TAC[BUTLAST;NOT_CONS_NIL;];
301 ]);;
302 (* }}} *)
303
304 let HD_BUTLAST = prove_by_refinement(
305   `!l. ~(l = []) ==> (!x. ~(l = [x])) ==> (HD (BUTLAST l) = HD l)`,
306 (* {{{ Proof *)
307 [
308   LIST_INDUCT_TAC;
309   REWRITE_TAC[];
310   REWRITE_TAC[NOT_CONS_NIL;HD;BUTLAST];
311   COND_CASES_TAC;
312   ASM_REWRITE_TAC[];
313   ASM_MESON_TAC[];
314   REPEAT STRIP_TAC;
315   REWRITE_TAC[HD];
316 ]);;
317 (* }}} *)
318
319
320 let SUBLIST = new_recursive_definition list_RECURSION
321   `(SUBLIST l [] <=> (l = [])) /\
322    (SUBLIST l (CONS h t) <=> (l = []) \/
323     SUBLIST l t \/
324     ((HD l = h) /\ SUBLIST (TL l) t))`;;
325
326 let SUBLIST_NIL = prove_by_refinement(
327   `!l. SUBLIST [] l`,
328 (* {{{ Proof *)
329 [
330   LIST_INDUCT_TAC THEN
331   ASM_MESON_TAC[SUBLIST];
332 ]);;
333 (* }}} *)
334
335 let SUBLIST_CONS = prove_by_refinement(
336   `!l1 l2 h. SUBLIST l1 l2 ==> SUBLIST l1 (CONS h l2)`,
337 (* {{{ Proof *)
338 [
339   REPEAT LIST_INDUCT_TAC THEN ASM_MESON_TAC[SUBLIST];
340 ]);;
341 (* }}} *)
342
343 let SUBLIST_TL = prove_by_refinement(
344   `!l1 l2. SUBLIST l1 l2 ==> ~(l1 = []) ==> SUBLIST (TL l1) l2`,
345 (* {{{ Proof *)
346 [
347   REPEAT LIST_INDUCT_TAC THEN ASM_MESON_TAC[SUBLIST;]
348 ]);;
349 (* }}} *)
350
351 let SUBLIST_CONS2 = prove_by_refinement(
352   `!h t l. SUBLIST (CONS h t) l ==> SUBLIST t l`,
353 (* {{{ Proof *)
354 [
355   STRIP_TAC;
356   REPEAT LIST_INDUCT_TAC THEN ASM_MESON_TAC[SUBLIST;NOT_CONS_NIL;HD;TL];
357 ]);;
358 (* }}} *)
359
360 let SUBLIST_ID = prove_by_refinement(
361   `!l. SUBLIST l l`,
362 (* {{{ Proof *)
363 [
364   LIST_INDUCT_TAC THEN ASM_MESON_TAC[SUBLIST;SUBLIST_NIL;NOT_CONS_NIL;HD;TL];
365 ]);;
366 (* }}} *)
367
368 let SUBLIST_CONS_CONS = prove_by_refinement(
369   `!h t1 t2. SUBLIST (CONS h t1) (CONS h t2) = SUBLIST t1 t2`,
370 (* {{{ Proof *)
371 [
372   STRIP_TAC;
373   REPEAT LIST_INDUCT_TAC;
374   ASM_MESON_TAC[SUBLIST;SUBLIST_NIL;SUBLIST_ID];
375   ASM_MESON_TAC[SUBLIST;SUBLIST_NIL;SUBLIST_ID];
376   REWRITE_TAC[SUBLIST;SUBLIST_NIL;SUBLIST_ID;NOT_CONS_NIL;HD;TL];
377   REWRITE_TAC[SUBLIST;SUBLIST_NIL;SUBLIST_ID;NOT_CONS_NIL;HD;TL;SUBLIST_CONS2;SUBLIST_CONS];
378   ASM_MESON_TAC[SUBLIST;SUBLIST_NIL;SUBLIST_ID;NOT_CONS_NIL;HD;TL];
379 ]);;
380 (* }}} *)
381
382 let SUBLIST_NEQ = prove_by_refinement(
383   `!h1 h2 t1 t2. SUBLIST (CONS h1 t1) (CONS h2 t2) ==> ~(h1 = h2) ==>
384      SUBLIST (CONS h1 t1) t2`,
385 (* {{{ Proof *)
386 [
387   ASM_MESON_TAC[SUBLIST;NOT_CONS_NIL;HD;TL];
388 ]);;
389 (* }}} *)
390
391 let SUBLIST_TRANS = prove_by_refinement(
392   `!l1 l2 l3. SUBLIST l1 l2 ==> SUBLIST l2 l3 ==> SUBLIST l1 l3`,
393 (* {{{ Proof *)
394 [
395   REPEAT LIST_INDUCT_TAC;
396   ASM_MESON_TAC[SUBLIST];
397   ASM_MESON_TAC[SUBLIST];
398   ASM_MESON_TAC[SUBLIST];
399   ASM_MESON_TAC[SUBLIST];
400   ASM_MESON_TAC[SUBLIST];
401   ASM_MESON_TAC[SUBLIST];
402   ASM_MESON_TAC[SUBLIST];
403   REPEAT STRIP_TAC;
404   REWRITE_TAC[SUBLIST;NOT_CONS_NIL;HD;TL];
405   CASES_ON `h = h''`;
406   DISJ2_TAC;
407   ASM_REWRITE_TAC[];
408   POP_ASSUM (REWRITE_ALL o list);
409   CASES_ON `h' = h''`;
410   POP_ASSUM (REWRITE_ALL o list);
411   ASM_MESON_TAC[SUBLIST_CONS_CONS];
412   REWRITE_ASSUMS[IMP_AND_THM];
413   FIRST_ASSUM MATCH_MP_TAC;
414   EVERY_ASSUM (fun x -> try MP_TAC (MATCH_MP SUBLIST_CONS2 x) with _ -> ALL_TAC);
415   REPEAT STRIP_TAC;
416   ASM_MESON_TAC[SUBLIST;NOT_CONS_NIL;HD;TL;SUBLIST_CONS;SUBLIST_CONS2];
417   DISJ1_TAC;
418   CASES_ON `h' = h''`;
419   POP_ASSUM (REWRITE_ALL o list);
420   REWRITE_ASSUMS[SUBLIST_CONS_CONS];
421   CLAIM `SUBLIST (CONS h t) t'`;
422   ASM_MESON_TAC[SUBLIST_NEQ];
423   STRIP_TAC;
424   ASM_MESON_TAC[];
425   CASES_ON `h = h'`;
426   POP_ASSUM (REWRITE_ALL o list);
427   REWRITE_ASSUMS[SUBLIST_CONS_CONS];
428   ASM_MESON_TAC[SUBLIST_NEQ];
429   CLAIM `SUBLIST (CONS h t) t'`;
430   ASM_MESON_TAC[SUBLIST_NEQ];
431   STRIP_TAC;
432   CLAIM `SUBLIST (CONS h' t') t''`;
433   ASM_MESON_TAC[SUBLIST_NEQ];
434   STRIP_TAC;
435   CLAIM `SUBLIST t' t''`;
436   ASM_MESON_TAC[SUBLIST_CONS2];
437   STRIP_TAC;
438   ASM_MESON_TAC[];
439 ]);;
440 (* }}} *)
441
442 let ROL_MEM = prove_by_refinement(
443   `!h t. real_ordered_list (CONS h t) ==> !x. MEM x t ==> h < x`,
444 (* {{{ Proof *)
445 [
446   STRIP_TAC;
447   LIST_INDUCT_TAC;
448   REWRITE_TAC[MEM];
449   REPEAT STRIP_TAC;
450   CASES_ON `x = h'`;
451   POP_ASSUM (REWRITE_ALL o list);
452   ASM_MESON_TAC[ROL_CONS_CONS];
453   CLAIM `real_ordered_list (CONS h t)`;
454   ASM_MESON_TAC[ROL_CONS_CONS_DELETE];
455   DISCH_THEN (REWRITE_ASSUMS o list);
456   FIRST_ASSUM MATCH_MP_TAC;
457   ASM_MESON_TAC[MEM];
458 ]);;
459 (* }}} *)
460
461 let SUBLIST_MEM = prove_by_refinement(
462   `!x l1 l2. SUBLIST l1 l2 ==> MEM x l1 ==> MEM x l2`,
463 (* {{{ Proof *)
464 [
465   STRIP_TAC;
466   REPEAT LIST_INDUCT_TAC;
467   REWRITE_TAC[MEM];
468   REWRITE_TAC[MEM];
469   REWRITE_TAC[SUBLIST;NOT_CONS_NIL;];
470   REPEAT STRIP_TAC;
471   CASES_ON `h = h'`;
472   POP_ASSUM (REWRITE_ALL o list);
473   REWRITE_ASSUMS[SUBLIST_CONS_CONS];
474   CASES_ON `x = h'`;
475   ASM_MESON_TAC[MEM];
476   REWRITE_ASSUMS[IMP_AND_THM];
477   FIRST_ASSUM MATCH_MP_TAC;
478   ASM_MESON_TAC[MEM;SUBLIST_CONS];
479   CASES_ON `x = h'`;
480   ASM_MESON_TAC[MEM];
481   ASM_MESON_TAC[SUBLIST_NEQ;SUBLIST;MEM];
482 ]);;
483 (* }}} *)
484
485 let ROL_SUBLIST_LT = prove_by_refinement(
486   `!h t1 t2. real_ordered_list (CONS h t2) ==>
487       SUBLIST (CONS h t1) (CONS h t2) ==> !x. MEM x t1 ==> h < x`,
488 (* {{{ Proof *)
489 [
490   STRIP_TAC;
491   REPEAT LIST_INDUCT_TAC;
492   REWRITE_TAC[MEM];
493   REWRITE_TAC[MEM];
494   ASM_MESON_TAC[SUBLIST;NOT_CONS_NIL;HD;TL];
495   REPEAT STRIP_TAC;
496   REWRITE_ASSUMS[SUBLIST_CONS_CONS];
497   CLAIM `MEM x (CONS h'' t')`;
498   ASM_MESON_TAC[SUBLIST_MEM];
499   STRIP_TAC;
500   ASM_MESON_TAC[ROL_MEM];
501 ]);;
502 (* }}} *)
503
504 let SUBLIST_DELETE = prove_by_refinement(
505   `!h1 h2 t l. SUBLIST (CONS h1 (CONS h2 t)) l ==>
506     SUBLIST (CONS h1 t) l`,
507 (* {{{ Proof *)
508 [
509   STRIP_TAC THEN STRIP_TAC;
510   REPEAT LIST_INDUCT_TAC;
511   REWRITE_TAC[SUBLIST;NOT_CONS_NIL;];
512   CASES_ON `h1 = h`;
513   POP_ASSUM (REWRITE_ALL o list);
514   REWRITE_TAC[SUBLIST;NOT_CONS_NIL;HD;TL;SUBLIST_NIL];
515   STRIP_TAC;
516   CLAIM `SUBLIST [h1; h2] t`;
517   ASM_MESON_TAC[SUBLIST_NEQ];
518   DISCH_THEN (REWRITE_ASSUMS o list);
519   ASM_MESON_TAC[SUBLIST_CONS];
520   REWRITE_TAC[SUBLIST;NOT_CONS_NIL;];
521   CASES_ON `h1 = h'`;
522   POP_ASSUM (REWRITE_ALL o list);
523   REWRITE_TAC[SUBLIST_CONS_CONS];
524   MESON_TAC[SUBLIST_CONS2];
525   STRIP_TAC;
526   CLAIM `SUBLIST (CONS h1 (CONS h2 (CONS h t))) t'`;
527   ASM_MESON_TAC[SUBLIST_NEQ];
528   DISCH_THEN (REWRITE_ASSUMS o list);
529   ASM_MESON_TAC[SUBLIST_CONS];
530 ]);;
531 (* }}} *)
532
533 let SUBLIST_MATCH = prove_by_refinement(
534   `!h t l. SUBLIST (CONS h t) l ==>
535      ?(l1:A list) l2. (l = APPEND l1 (CONS h l2)) /\ SUBLIST t l2`,
536 (* {{{ Proof *)
537 [
538   STRIP_TAC;
539   REPEAT LIST_INDUCT_TAC;
540   REWRITE_TAC[SUBLIST;NOT_CONS_NIL;];
541   CASES_ON `h = h'`;
542   POP_ASSUM (REWRITE_ALL o list);
543   STRIP_TAC;
544   EXISTS_TAC `[]`;
545   REWRITE_TAC[APPEND;SUBLIST_NIL];
546   ASM_MESON_TAC[];
547   REWRITE_TAC[SUBLIST_NIL];
548   STRIP_TAC;
549   CLAIM `SUBLIST [h] t`;
550   ASM_MESON_TAC[SUBLIST_NEQ];
551   DISCH_THEN (REWRITE_ASSUMS o list);
552   REPEAT (POP_ASSUM MP_TAC);
553   REPEAT STRIP_TAC;
554   EXISTS_TAC `CONS h' l1`;
555   EXISTS_TAC `l2`;
556   REWRITE_TAC[APPEND];
557   AP_TERM_TAC;
558   ASM_MESON_TAC[];
559   REWRITE_TAC[SUBLIST;NOT_CONS_NIL;];
560   (* save *)
561   CASES_ON `h = h''`;
562   POP_ASSUM (REWRITE_ALL o list);
563   STRIP_TAC;
564   REWRITE_ASSUMS[SUBLIST_CONS_CONS];
565   EXISTS_TAC `[]:A list`;
566   EXISTS_TAC `t'`;
567   ASM_MESON_TAC[APPEND];
568   (* save *)
569   STRIP_TAC;
570   CLAIM `SUBLIST (CONS h (CONS h' t)) t'`;
571   ASM_MESON_TAC[SUBLIST_NEQ];
572   DISCH_THEN (REWRITE_ASSUMS o list);
573   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
574   ASM_REWRITE_TAC[];
575   EXISTS_TAC `CONS h'' l1`;
576   EXISTS_TAC `l2`;
577   ASM_REWRITE_TAC[APPEND];
578 ]);;
579 (* }}} *)
580
581 let ROL_SUBLIST = prove_by_refinement(
582   `!l1 l2.  real_ordered_list l2 ==> SUBLIST l1 l2 ==> real_ordered_list l1`,
583 (* {{{ Proof *)
584 [
585   LIST_INDUCT_TAC;
586   REWRITE_TAC[ROL_NIL];
587   REWRITE_TAC[real_ordered_list];
588   REPEAT STRIP_TAC;
589   REWRITE_ASSUMS[IMP_AND_THM];
590   FIRST_ASSUM MATCH_MP_TAC;
591   ASM_MESON_TAC[SUBLIST_CONS2];
592   CASES_ON `t = []`;
593   ASM_REWRITE_TAC[];
594   ASM_REWRITE_TAC[];
595   REWRITE_ASSUMS[NOT_NIL];
596   POP_ASSUM MP_TAC THEN STRIP_TAC;
597   POP_ASSUM (REWRITE_ALL o list);
598   REWRITE_TAC[HD];
599   DISJ_CASES_TAC (ISPEC `l2:real list` list_CASES);
600   ASM_MESON_TAC[SUBLIST;NOT_CONS_NIL];
601   POP_ASSUM MP_TAC THEN STRIP_TAC;
602   POP_ASSUM (REWRITE_ALL o list);
603   CASES_ON `h = h''`;
604   POP_ASSUM (REWRITE_ALL o list);
605   ASM_MESON_TAC[ROL_SUBLIST_LT;MEM];
606   FIRST_ASSUM (fun x -> MP_TAC (MATCH_MP SUBLIST_MATCH x));
607   STRIP_TAC;
608   CLAIM `real_ordered_list (CONS h l2')`;
609   ASM_MESON_TAC[ROL_APPEND];
610   STRIP_TAC;
611   CLAIM `MEM h' l2'`;
612   ASM_MESON_TAC[SUBLIST_MEM;MEM];
613   STRIP_TAC;
614   ASM_MESON_TAC[ROL_MEM];
615 ]);;
616 (* }}} *)
617
618 let SUBLIST_BUTLAST = prove_by_refinement(
619   `!l. SUBLIST (BUTLAST l) l`,
620 (* {{{ Proof *)
621
622 [
623   LIST_INDUCT_TAC;
624   REWRITE_TAC[BUTLAST;SUBLIST_NIL];
625   REWRITE_TAC[BUTLAST;SUBLIST_NIL;SUBLIST];
626   REPEAT COND_CASES_TAC;
627   REWRITE_TAC[SUBLIST_NIL];
628   ASM_REWRITE_TAC[HD;TL;NOT_CONS_NIL;];
629 ]);;
630
631 (* }}} *)
632
633 let SUBLIST_APPEND_HD = prove_by_refinement(
634   `!l2 l3 l1. SUBLIST (APPEND l1 l2) (APPEND l1 l3) = SUBLIST l2 l3`,
635 (* {{{ Proof *)
636 [
637   REPEAT_N 2 STRIP_TAC;
638   LIST_INDUCT_TAC;
639   REWRITE_TAC[APPEND];
640   ASM_REWRITE_TAC[APPEND;SUBLIST_CONS_CONS];
641 ]);;
642 (* }}} *)
643
644 let SUBLIST_ID_CONS = prove_by_refinement(
645   `!h l. ~(SUBLIST (CONS h l) l)`,
646 (* {{{ Proof *)
647 [
648   STRIP_TAC;
649   LIST_INDUCT_TAC;
650   REWRITE_TAC[SUBLIST;NOT_CONS_NIL;];
651   ASM_REWRITE_TAC[SUBLIST;NOT_CONS_NIL;HD;TL];
652   ASM_MESON_TAC[SUBLIST_DELETE];
653 ]);;
654 (* }}} *)
655
656 let SUBLIST_ID_APPEND = prove_by_refinement(
657   `!m l. ~(l = []) ==> ~(SUBLIST (APPEND l m) m)`,
658 (* {{{ Proof *)
659 [
660   STRIP_TAC;
661   LIST_INDUCT_TAC;
662   REWRITE_TAC[];
663   REWRITE_TAC[APPEND;];
664   DISCH_THEN (fun x -> ALL_TAC);
665   CASES_ON `t = []`;
666   POP_ASSUM (REWRITE_ALL o list);
667   REWRITE_TAC[APPEND;SUBLIST_ID_CONS];
668   POP_ASSUM (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
669   ASM_MESON_TAC[SUBLIST_CONS2];
670 ]);;
671 (* }}} *)
672
673 let SUBLIST_APPEND_TL = prove_by_refinement(
674   `!l3 l1 l2. SUBLIST (APPEND l1 l3) (APPEND l2 l3) = SUBLIST l1 l2`,
675 (* {{{ Proof *)
676 [
677   STRIP_TAC;
678   REPEAT LIST_INDUCT_TAC;
679   REWRITE_TAC[APPEND;APPEND_NIL;SUBLIST;SUBLIST_ID];
680   REWRITE_ALL[SUBLIST_NIL;APPEND;APPEND_NIL;SUBLIST;SUBLIST_ID];
681   ASM_REWRITE_TAC[];
682   REWRITE_ALL[SUBLIST_NIL;SUBLIST;SUBLIST_ID;NOT_CONS_NIL;];
683   ASM_MESON_TAC[SUBLIST_ID_APPEND;APPEND;NOT_CONS_NIL;];
684   REWRITE_TAC[APPEND];
685   CASES_ON `h = h'`;
686   POP_ASSUM (REWRITE_ALL o list);
687   EQ_TAC;
688   REWRITE_TAC[SUBLIST;APPEND;HD;TL;NOT_CONS_NIL;];
689   STRIP_TAC;
690   ASM_MESON_TAC[APPEND;];
691   ASM_MESON_TAC[APPEND;];
692   REWRITE_TAC[SUBLIST_CONS_CONS];
693   ASM_MESON_TAC[];
694   EQ_TAC;
695   STRIP_TAC;
696   MATCH_MP_TAC SUBLIST_CONS;
697   CLAIM `SUBLIST (CONS h (APPEND t l3)) (APPEND t' l3)`;
698   ASM_MESON_TAC[SUBLIST_NEQ];
699   STRIP_TAC;
700   ASM_MESON_TAC[APPEND;];
701   ASM_REWRITE_TAC[NOT_CONS_NIL;SUBLIST;HD;TL];
702   STRIP_TAC;
703   ASM_MESON_TAC[APPEND;];
704 ]);;
705 (* }}} *)
706
707 let SUBLIST_TRANS2 = REWRITE_RULE[IMP_AND_THM] SUBLIST_TRANS;;
708
709 let APPEND_CONS = prove_by_refinement(
710   `!h l1 l2. APPEND l1 (CONS h l2) = APPEND (APPEND l1 [h]) l2`,
711 (* {{{ Proof *)
712 [
713   STRIP_TAC;
714   REPEAT LIST_INDUCT_TAC THEN REWRITE_TAC[APPEND_NIL;APPEND];
715   ASM_MESON_TAC[];
716 ]);;
717 (* }}} *)
718
719 let SUBLIST_APPEND = prove_by_refinement(
720   `!l1 l2 m1 m2. SUBLIST l1 l2 ==> SUBLIST m1 m2 ==>
721     SUBLIST (APPEND l1 m1) (APPEND l2 m2)`,
722 (* {{{ Proof *)
723 [
724   LIST_INDUCT_TAC;
725   REWRITE_TAC[SUBLIST_NIL;APPEND];
726   LIST_INDUCT_TAC;
727   REWRITE_TAC[APPEND];
728   REPEAT STRIP_TAC;
729   POP_ASSUM (fun x -> FIRST_ASSUM (fun y -> ASSUME_TAC (MATCH_MP y x) THEN ASSUME_TAC x));
730   REWRITE_TAC[APPEND];
731   ASM_MESON_TAC[SUBLIST_CONS];
732   LIST_INDUCT_TAC;
733   MESON_TAC[SUBLIST;NOT_CONS_NIL];
734   CASES_ON `h = h'`;
735   POP_ASSUM (REWRITE_ALL o list);
736   REWRITE_TAC[SUBLIST_CONS_CONS];
737   REWRITE_TAC[SUBLIST_CONS_CONS;APPEND;];
738   ASM_MESON_TAC[];
739   REPEAT STRIP_TAC;
740   CLAIM `SUBLIST (CONS h t) t'`;
741   ASM_MESON_TAC[SUBLIST_NEQ];
742   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP y x)));
743   POP_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
744   ASM_MESON_TAC[APPEND;SUBLIST_CONS];
745 ]);;
746 (* }}} *)
747
748 let SUBLIST_APPEND2 = REWRITE_RULE[IMP_AND_THM] SUBLIST_APPEND;;
749
750 let ROL_APPEND2 = prove_by_refinement(
751   `!l2 l1. real_ordered_list (APPEND l1 l2) ==>
752            real_ordered_list (APPEND l1 (BUTLAST l2))`,
753 (* {{{ Proof *)
754 [
755   REPEAT STRIP_TAC;
756   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ROL_SUBLIST);
757   EXISTS_TAC `APPEND l1 l2`;
758   ASM_REWRITE_TAC[SUBLIST_APPEND_HD;SUBLIST_BUTLAST];
759 ]);;
760 (* }}} *)
761
762 let PL_LEM = prove_by_refinement(
763   `!l. ~(l = []) ==> ~(TL (partition_line l) = [])`,
764 (* {{{ Proof *)
765 [
766   LIST_INDUCT_TAC;
767   REWRITE_TAC[];
768   STRIP_TAC;
769   REWRITE_TAC[partition_line];
770   ASM_MESON_TAC[NOT_CONS_NIL;APPEND;TL];
771 ]);;
772 (* }}} *)
773
774 let HD_APPEND2 = prove_by_refinement(
775   `!l m. ~(l = []) ==> (HD (APPEND l m) = HD l)`,
776 (* {{{ Proof *)
777
778 [
779   LIST_INDUCT_TAC;
780   REWRITE_TAC[];
781   REPEAT STRIP_TAC;
782   REWRITE_TAC[APPEND;HD];
783 ]);;
784
785 (* }}} *)
786
787 let BUTLAST_TL = prove_by_refinement(
788   `!l. LENGTH l > 1 ==> (BUTLAST (TL l) = TL (BUTLAST l))`,
789 (* {{{ Proof *)
790 [
791   LIST_INDUCT_TAC;
792   REWRITE_TAC[LENGTH] THEN ARITH_TAC;
793   REWRITE_TAC[LENGTH];
794   STRIP_TAC;
795   REWRITE_TAC[TL;BUTLAST];
796   COND_CASES_TAC;
797   REWRITE_ASSUMS [GSYM LENGTH_0];
798   REPEAT (POP_ASSUM MP_TAC) THEN ARITH_TAC;
799   REWRITE_ASSUMS[NOT_NIL];
800   POP_ASSUM MP_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[];
801   REWRITE_TAC[TL;BUTLAST];
802 ]);;
803 (* }}} *)
804
805 let APPEND_TL = prove_by_refinement(
806   `!m l. ~(l = []) ==> (APPEND (TL l) m = TL (APPEND l m))`,
807 (* {{{ Proof *)
808 [
809   STRIP_TAC;
810   LIST_INDUCT_TAC;
811   REWRITE_TAC[];
812   REWRITE_TAC[APPEND;TL];
813 ]);;
814 (* }}} *)
815
816 let APPEND_HD = prove_by_refinement(
817   `!m l. ~(l = []) ==> (HD (APPEND l m) = HD l)`,
818 (* {{{ Proof *)
819 [
820   STRIP_TAC;
821   LIST_INDUCT_TAC;
822   REWRITE_TAC[];
823   STRIP_TAC;
824   REWRITE_TAC[APPEND;HD];
825 ]);;
826 (* }}} *)
827
828 let PL_LEM2 = prove_by_refinement(
829   `!l. ~(l = []) ==> LENGTH (partition_line l) > 1`,
830 (* {{{ Proof *)
831 [
832   LIST_INDUCT_TAC THEN REWRITE_TAC[];
833   REWRITE_TAC[partition_line];
834   STRIP_TAC;
835   COND_CASES_TAC;
836   REWRITE_TAC[LENGTH] THEN ARITH_TAC;
837   REWRITE_TAC[APPEND;LENGTH] THEN ARITH_TAC;
838 ]);;
839 (* }}} *)
840
841 let BUTLAST_APPEND = prove_by_refinement(
842   `!l m. ~(m = []) ==>
843      (BUTLAST (APPEND l m) = APPEND l (BUTLAST m))`,
844 (* {{{ Proof *)
845 [
846   LIST_INDUCT_TAC;
847   REWRITE_TAC[APPEND];
848   REPEAT STRIP_TAC;
849   REWRITE_TAC[APPEND;BUTLAST];
850   ASM_MESON_TAC[APPEND_EQ_NIL];
851 ]);;
852 (* }}} *)
853
854 let LENGTH_TL1 = prove_by_refinement(
855   `!l. LENGTH l > 1 ==> ~(TL l = [])`,
856 (* {{{ Proof *)
857 [
858   LIST_INDUCT_TAC;
859   REWRITE_TAC[LENGTH]  THEN ARITH_TAC;
860   REWRITE_TAC[LENGTH;TL];
861   REPEAT STRIP_TAC;
862   POP_ASSUM (REWRITE_ASSUMS o list);
863   REWRITE_ASSUMS[LENGTH];
864   POP_ASSUM MP_TAC THEN ARITH_TAC;
865 ]);;
866 (* }}} *)
867
868 let PL_BUTLAST = prove_by_refinement(
869   `!l. ~(l = []) ==> ~(BUTLAST (partition_line l) = [])`,
870 (* {{{ Proof *)
871 [
872   LIST_INDUCT_TAC;
873   REWRITE_TAC[];
874   REWRITE_TAC[partition_line];
875   COND_CASES_TAC;
876   (* XXX REWRITE_TAC works here, but not MESON_TAC *)
877   REWRITE_TAC[APPEND;NOT_CONS_NIL;BUTLAST];
878   REWRITE_TAC[APPEND;NOT_CONS_NIL;BUTLAST];
879 ]);;
880 (* }}} *)
881
882 let PARTITION_LINE_APPEND = prove_by_refinement(
883   `!h t l. ~(l = []) ==>
884     (partition_line (APPEND l (CONS h t)) =
885       APPEND (BUTLAST (partition_line l))
886         (CONS (\x. LAST l < x /\ x < h)
887           (TL (partition_line (CONS h t)))))`,
888 (* {{{ Proof *)
889 [
890   STRIP_TAC THEN STRIP_TAC;
891   LIST_INDUCT_TAC;
892   REWRITE_TAC[];
893   DISCH_THEN (fun x -> ALL_TAC);
894   CASES_ON `t' = []`;
895   POP_ASSUM (REWRITE_ALL o list);
896   REWRITE_TAC[HD;APPEND;partition_line;BUTLAST;LAST;TL;NOT_CONS_NIL;];
897   POP_ASSUM (fun x -> REWRITE_ASSUMS [x] THEN ASSUME_TAC x);
898   REWRITE_TAC[APPEND];
899   CONV_TAC (LAND_CONV (REWRITE_CONV[partition_line]));
900   COND_CASES_TAC;
901   ASM_MESON_TAC[NOT_CONS_NIL;APPEND_EQ_NIL];
902   POP_ASSUM (fun x -> ALL_TAC);
903   ASM_REWRITE_TAC[];
904   ASM_REWRITE_TAC[LAST];
905   ASM_SIMP_TAC[APPEND_HD];
906   CONV_TAC (RAND_CONV (LAND_CONV (RAND_CONV (REWRITE_CONV[partition_line]))));
907   ASM_REWRITE_TAC[];
908   REWRITE_TAC[APPEND;BUTLAST;NOT_CONS_NIL;];
909   REPEAT AP_TERM_TAC;
910   COND_CASES_TAC;
911   ASM_MESON_TAC[PL_LEM2;LENGTH_TL1];
912   REWRITE_TAC[APPEND];
913   AP_TERM_TAC;
914   MP_TAC (ISPEC `t':real list` PL_LEM2);
915   ASM_REWRITE_TAC[];
916   STRIP_TAC;
917   ASM_SIMP_TAC[BUTLAST_TL];
918   MP_TAC (ISPEC `t':real list` PL_BUTLAST);
919   ASM_REWRITE_TAC[];
920   STRIP_TAC;
921   ASM_SIMP_TAC[APPEND_TL];
922 ]);;
923 (* }}} *)
924
925 let HD_TL = prove_by_refinement(
926   `!l. ~(l = []) ==> (l = CONS (HD l) (TL l))`,
927 (* {{{ Proof *)
928 [
929   LIST_INDUCT_TAC;
930   REWRITE_TAC[];
931   REWRITE_TAC[HD;TL];
932 ]);;
933 (* }}} *)
934
935 let HD_LEM = prove_by_refinement(
936   `!l1 l2. (TL l1 = l2) <=> (CONS (HD l1) (TL l1) = CONS (HD l1) l2)`,
937 (* {{{ Proof *)
938 [
939   MESON_TAC[CONS_11];
940 ]);;
941 (* }}} *)
942
943 let rec LENGTH_N n ty =
944   let zero = `0` in
945   let neg = `(~)` in
946   let imp_thm = TAUT `(a ==> b) ==> (b ==> a) ==> (a <=> b)` in
947   match n with
948     0 -> CONJUNCT1 LENGTH
949   | 1 -> LENGTH_SING
950   | n ->
951       let len_tm = mk_const ("LENGTH",[ty,aty]) in
952       let tl_tm = mk_const ("TL",[ty,aty]) in
953       let hd_tm = mk_const ("HD",[ty,aty]) in
954       let t = mk_var("t",mk_type("list",[ty])) in
955       let n_tm = mk_small_numeral n in
956       let pren_tm = mk_small_numeral (n - 1) in
957       let len_thm = ASSUME (mk_eq(mk_comb(len_tm,t),n_tm)) in
958       let pre_thm = LENGTH_N (n - 1) ty in
959       let n_nz = prove(mk_neg(mk_eq(n_tm,zero)),ARITH_TAC) in
960       let not_nil_thm = EQ_MP (REWRITE_RULE[len_thm] (AP_TERM neg (ISPEC t LENGTH_0))) n_nz in
961       let n_suc = prove(mk_eq(n_tm,mk_comb(`SUC`,pren_tm)),ARITH_TAC) in
962       let len_tl = REWRITE_RULE[n_suc;PRE;ISPEC (mk_comb(tl_tm,t)) pre_thm;len_thm] (MATCH_MP LENGTH_TL not_nil_thm) in
963       let cons_thm = MATCH_MP (ISPEC t HD_TL) not_nil_thm in
964       let hd_thm = ONCE_REWRITE_RULE[HD_LEM] len_tl in
965       let thm = REWRITE_RULE[GSYM cons_thm] hd_thm in
966       let x0 = mk_var("x" ^ string_of_int n,ty) in
967       let hdt = mk_comb(hd_tm,t) in
968       let ex_thm = EXISTS (mk_exists(x0,subst[x0,hdt] (concl thm)),mk_comb(hd_tm,t)) thm in
969       let left = DISCH (concl len_thm) ex_thm in
970       let right = prove(mk_imp(concl ex_thm,concl len_thm),REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[LENGTH] THEN ARITH_TAC) in
971         GEN_ALL(MATCH_MPL[imp_thm;left;right]);;
972
973 let BUTLAST_LENGTH = prove_by_refinement(
974   `!l. ~(l = []) ==> (LENGTH (BUTLAST l) = PRE (LENGTH l))`,
975 (* {{{ Proof *)
976 [
977   LIST_INDUCT_TAC THEN REWRITE_TAC[];
978   REWRITE_TAC[BUTLAST;LENGTH];
979   COND_CASES_TAC;
980   ASM_REWRITE_TAC[NOT_CONS_NIL;LENGTH;];
981   ARITH_TAC;
982   ASM_REWRITE_TAC[NOT_CONS_NIL;LENGTH;];
983   ASM_SIMP_TAC[];
984   MATCH_MP_TAC (ARITH_RULE `~(n = 0) ==> (SUC(PRE n) = PRE(SUC n))`);
985   ASM_MESON_TAC[LENGTH_0];
986 ]);;
987 (* }}} *)
988
989 let ALL2_LEM = prove_by_refinement(
990   `!a b x y s eqs pts sgns.
991    ALL2 (interpsigns eqs) (partition_line
992     (APPEND pts [x; y])) (APPEND sgns [a; b; s; s; s]) ==>
993    ALL2 (interpsigns eqs) (partition_line
994     (APPEND pts [x])) (APPEND sgns [a; b; s])`,
995 (* {{{ Proof *)
996
997 [
998   REPEAT STRIP_TAC;
999   DISJ_CASES_TAC (ISPEC `pts:real list` list_CASES);
1000   POP_ASSUM (REWRITE_ALL o list);
1001   REWRITE_ALL[APPEND;partition_line;NOT_CONS_NIL;HD;TL];
1002   CLAIM `sgns = []`;
1003   CLAIM `LENGTH [\x'. x' < x; \x'. x' = x; \x'. x < x' /\ x' < y; \x. x = y; \x. y < x] = LENGTH (APPEND sgns [a; b; s; s; s])`;
1004   ASM_MESON_TAC[ALL2_LENGTH];
1005   REWRITE_TAC[LENGTH;LENGTH_APPEND;GSYM LENGTH_0];
1006   ARITH_TAC;
1007   DISCH_THEN (REWRITE_ALL o list);
1008   REWRITE_ALL [APPEND;ALL2;];
1009   POP_ASSUM MP_TAC THEN STRIP_TAC;
1010   ASM_REWRITE_TAC[];
1011   MATCH_MP_TAC INTERPSIGNS_SUBSET;
1012   EXISTS_TAC `\z. x < z /\ z < y \/ (z = y) \/ y < z`;
1013   STRIP_TAC;
1014   MATCH_MP_TAC INTERPSIGNS_CONJ;
1015   ASM_REWRITE_TAC[];
1016   MATCH_MP_TAC INTERPSIGNS_CONJ;
1017   ASM_REWRITE_TAC[];
1018   REWRITE_TAC[SUBSET;IN];
1019   REAL_ARITH_TAC;
1020   (* save *)
1021   POP_ASSUM MP_TAC THEN STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
1022   POP_ASSUM MP_TAC;
1023   ASM_SIMP_TAC[PARTITION_LINE_APPEND;NOT_CONS_NIL;];
1024   STRIP_TAC;
1025   CLAIM `LENGTH (APPEND (BUTLAST (partition_line (CONS (h:real) t))) (CONS (\x'. LAST (CONS h t) < x' /\ x' < x) (TL (partition_line [x; y])))) = LENGTH (APPEND sgns [(a:sign list); b; s; s; s])`;
1026   ASM_MESON_TAC[ALL2_LENGTH];
1027   CLAIM `~(partition_line [x; y] = [])`;
1028   REWRITE_TAC[APPEND;NOT_CONS_NIL;partition_line;];
1029   REWRITE_TAC[TL;APPEND;NOT_CONS_NIL;LENGTH_APPEND;PARTITION_LINE_LENGTH;LENGTH;LENGTH_TL];
1030   STRIP_TAC;
1031   ASM_SIMP_TAC[LENGTH_TL];
1032   REWRITE_TAC[partition_line;NOT_CONS_NIL;];
1033   COND_CASES_TAC;
1034   POP_ASSUM (REWRITE_ALL o list);
1035   REWRITE_TAC[HD;LENGTH;APPEND;TL;BUTLAST;NOT_CONS_NIL;];
1036   ARITH_SIMP_TAC[];
1037   STRIP_TAC;
1038   CLAIM `LENGTH sgns = 2`;
1039   POP_ASSUM MP_TAC THEN ARITH_TAC;
1040   REWRITE_TAC[LENGTH_PAIR];
1041   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
1042   REWRITE_ALL[partition_line;BUTLAST;LAST;ALL2;TL;APPEND;NOT_CONS_NIL;LENGTH_APPEND;PARTITION_LINE_LENGTH;LENGTH;LENGTH_TL];
1043   ASM_REWRITE_TAC[];
1044   POP_ASSUM (fun x -> ALL_TAC);
1045   POP_ASSUM (fun x -> ALL_TAC);
1046   POP_ASSUM MP_TAC THEN STRIP_TAC;
1047   MATCH_MP_TAC INTERPSIGNS_SUBSET;
1048   REWRITE_ASSUMS[HD];
1049   EXISTS_TAC `\z. x < z /\ z < y \/ (z = y) \/ y < z`;
1050   STRIP_TAC;
1051   MATCH_MP_TAC INTERPSIGNS_CONJ;
1052   ASM_REWRITE_TAC[];
1053   MATCH_MP_TAC INTERPSIGNS_CONJ;
1054   ASM_REWRITE_TAC[];
1055   REWRITE_TAC[SUBSET;IN];
1056   REAL_ARITH_TAC;
1057   (* save *)
1058   REWRITE_ALL[HD;partition_line;BUTLAST;LAST;ALL2;TL;APPEND;NOT_CONS_NIL;LENGTH_APPEND;PARTITION_LINE_LENGTH;LENGTH;LENGTH_TL];
1059   POP_ASSUM (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
1060   COND_CASES_TAC;
1061   ASM_MESON_TAC[PL_LEM2;LENGTH_TL1];
1062   ARITH_SIMP_TAC[LENGTH;];
1063   ASM_SIMP_TAC[PARTITION_LINE_LENGTH];
1064   ASM_SIMP_TAC[BUTLAST_LENGTH];
1065   CLAIM `~(partition_line t =  [])`;
1066   REWRITE_ASSUMS[NOT_NIL];
1067   POP_ASSUM (fun x -> ALL_TAC);
1068   POP_ASSUM MP_TAC THEN STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
1069   REWRITE_TAC[partition_line;NOT_CONS_NIL;list_CASES;APPEND;];
1070   COND_CASES_TAC;
1071   MESON_TAC[NOT_CONS_NIL];
1072   MESON_TAC[NOT_CONS_NIL];
1073   STRIP_TAC;
1074   ASM_SIMP_TAC[LENGTH_TL];
1075   STRIP_TAC;
1076   MP_TAC (ISPEC `t:real list` PARTITION_LINE_LENGTH);
1077   STRIP_TAC;
1078   CLAIM `~(LENGTH (partition_line t) = 0)`;
1079   POP_ASSUM MP_TAC THEN ARITH_TAC;
1080   STRIP_TAC;
1081   FIRST_ASSUM (MP_TAC o MATCH_MP PL_LEM2);
1082   STRIP_TAC;
1083   CLAIM `~(PRE (LENGTH (partition_line t)) = 0)`;
1084   POP_ASSUM MP_TAC THEN ARITH_TAC;
1085   STRIP_TAC;
1086   CLAIM `SUC(LENGTH (partition_line t)) = LENGTH sgns`;
1087   REPEAT_N 5 (POP_ASSUM MP_TAC) THEN ARITH_TAC;
1088   DISCH_THEN (ASSUME_TAC o GSYM);
1089   POP_ASSUM (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
1090   REWRITE_TAC[GSYM APPEND];
1091   CLAIM `(ALL2 (interpsigns eqs) (BUTLAST
1092         (CONS (\x. x < h)
1093         (CONS (\x. x = h)
1094         (CONS (\x. h < x /\ x < HD t) (TL (partition_line t))))))
1095         sgns) /\ (ALL2 (interpsigns eqs) [\x'. LAST t < x' /\ x' < x; \x'. x' = x; \x'. x < x' /\
1096                                                       x' < y;
1097        \x. x = y; \x. y < x] [a; b; s; s; s])`;
1098   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_APPEND_LENGTH);
1099   REPEAT STRIP_TAC;
1100   ASM_REWRITE_TAC[BUTLAST;NOT_CONS_NIL;LENGTH;];
1101   ASM_SIMP_TAC[BUTLAST_LENGTH;LENGTH_TL];
1102   CLAIM `~(LENGTH t = 0)`;
1103   ASM_MESON_TAC[LENGTH_0];
1104   ARITH_TAC;
1105   ASM_REWRITE_TAC[];
1106   REPEAT STRIP_TAC;
1107   MATCH_MP_TAC ALL2_APPEND;
1108   STRIP_TAC;
1109   REWRITE_ASSUMS[BUTLAST;NOT_CONS_NIL;];
1110   ASM_MESON_TAC[];
1111   REWRITE_ALL[BUTLAST;LAST;ALL2;TL;APPEND;NOT_CONS_NIL;LENGTH_APPEND;PARTITION_LINE_LENGTH;LENGTH;LENGTH_TL];
1112   ASM_REWRITE_TAC[];
1113   MATCH_MP_TAC INTERPSIGNS_SUBSET;
1114   EXISTS_TAC `\z. x < z /\ z < y \/ (z = y) \/ y < z`;
1115   STRIP_TAC;
1116   MATCH_MP_TAC INTERPSIGNS_CONJ;
1117   ASM_REWRITE_TAC[];
1118   MATCH_MP_TAC INTERPSIGNS_CONJ;
1119   ASM_REWRITE_TAC[];
1120   REWRITE_TAC[SUBSET;IN];
1121   REAL_ARITH_TAC;
1122 ]);;
1123
1124 (* }}} *)
1125
1126 let INTERPMAT_TRIO_TL = prove_by_refinement(
1127   `!a b x y s eqs pts sgns.
1128      interpmat (APPEND pts [x; y]) eqs
1129         (APPEND sgns [a; b; s; s; s]) ==>
1130      interpmat (APPEND pts [x]) eqs (APPEND sgns [a; b; s])`,
1131 (* {{{ Proof *)
1132 [
1133   REWRITE_TAC[interpmat];
1134   REPEAT STRIP_TAC;
1135   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ROL_SUBLIST);
1136   EXISTS_TAC `APPEND pts [x; y]`;
1137   ASM_REWRITE_TAC[SUBLIST_APPEND_HD;SUBLIST_CONS_CONS;SUBLIST_NIL];
1138   MATCH_MP_TAC ALL2_LEM;
1139   ASM_MESON_TAC[];
1140 ]);;
1141 (* }}} *)
1142
1143
1144 let LAST_APPEND = prove_by_refinement(
1145   `!l1 l2. ~(l2 = []) ==> (LAST (APPEND l1 l2) = LAST l2)`,
1146 (* {{{ Proof *)
1147 [
1148   LIST_INDUCT_TAC;
1149   REWRITE_TAC[APPEND];
1150   REWRITE_TAC[APPEND;LAST;];
1151   REPEAT STRIP_TAC;
1152   ASM_REWRITE_TAC[APPEND_EQ_NIL];
1153   ASM_MESON_TAC[];
1154 ]);;
1155 (* }}} *)
1156
1157 let APPEND_APPEND = prove_by_refinement(
1158   `!l1 l2 l3. APPEND (APPEND l1 l2) l3 = APPEND l1 (APPEND l2 l3)`,
1159 (* {{{ Proof *)
1160 [
1161   LIST_INDUCT_TAC;
1162   REWRITE_TAC[APPEND];
1163   REWRITE_TAC[APPEND];
1164   ASM_MESON_TAC[];
1165 ]);;
1166 (* }}} *)
1167
1168 let ALL2_LEM2 = prove_by_refinement(
1169   `!a b x y s eqs pts sgns qts rgns.
1170    ALL2 (interpsigns eqs) (partition_line
1171     (APPEND pts (CONS x (CONS y qts))))
1172     (APPEND sgns (CONS a (CONS b
1173       (CONS s (CONS s (CONS s rgns)))))) ==>
1174    (LENGTH sgns = 2 * LENGTH pts) ==>
1175    ALL2 (interpsigns eqs) (partition_line
1176     (APPEND pts (CONS x qts)))
1177     (APPEND sgns (CONS a (CONS b (CONS s rgns))))`,
1178 (* {{{ Proof *)
1179
1180 [
1181   REPEAT STRIP_TAC;
1182   CLAIM `LENGTH (partition_line
1183     (APPEND pts (CONS x (CONS y qts)))) =
1184     LENGTH (APPEND sgns (CONS (a:sign list) (CONS b
1185       (CONS s (CONS s (CONS s rgns))))))`;
1186   ASM_MESON_TAC[ALL2_LENGTH];
1187   ASM_REWRITE_TAC[PARTITION_LINE_LENGTH;LENGTH;APPEND;LENGTH_APPEND];
1188   STRIP_TAC;
1189   CLAIM `LENGTH rgns = 2 * LENGTH qts`;
1190   POP_ASSUM MP_TAC THEN ARITH_TAC;
1191   POP_ASSUM (fun x -> ALL_TAC);
1192   STRIP_TAC;
1193   CASES_ON `pts = []`;
1194   POP_ASSUM (REWRITE_ALL o list);
1195   CLAIM `sgns = []`;
1196   ASM_MESON_TAC[ARITH_RULE `2 * 0 = 0`;LENGTH_0;LENGTH];
1197   DISCH_THEN (REWRITE_ALL o list);
1198   REWRITE_ALL[APPEND];
1199   REPEAT (POP_ASSUM MP_TAC);
1200   REWRITE_TAC[partition_line;NOT_CONS_NIL;HD;TL;APPEND;];
1201   COND_CASES_TAC;
1202   POP_ASSUM (REWRITE_ALL o list);
1203   REWRITE_TAC[ALL2;partition_line;NOT_CONS_NIL;HD;TL;APPEND;];
1204   REPEAT_N 3 STRIP_TAC;
1205   ASM_REWRITE_TAC[];
1206   MATCH_MP_TAC INTERPSIGNS_SUBSET;
1207   EXISTS_TAC `\(z:real). x < z /\ z < y \/ (z = y) \/ y < z`;
1208   STRIP_TAC;
1209   MATCH_MP_TAC INTERPSIGNS_CONJ;
1210   ASM_REWRITE_TAC[];
1211   MATCH_MP_TAC INTERPSIGNS_CONJ;
1212   ASM_REWRITE_TAC[];
1213   REWRITE_TAC[SUBSET;IN];
1214   REAL_ARITH_TAC;
1215   ASM_REWRITE_TAC[];
1216   REWRITE_TAC[ALL2;partition_line;NOT_CONS_NIL;HD;TL;APPEND;];
1217   REPEAT_N 3 STRIP_TAC;
1218   ASM_REWRITE_TAC[];
1219   MATCH_MP_TAC INTERPSIGNS_SUBSET;
1220   EXISTS_TAC `\(z:real). x < z /\ z < y \/ (z = y) \/ y < z /\ z < HD qts`;
1221   STRIP_TAC;
1222   MATCH_MP_TAC INTERPSIGNS_CONJ;
1223   ASM_REWRITE_TAC[];
1224   MATCH_MP_TAC INTERPSIGNS_CONJ;
1225   ASM_REWRITE_TAC[];
1226   REWRITE_TAC[SUBSET;IN];
1227   REAL_ARITH_TAC;
1228   (* save *)
1229   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
1230   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
1231   REPEAT STRIP_TAC;
1232   MATCH_MP_TAC ALL2_APPEND;
1233   CLAIM `LENGTH (BUTLAST (partition_line pts)) = LENGTH sgns`;
1234   ASM_REWRITE_TAC[];
1235   ASSUME_TAC (ISPEC `pts:real list` PARTITION_LINE_NOT_NIL);
1236   ASM_SIMP_TAC[BUTLAST_LENGTH];
1237   REWRITE_TAC[PARTITION_LINE_LENGTH];
1238   ARITH_TAC;
1239   STRIP_TAC;
1240   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
1241   ASM_SIMP_TAC[ALL2_SPLIT];
1242   REWRITE_ALL[partition_line;NOT_CONS_NIL;HD;TL;];
1243   COND_CASES_TAC;
1244   REWRITE_TAC[ALL2;TL;HD;APPEND;];
1245   REPEAT_N 4 STRIP_TAC;
1246   ASM_REWRITE_TAC[];
1247   MATCH_MP_TAC INTERPSIGNS_SUBSET;
1248   EXISTS_TAC `\(z:real). x < z /\ z < y \/ (z = y) \/ y < z`;
1249   STRIP_TAC;
1250   MATCH_MP_TAC INTERPSIGNS_CONJ;
1251   ASM_REWRITE_TAC[];
1252   MATCH_MP_TAC INTERPSIGNS_CONJ;
1253   ASM_REWRITE_TAC[];
1254   REWRITE_TAC[SUBSET;IN];
1255   REAL_ARITH_TAC;
1256   (* save *)
1257   REWRITE_TAC[APPEND;TL;HD;ALL2;];
1258   REPEAT_N 4 STRIP_TAC;
1259   ASM_REWRITE_TAC[];
1260   MATCH_MP_TAC INTERPSIGNS_SUBSET;
1261   EXISTS_TAC `\(z:real). x < z /\ z < y \/ (z = y) \/ y < z /\ z < HD qts`;
1262   STRIP_TAC;
1263   MATCH_MP_TAC INTERPSIGNS_CONJ;
1264   ASM_REWRITE_TAC[];
1265   MATCH_MP_TAC INTERPSIGNS_CONJ;
1266   ASM_REWRITE_TAC[];
1267   REWRITE_TAC[SUBSET;IN];
1268   REAL_ARITH_TAC;
1269 ]);;
1270
1271 (* }}} *)
1272
1273 let INTERPMAT_TRIO_INNER = prove_by_refinement(
1274   `!a b x y s eqs qts rgns pts sgns.
1275      interpmat (APPEND pts (CONS x (CONS y qts))) eqs
1276         (APPEND sgns (CONS a (CONS b
1277           (CONS s (CONS s (CONS s rgns)))))) ==>
1278         (LENGTH sgns = 2 * LENGTH pts) ==>
1279        interpmat (APPEND pts (CONS x qts)) eqs
1280         (APPEND sgns (CONS a (CONS b (CONS s rgns))))`,
1281 (* {{{ Proof *)
1282 [
1283   REWRITE_TAC[interpmat];
1284   REPEAT STRIP_TAC;
1285   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ROL_SUBLIST);
1286   EXISTS_TAC `(APPEND pts (CONS x (CONS y qts)))`;
1287   ASM_REWRITE_TAC[SUBLIST_APPEND_HD;SUBLIST_CONS_CONS;SUBLIST_NIL];
1288   MESON_TAC[SUBLIST_CONS;SUBLIST_ID];
1289   ASM_MESON_TAC[ALL2_LEM2];
1290 ]);;
1291 (* }}} *)
1292
1293 let INTERPMAT_SING = prove_by_refinement(
1294   `!x l.  interpmat [x] eqs [l; l; l] ==> interpmat [] eqs [l]`,
1295 (* {{{ Proof *)
1296 [
1297   REWRITE_TAC[interpmat];
1298   REWRITE_TAC[ROL_SING;partition_line;ROL_NIL;ALL2;];
1299   REPEAT STRIP_TAC;
1300   MATCH_MP_TAC INTERPSIGNS_SUBSET;
1301   EXISTS_TAC `\(z:real). x < z \/ (z = x) \/ z < x`;
1302   STRIP_TAC;
1303   MATCH_MP_TAC INTERPSIGNS_CONJ;
1304   ASM_REWRITE_TAC[];
1305   MATCH_MP_TAC INTERPSIGNS_CONJ;
1306   ASM_REWRITE_TAC[];
1307   REWRITE_TAC[SUBSET;IN];
1308   REAL_ARITH_TAC;
1309 ]);;
1310 (* }}} *)
1311
1312 let INFERISIGN_POS_POS_POS = prove_by_refinement(
1313   `!y z p pts qts eqs sgns rgns r1 r2 r3.
1314      interpmat (APPEND pts (CONS y (CONS z qts)))
1315       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
1316         (APPEND sgns
1317           (CONS (CONS Pos r1)
1318            (CONS (CONS Unknown (CONS Pos r2))
1319             (CONS (CONS Pos r3) rgns)))) ==>
1320      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
1321     interpmat (APPEND pts (CONS y (CONS z qts)))
1322       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
1323         (APPEND sgns
1324           (CONS (CONS Pos r1)
1325            (CONS (CONS Pos (CONS Pos r2))
1326             (CONS (CONS Pos r3) rgns))))`,
1327 (* {{{ Proof *)
1328 [
1329   REWRITE_TAC[interpmat];
1330   REPEAT STRIP_TAC;
1331   ASM_REWRITE_TAC[];
1332   CLAIM `~(sgns = [])`;
1333   REWRITE_TAC[GSYM LENGTH_0];
1334   DISCH_THEN (REWRITE_ALL o list);
1335   POP_ASSUM MP_TAC THEN ARITH_TAC;
1336   STRIP_TAC;
1337   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) = LENGTH (APPEND sgns (CONS (CONS Pos r1) (CONS (CONS Unknown (CONS Pos r2)) (CONS (CONS Pos r3) rgns))))`;
1338   ASM_MESON_TAC[ALL2_LENGTH];
1339   STRIP_TAC;
1340   (* save *)
1341   CASES_ON `pts = []`;
1342   POP_ASSUM (REWRITE_ALL o list);
1343   REWRITE_ALL[APPEND;];
1344   CLAIM `LENGTH sgns = 1`;
1345   POP_ASSUM (fun x -> ALL_TAC);
1346   REWRITE_ALL[LENGTH];
1347   ASM_REWRITE_TAC[];
1348   POP_ASSUM MP_TAC THEN ARITH_TAC;
1349   REWRITE_TAC[LENGTH_1];
1350   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
1351   REWRITE_ALL[APPEND];
1352   REPEAT (POP_ASSUM MP_TAC);
1353   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
1354   COND_CASES_TAC;
1355   POP_ASSUM (REWRITE_ALL o list);
1356   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
1357   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1358   REWRITE_ALL[interpsigns;ALL2;];
1359   ASM_REWRITE_TAC[];
1360   REWRITE_TAC[interpsign];
1361   REWRITE_ALL[real_gt];
1362   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] pos_pos_neq_thm);
1363   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
1364   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1365   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
1366   ASM_MESON_TAC[];
1367   ASM_MESON_TAC[real_gt;];
1368   ASM_MESON_TAC[REAL_ARITH `x > y ==> ~(x = y)`];
1369   (* save *)
1370   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
1371   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1372   REWRITE_TAC[interpsign;real_gt;];
1373   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] pos_pos_neq_thm);
1374   REWRITE_ALL[interpsign;real_ordered_list;NOT_CONS_NIL;HD;ALL2;];
1375   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1376   REWRITE_ALL[real_gt];
1377   ASM_MESON_TAC[];
1378   ASM_MESON_TAC[real_gt;];
1379   ASM_MESON_TAC[REAL_ARITH `x > y ==> ~(x = y)`];
1380   (* save *)
1381   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
1382   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
1383   COND_CASES_TAC;
1384   POP_ASSUM (REWRITE_ALL o list);
1385   REWRITE_TAC[TL;HD;APPEND;ALL2;];
1386   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
1387   MESON_TAC[APPEND;APPEND_CONS];
1388   DISCH_THEN (REWRITE_ALL o list);
1389   REPEAT STRIP_TAC;
1390   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
1391   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
1392   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
1393   ARITH_TAC;
1394   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
1395   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
1396   REPEAT STRIP_TAC;
1397   REPEAT STRIP_TAC;
1398   MATCH_MP_TAC ALL2_APPEND;
1399   ASM_REWRITE_TAC[];
1400   REWRITE_ALL[ALL2;interpsigns;];
1401   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1402   REWRITE_ALL[interpsign;real_gt];
1403   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] pos_pos_neq_thm);
1404   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
1405   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1406   CLAIM `real_ordered_list [y; z]`;
1407   ASM_MESON_TAC[ROL_APPEND];
1408   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
1409   ASM_MESON_TAC[];
1410   ASM_MESON_TAC[real_gt;];
1411   ASM_MESON_TAC[REAL_ARITH `x < y ==> ~(x = y)`];
1412   (* save *)
1413   REWRITE_TAC[APPEND;TL;HD;ALL2;];
1414   REPEAT STRIP_TAC;
1415   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
1416   MESON_TAC[APPEND;APPEND_CONS];
1417   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
1418   REPEAT STRIP_TAC;
1419   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
1420   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
1421   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
1422   ARITH_TAC;
1423   REWRITE_ALL[TL;APPEND;HD];
1424   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
1425   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
1426   REPEAT STRIP_TAC;
1427   REPEAT STRIP_TAC;
1428   MATCH_MP_TAC ALL2_APPEND;
1429   ASM_REWRITE_TAC[];
1430   REWRITE_ALL[ALL2;interpsigns;];
1431   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1432   REWRITE_ALL[interpsign;real_gt];
1433   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] pos_pos_neq_thm);
1434   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
1435   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1436   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
1437   ASM_MESON_TAC[ROL_APPEND];
1438   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
1439   ASM_MESON_TAC[];
1440   ASM_MESON_TAC[real_gt;];
1441   ASM_MESON_TAC[REAL_ARITH `x < y ==> ~(x = y)`];
1442   ASM_MESON_TAC[REAL_ARITH `x < y ==> ~(x = y)`];
1443 ]);;
1444 (* }}} *)
1445
1446 let INFERISIGN_POS_POS_NEG = prove_by_refinement(
1447   `!y z p pts qts eqs sgns rgns r1 r2 r3.
1448      interpmat (APPEND pts (CONS y (CONS z qts)))
1449       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
1450         (APPEND sgns
1451           (CONS (CONS Pos r1)
1452            (CONS (CONS Unknown (CONS Neg r2))
1453             (CONS (CONS Pos r3) rgns)))) ==>
1454      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
1455     interpmat (APPEND pts (CONS y (CONS z qts)))
1456       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
1457         (APPEND sgns
1458           (CONS (CONS Pos r1)
1459            (CONS (CONS Pos (CONS Neg r2))
1460             (CONS (CONS Pos r3) rgns))))`,
1461 (* {{{ Proof *)
1462
1463 [
1464   REWRITE_TAC[interpmat];
1465   REPEAT STRIP_TAC;
1466   ASM_REWRITE_TAC[];
1467   CLAIM `~(sgns = [])`;
1468   REWRITE_TAC[GSYM LENGTH_0];
1469   DISCH_THEN (REWRITE_ALL o list);
1470   POP_ASSUM MP_TAC THEN ARITH_TAC;
1471   STRIP_TAC;
1472   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) = LENGTH (APPEND sgns (CONS (CONS Pos r1) (CONS (CONS Unknown (CONS Neg r2)) (CONS (CONS Pos r3) rgns))))`;
1473   ASM_MESON_TAC[ALL2_LENGTH];
1474   STRIP_TAC;
1475   (* save *)
1476   CASES_ON `pts = []`;
1477   POP_ASSUM (REWRITE_ALL o list);
1478   REWRITE_ALL[APPEND;];
1479   CLAIM `LENGTH sgns = 1`;
1480   POP_ASSUM (fun x -> ALL_TAC);
1481   REWRITE_ALL[LENGTH];
1482   ASM_REWRITE_TAC[];
1483   POP_ASSUM MP_TAC THEN ARITH_TAC;
1484   REWRITE_TAC[LENGTH_1];
1485   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
1486   REWRITE_ALL[APPEND];
1487   REPEAT (POP_ASSUM MP_TAC);
1488   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
1489   COND_CASES_TAC;
1490   POP_ASSUM (REWRITE_ALL o list);
1491   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
1492   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1493   REWRITE_ALL[interpsigns;ALL2;];
1494   ASM_REWRITE_TAC[];
1495   REWRITE_TAC[interpsign];
1496   REWRITE_ALL[real_gt];
1497   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] pos_pos_neq_thm);
1498   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
1499   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1500   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
1501   ASM_MESON_TAC[];
1502   ASM_MESON_TAC[real_gt;];
1503   ASM_MESON_TAC[REAL_ARITH `x < y ==> ~(x = y)`];
1504   (* save *)
1505   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
1506   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1507   REWRITE_TAC[interpsign;real_gt;];
1508   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] pos_pos_neq_thm);
1509   REWRITE_ALL[interpsign;real_ordered_list;NOT_CONS_NIL;HD;ALL2;];
1510   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1511   REWRITE_ALL[real_gt];
1512   ASM_MESON_TAC[];
1513   ASM_MESON_TAC[real_gt;];
1514   ASM_MESON_TAC[REAL_ARITH `x < y ==> ~(x = y)`];
1515   (* save *)
1516   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
1517   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
1518   COND_CASES_TAC;
1519   POP_ASSUM (REWRITE_ALL o list);
1520   REWRITE_TAC[TL;HD;APPEND;ALL2;];
1521   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
1522   MESON_TAC[APPEND;APPEND_CONS];
1523   DISCH_THEN (REWRITE_ALL o list);
1524   REPEAT STRIP_TAC;
1525   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
1526   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
1527   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
1528   ARITH_TAC;
1529   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
1530   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
1531   REPEAT STRIP_TAC;
1532   REPEAT STRIP_TAC;
1533   MATCH_MP_TAC ALL2_APPEND;
1534   ASM_REWRITE_TAC[];
1535   REWRITE_ALL[ALL2;interpsigns;];
1536   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1537   REWRITE_ALL[interpsign;real_gt];
1538   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] pos_pos_neq_thm);
1539   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
1540   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1541   CLAIM `real_ordered_list [y; z]`;
1542   ASM_MESON_TAC[ROL_APPEND];
1543   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
1544   ASM_MESON_TAC[];
1545   ASM_MESON_TAC[real_gt;];
1546   ASM_MESON_TAC[REAL_ARITH `x < y ==> ~(x = y)`];
1547   (* save *)
1548   REWRITE_TAC[APPEND;TL;HD;ALL2;];
1549   REPEAT STRIP_TAC;
1550   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
1551   MESON_TAC[APPEND;APPEND_CONS];
1552   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
1553   REPEAT STRIP_TAC;
1554   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
1555   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
1556   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
1557   ARITH_TAC;
1558   REWRITE_ALL[TL;APPEND;HD];
1559   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
1560   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
1561   REPEAT STRIP_TAC;
1562   REPEAT STRIP_TAC;
1563   MATCH_MP_TAC ALL2_APPEND;
1564   ASM_REWRITE_TAC[];
1565   REWRITE_ALL[ALL2;interpsigns;];
1566   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1567   REWRITE_ALL[interpsign;real_gt];
1568   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] pos_pos_neq_thm);
1569   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
1570   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1571   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
1572   ASM_MESON_TAC[ROL_APPEND];
1573   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
1574   ASM_MESON_TAC[];
1575   ASM_MESON_TAC[real_gt;];
1576   ASM_MESON_TAC[REAL_ARITH `x < y ==> ~(x = y)`];
1577   ASM_MESON_TAC[REAL_ARITH `x < y ==> ~(x = y)`];
1578 ]);;
1579
1580 (* }}} *)
1581
1582
1583 let INFERISIGN_NEG_NEG_POS = prove_by_refinement(
1584   `!y z p pts qts eqs sgns rgns r1 r2 r3.
1585      interpmat (APPEND pts (CONS y (CONS z qts)))
1586       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
1587         (APPEND sgns
1588           (CONS (CONS Neg r1)
1589            (CONS (CONS Unknown (CONS Pos r2))
1590             (CONS (CONS Neg r3) rgns)))) ==>
1591      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
1592     interpmat (APPEND pts (CONS y (CONS z qts)))
1593       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
1594         (APPEND sgns
1595           (CONS (CONS Neg r1)
1596            (CONS (CONS Neg (CONS Pos r2))
1597             (CONS (CONS Neg r3) rgns))))`,
1598 (* {{{ Proof *)
1599 [
1600   REWRITE_TAC[interpmat];
1601   REPEAT STRIP_TAC;
1602   ASM_REWRITE_TAC[];
1603   CLAIM `~(sgns = [])`;
1604   REWRITE_TAC[GSYM LENGTH_0];
1605   DISCH_THEN (REWRITE_ALL o list);
1606   POP_ASSUM MP_TAC THEN ARITH_TAC;
1607   STRIP_TAC;
1608   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) = LENGTH (APPEND sgns (CONS (CONS Neg r1) (CONS (CONS Unknown (CONS Pos r2)) (CONS (CONS Neg r3) rgns))))`;
1609   ASM_MESON_TAC[ALL2_LENGTH];
1610   STRIP_TAC;
1611   (* save *)
1612   CASES_ON `pts = []`;
1613   POP_ASSUM (REWRITE_ALL o list);
1614   REWRITE_ALL[APPEND;];
1615   CLAIM `LENGTH sgns = 1`;
1616   POP_ASSUM (fun x -> ALL_TAC);
1617   REWRITE_ALL[LENGTH];
1618   ASM_REWRITE_TAC[];
1619   POP_ASSUM MP_TAC THEN ARITH_TAC;
1620   REWRITE_TAC[LENGTH_1];
1621   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
1622   REWRITE_ALL[APPEND];
1623   REPEAT (POP_ASSUM MP_TAC);
1624   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
1625   COND_CASES_TAC;
1626   POP_ASSUM (REWRITE_ALL o list);
1627   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
1628   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1629   REWRITE_ALL[interpsigns;ALL2;];
1630   ASM_REWRITE_TAC[];
1631   REWRITE_TAC[interpsign];
1632   REWRITE_ALL[real_gt];
1633   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] neg_neg_neq_thm);
1634   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
1635   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1636   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
1637   ASM_MESON_TAC[];
1638   ASM_MESON_TAC[real_gt;];
1639   ASM_MESON_TAC[REAL_ARITH `x > y ==> ~(x = y)`];
1640   (* save *)
1641   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
1642   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1643   REWRITE_TAC[interpsign;real_gt;];
1644   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] neg_neg_neq_thm);
1645   REWRITE_ALL[interpsign;real_ordered_list;NOT_CONS_NIL;HD;ALL2;];
1646   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1647   REWRITE_ALL[real_gt];
1648   ASM_MESON_TAC[];
1649   ASM_MESON_TAC[real_gt;];
1650   ASM_MESON_TAC[REAL_ARITH `x > y ==> ~(x = y)`];
1651   (* save *)
1652   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
1653   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
1654   COND_CASES_TAC;
1655   POP_ASSUM (REWRITE_ALL o list);
1656   REWRITE_TAC[TL;HD;APPEND;ALL2;];
1657   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
1658   MESON_TAC[APPEND;APPEND_CONS];
1659   DISCH_THEN (REWRITE_ALL o list);
1660   REPEAT STRIP_TAC;
1661   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
1662   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
1663   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
1664   ARITH_TAC;
1665   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
1666   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
1667   REPEAT STRIP_TAC;
1668   REPEAT STRIP_TAC;
1669   MATCH_MP_TAC ALL2_APPEND;
1670   ASM_REWRITE_TAC[];
1671   REWRITE_ALL[ALL2;interpsigns;];
1672   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1673   REWRITE_ALL[interpsign;real_gt];
1674   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] neg_neg_neq_thm);
1675   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
1676   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1677   CLAIM `real_ordered_list [y; z]`;
1678   ASM_MESON_TAC[ROL_APPEND];
1679   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
1680   ASM_MESON_TAC[];
1681   ASM_MESON_TAC[real_gt;];
1682   ASM_MESON_TAC[REAL_ARITH `x < y ==> ~(x = y)`];
1683   (* save *)
1684   REWRITE_TAC[APPEND;TL;HD;ALL2;];
1685   REPEAT STRIP_TAC;
1686   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
1687   MESON_TAC[APPEND;APPEND_CONS];
1688   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
1689   REPEAT STRIP_TAC;
1690   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
1691   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
1692   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
1693   ARITH_TAC;
1694   REWRITE_ALL[TL;APPEND;HD];
1695   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
1696   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
1697   REPEAT STRIP_TAC;
1698   REPEAT STRIP_TAC;
1699   MATCH_MP_TAC ALL2_APPEND;
1700   ASM_REWRITE_TAC[];
1701   REWRITE_ALL[ALL2;interpsigns;];
1702   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1703   REWRITE_ALL[interpsign;real_gt];
1704   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] neg_neg_neq_thm);
1705   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
1706   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1707   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
1708   ASM_MESON_TAC[ROL_APPEND];
1709   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
1710   ASM_MESON_TAC[];
1711   ASM_MESON_TAC[real_gt;];
1712   ASM_MESON_TAC[REAL_ARITH `x < y ==> ~(x = y)`];
1713   ASM_MESON_TAC[REAL_ARITH `x < y ==> ~(x = y)`];
1714 ]);;
1715 (* }}} *)
1716
1717 let INFERISIGN_NEG_NEG_NEG = prove_by_refinement(
1718   `!y z p pts qts eqs sgns rgns r1 r2 r3.
1719      interpmat (APPEND pts (CONS y (CONS z qts)))
1720       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
1721         (APPEND sgns
1722           (CONS (CONS Neg r1)
1723            (CONS (CONS Unknown (CONS Neg r2))
1724             (CONS (CONS Neg r3) rgns)))) ==>
1725      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
1726     interpmat (APPEND pts (CONS y (CONS z qts)))
1727       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
1728         (APPEND sgns
1729           (CONS (CONS Neg r1)
1730            (CONS (CONS Neg (CONS Neg r2))
1731             (CONS (CONS Neg r3) rgns))))`,
1732 (* {{{ Proof *)
1733
1734 [
1735   REWRITE_TAC[interpmat];
1736   REPEAT STRIP_TAC;
1737   ASM_REWRITE_TAC[];
1738   CLAIM `~(sgns = [])`;
1739   REWRITE_TAC[GSYM LENGTH_0];
1740   DISCH_THEN (REWRITE_ALL o list);
1741   POP_ASSUM MP_TAC THEN ARITH_TAC;
1742   STRIP_TAC;
1743   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) = LENGTH (APPEND sgns (CONS (CONS Neg r1) (CONS (CONS Unknown (CONS Neg r2)) (CONS (CONS Neg r3) rgns))))`;
1744   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
1745   STRIP_TAC;
1746   (* save *)
1747   CASES_ON `pts = []`;
1748   POP_ASSUM (REWRITE_ALL o list);
1749   REWRITE_ALL[APPEND;];
1750   CLAIM `LENGTH sgns = 1`;
1751   POP_ASSUM (fun x -> ALL_TAC);
1752   REWRITE_ALL[LENGTH];
1753   ASM_REWRITE_TAC[];
1754   POP_ASSUM MP_TAC THEN ARITH_TAC;
1755   REWRITE_TAC[LENGTH_1];
1756   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
1757   REWRITE_ALL[APPEND];
1758   REPEAT (POP_ASSUM MP_TAC);
1759   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
1760   COND_CASES_TAC;
1761   POP_ASSUM (REWRITE_ALL o list);
1762   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
1763   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1764   REWRITE_ALL[interpsigns;ALL2;];
1765   ASM_REWRITE_TAC[];
1766   REWRITE_TAC[interpsign];
1767   REWRITE_ALL[real_gt];
1768   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] neg_neg_neq_thm);
1769   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
1770   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1771   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
1772   ASM_MESON_TAC[real_gt;];
1773   ASM_MESON_TAC[real_gt;real_gt;];
1774   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
1775   (* save *)
1776   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
1777   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1778   REWRITE_TAC[interpsign;real_gt;];
1779   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] neg_neg_neq_thm);
1780   REWRITE_ALL[interpsign;real_ordered_list;NOT_CONS_NIL;HD;ALL2;];
1781   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1782   REWRITE_ALL[real_gt];
1783   ASM_MESON_TAC[real_gt;];
1784   ASM_MESON_TAC[real_gt;real_gt;];
1785   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
1786   (* save *)
1787   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
1788   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
1789   COND_CASES_TAC;
1790   POP_ASSUM (REWRITE_ALL o list);
1791   REWRITE_TAC[TL;HD;APPEND;ALL2;];
1792   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
1793   MESON_TAC[real_gt;APPEND;APPEND_CONS];
1794   DISCH_THEN (REWRITE_ALL o list);
1795   REPEAT STRIP_TAC;
1796   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
1797   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
1798   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
1799   ARITH_TAC;
1800   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
1801   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
1802   REPEAT STRIP_TAC;
1803   REPEAT STRIP_TAC;
1804   MATCH_MP_TAC ALL2_APPEND;
1805   ASM_REWRITE_TAC[];
1806   REWRITE_ALL[ALL2;interpsigns;];
1807   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1808   REWRITE_ALL[interpsign;real_gt];
1809   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] neg_neg_neq_thm);
1810   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
1811   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1812   CLAIM `real_ordered_list [y; z]`;
1813   ASM_MESON_TAC[real_gt;ROL_APPEND];
1814   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
1815   ASM_MESON_TAC[real_gt;];
1816   ASM_MESON_TAC[real_gt;real_gt;];
1817   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
1818   (* save *)
1819   REWRITE_TAC[APPEND;TL;HD;ALL2;];
1820   REPEAT STRIP_TAC;
1821   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
1822   MESON_TAC[real_gt;APPEND;APPEND_CONS];
1823   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
1824   REPEAT STRIP_TAC;
1825   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
1826   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
1827   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
1828   ARITH_TAC;
1829   REWRITE_ALL[TL;APPEND;HD];
1830   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
1831   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
1832   REPEAT STRIP_TAC;
1833   REPEAT STRIP_TAC;
1834   MATCH_MP_TAC ALL2_APPEND;
1835   ASM_REWRITE_TAC[];
1836   REWRITE_ALL[ALL2;interpsigns;];
1837   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1838   REWRITE_ALL[interpsign;real_gt];
1839   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] neg_neg_neq_thm);
1840   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
1841   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1842   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
1843   ASM_MESON_TAC[real_gt;ROL_APPEND];
1844   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
1845   ASM_MESON_TAC[real_gt;];
1846   ASM_MESON_TAC[real_gt;real_gt;];
1847   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
1848   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
1849 ]);;
1850
1851 (* }}} *)
1852
1853
1854 let ALL2_INTERPSIGN_SUBSET = prove_by_refinement(
1855   `!P Q l1 l2. ALL2 (interpsign P) l1 l2 ==> Q SUBSET P ==>
1856    ALL2 (interpsign Q) l1 l2`,
1857 (* {{{ Proof *)
1858 [
1859   STRIP_TAC THEN STRIP_TAC THEN REPEAT LIST_INDUCT_TAC THEN REWRITE_TAC[ALL2];
1860   ASM_MESON_TAC[INTERPSIGN_SUBSET];
1861 ]);;
1862 (* }}} *)
1863
1864
1865 let HD_APPEND1 = prove_by_refinement(
1866   `!h i l1 l2.
1867   HD (APPEND l1 (CONS h l2)) = HD (APPEND l1 (CONS h (CONS i l2)))`,
1868 (* {{{ Proof *)
1869 [
1870   STRIP_TAC THEN STRIP_TAC;
1871   LIST_INDUCT_TAC;
1872   ASM_REWRITE_TAC[HD;APPEND];
1873   ASM_REWRITE_TAC[HD;APPEND];
1874 ]);;
1875 (* }}} *)
1876
1877 let ROL_APPEND_INSERT = prove_by_refinement(
1878   `!h j l1 l2.
1879     real_ordered_list (APPEND l1 (CONS h (CONS i l2))) ==>
1880     h < j ==> j < i ==>
1881       real_ordered_list (APPEND l1 (CONS h (CONS j (CONS i l2))))`,
1882 (* {{{ Proof *)
1883 [
1884   STRIP_TAC THEN STRIP_TAC;
1885   LIST_INDUCT_TAC;
1886   REWRITE_TAC[APPEND;real_ordered_list;HD;TL;NOT_CONS_NIL;];
1887   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1888   REWRITE_TAC[APPEND;real_ordered_list];
1889   REPEAT STRIP_TAC;
1890   ASM_MESON_TAC[];
1891   ASM_MESON_TAC[APPEND_EQ_NIL;NOT_CONS_NIL;];
1892   ASM_MESON_TAC[];
1893   DISJ2_TAC;
1894   ASM_MESON_TAC[HD_APPEND1];
1895 ]);;
1896 (* }}} *)
1897
1898
1899 let INFERISIGN_POS_NEG_POS = prove_by_refinement(
1900   `!y z p pts qts eqs sgns rgns r1 r2 r3.
1901      interpmat (APPEND pts (CONS y (CONS z qts)))
1902       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
1903         (APPEND sgns
1904           (CONS (CONS Pos r1)
1905            (CONS (CONS Unknown (CONS Pos r2))
1906             (CONS (CONS Neg r3) rgns)))) ==>
1907      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
1908     ?w. interpmat (APPEND pts (CONS y (CONS w (CONS z qts))))
1909       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
1910         (APPEND sgns
1911           (CONS (CONS Pos r1)
1912           (CONS (CONS Pos (CONS Pos r2))
1913           (CONS (CONS Zero (CONS Pos r2))
1914           (CONS (CONS Neg (CONS Pos r2))
1915           (CONS (CONS Neg r3) rgns))))))`,
1916 (* {{{ Proof *)
1917 [
1918   REWRITE_TAC[interpmat];
1919   REPEAT STRIP_TAC;
1920   CLAIM `~(sgns = [])`;
1921   REWRITE_TAC[GSYM LENGTH_0];
1922   DISCH_THEN (REWRITE_ALL o list);
1923   POP_ASSUM MP_TAC THEN ARITH_TAC;
1924   STRIP_TAC;
1925   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) = LENGTH (APPEND sgns (CONS (CONS Pos r1) (CONS (CONS Unknown (CONS Pos r2)) (CONS (CONS Neg r3) rgns))))`;
1926   ASM_MESON_TAC[ALL2_LENGTH];
1927   STRIP_TAC;
1928   (* save *)
1929   CASES_ON `pts = []`;
1930   POP_ASSUM (REWRITE_ALL o list);
1931   REWRITE_ALL[APPEND;];
1932   CLAIM `LENGTH sgns = 1`;
1933   POP_ASSUM (fun x -> ALL_TAC);
1934   REWRITE_ALL[LENGTH];
1935   ASM_REWRITE_TAC[];
1936   POP_ASSUM MP_TAC THEN ARITH_TAC;
1937   REWRITE_TAC[LENGTH_1];
1938   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
1939   REWRITE_ALL[APPEND];
1940   REPEAT (POP_ASSUM MP_TAC);
1941   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
1942   COND_CASES_TAC;
1943   POP_ASSUM (REWRITE_ALL o list);
1944   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
1945   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1946   REWRITE_ALL[interpsigns;ALL2;];
1947   ASM_REWRITE_TAC[];
1948   REWRITE_TAC[interpsign];
1949   REWRITE_ALL[real_gt];
1950   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] pos_neg_neq_thm);
1951   REWRITE_ALL[real_ordered_list;HD;NOT_CONS_NIL;];
1952   ASM_REWRITE_TAC[];
1953   STRIP_TAC;
1954   LABEL_ALL_TAC;
1955   PROVE_ASSUM_ANTECEDENT_TAC 0;
1956   REPEAT STRIP_TAC;
1957   ASM_MESON_TAC[interpsigns;ALL2;interpsign;real_gt;];
1958   ASM_MESON_TAC[interpsigns;ALL2;interpsign;real_gt;];
1959   ASM_MESON_TAC[interpsigns;ALL2;interpsign;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
1960   POP_ASSUM MP_TAC THEN STRIP_TAC;
1961   EXISTS_TAC `X`;
1962   REWRITE_ALL[interpsign;real_gt];
1963   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1964   ASM_MESON_TAC[];
1965   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
1966   FIRST_ASSUM MATCH_MP_TAC;
1967   ASM_REWRITE_TAC[];
1968   ASM_MESON_TAC[REAL_LT_TRANS];
1969   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
1970   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
1971   EXISTS_TAC `\x. y < x /\ x < z`;
1972   ASM_REWRITE_TAC[];
1973   REWRITE_TAC[SUBSET;IN];
1974   REPEAT STRIP_TAC;
1975   ASM_MESON_TAC[REAL_LT_TRANS];
1976   ASM_MESON_TAC[REAL_LT_TRANS];
1977   ASM_MESON_TAC[REAL_LT_TRANS];
1978   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
1979   EXISTS_TAC `\x. y < x /\ x < z`;
1980   ASM_REWRITE_TAC[];
1981   REWRITE_TAC[SUBSET;IN];
1982   REPEAT STRIP_TAC;
1983   ASM_MESON_TAC[REAL_LT_TRANS];
1984   ASM_MESON_TAC[REAL_LT_TRANS];
1985   ASM_MESON_TAC[REAL_LT_TRANS];
1986   ASM_MESON_TAC[REAL_LT_TRANS];
1987   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
1988   EXISTS_TAC `\x. y < x /\ x < z`;
1989   ASM_REWRITE_TAC[];
1990   REWRITE_TAC[SUBSET;IN];
1991   REPEAT STRIP_TAC;
1992   ASM_MESON_TAC[REAL_LT_TRANS];
1993   ASM_MESON_TAC[REAL_LT_TRANS];
1994   (* save *)
1995   REWRITE_TAC[TL;APPEND;ALL2;real_gt;interpsigns;interpsign];
1996   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
1997   REWRITE_ALL[interpsigns;ALL2;];
1998   ASM_REWRITE_TAC[];
1999   REWRITE_TAC[interpsign];
2000   REWRITE_ALL[real_gt];
2001   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] pos_neg_neq_thm);
2002   REWRITE_ALL[real_ordered_list;HD;NOT_CONS_NIL;];
2003   ASM_REWRITE_TAC[];
2004   STRIP_TAC;
2005   LABEL_ALL_TAC;
2006   PROVE_ASSUM_ANTECEDENT_TAC 0;
2007   REPEAT STRIP_TAC;
2008   ASM_MESON_TAC[interpsigns;ALL2;interpsign;real_gt;];
2009   ASM_MESON_TAC[interpsigns;ALL2;interpsign;real_gt;];
2010   ASM_MESON_TAC[interpsigns;ALL2;interpsign;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2011   POP_ASSUM MP_TAC THEN STRIP_TAC;
2012   EXISTS_TAC `X`;
2013   REWRITE_ALL[interpsign;real_gt];
2014   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2015   ASM_MESON_TAC[];
2016   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2017   FIRST_ASSUM MATCH_MP_TAC;
2018   ASM_REWRITE_TAC[];
2019   ASM_MESON_TAC[REAL_LT_TRANS];
2020   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2021   ASM_MESON_TAC[REAL_LT_TRANS;];
2022   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2023   EXISTS_TAC `\x. y < x /\ x < z`;
2024   ASM_REWRITE_TAC[];
2025   REWRITE_TAC[SUBSET;IN];
2026   REPEAT STRIP_TAC;
2027   ASM_MESON_TAC[REAL_LT_TRANS];
2028   ASM_MESON_TAC[REAL_LT_TRANS];
2029   ASM_MESON_TAC[REAL_LT_TRANS];
2030   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2031   EXISTS_TAC `\x. y < x /\ x < z`;
2032   ASM_REWRITE_TAC[];
2033   REWRITE_TAC[SUBSET;IN];
2034   REPEAT STRIP_TAC;
2035   ASM_MESON_TAC[REAL_LT_TRANS];
2036   ASM_MESON_TAC[REAL_LT_TRANS];
2037   ASM_MESON_TAC[REAL_LT_TRANS];
2038   ASM_MESON_TAC[REAL_LT_TRANS];
2039   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2040   EXISTS_TAC `\x. y < x /\ x < z`;
2041   ASM_REWRITE_TAC[];
2042   REWRITE_TAC[SUBSET;IN];
2043   REPEAT STRIP_TAC;
2044   ASM_MESON_TAC[REAL_LT_TRANS];
2045   ASM_MESON_TAC[REAL_LT_TRANS];
2046   (* save *)
2047   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
2048   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
2049   CLAIM `!rts. APPEND (BUTLAST (partition_line pts))
2050        (CONS (\x. LAST pts < x /\ x < y) rts) =
2051      APPEND (APPEND (BUTLAST (partition_line pts))
2052         [\x. LAST pts < x /\ x < y]) rts`;
2053   MESON_TAC[APPEND;APPEND_CONS];
2054   DISCH_THEN (ONCE_REWRITE_TAC o list);
2055   REPEAT STRIP_TAC;
2056   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
2057   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
2058   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
2059   ARITH_TAC;
2060   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
2061   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
2062   REPEAT STRIP_TAC;
2063   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
2064   ASM_MESON_TAC[real_gt;ROL_APPEND];
2065   REWRITE_TAC[real_ordered_list;NOT_CONS_NIL;HD;];
2066   REPEAT (POP_ASSUM MP_TAC);
2067   REWRITE_ALL[ALL2;partition_line;HD;TL;NOT_CONS_NIL;];
2068   (* save *)
2069   COND_CASES_TAC;
2070   POP_ASSUM (REWRITE_ALL o list);
2071   REWRITE_ALL[APPEND;TL;HD;interpsigns;interpsign;ALL2;];
2072   REPEAT STRIP_TAC;
2073   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] pos_neg_neq_thm);
2074   REPEAT STRIP_TAC;
2075   LABEL_ALL_TAC;
2076   PROVE_ASSUM_ANTECEDENT_TAC 0;
2077   REPEAT STRIP_TAC;
2078   ASM_REWRITE_TAC[];
2079   ASM_MESON_TAC[real_gt;];
2080   ASM_MESON_TAC[real_gt;];
2081   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2082   POP_ASSUM MP_TAC THEN STRIP_TAC;
2083   EXISTS_TAC `X`;
2084   REWRITE_ALL[interpsign;real_gt];
2085   (* save *)
2086   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[interpsigns;interpsign];
2087   FIRST_ASSUM (MP_TAC o MATCH_MP ROL_APPEND);
2088   REPEAT STRIP_TAC;
2089   ASM_MESON_TAC[ROL_APPEND_INSERT];
2090   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
2091   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
2092   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
2093   ARITH_TAC;
2094   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
2095   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
2096   REPEAT STRIP_TAC;
2097   MATCH_MP_TAC ALL2_APPEND;
2098   ASM_REWRITE_TAC[];
2099   REWRITE_ALL[ALL2;interpsigns;interpsign];
2100   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2101   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2102   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2103   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2104   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2105   EXISTS_TAC `\x. y < x /\ x < z`;
2106   REWRITE_TAC[SUBSET;IN];
2107   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2108   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2109   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2110   EXISTS_TAC `\x. y < x /\ x < z`;
2111   REWRITE_TAC[SUBSET;IN];
2112   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2113   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2114   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2115   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2116   EXISTS_TAC `\x. y < x /\ x < z`;
2117   REWRITE_TAC[SUBSET;IN];
2118   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2119   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2120   (* save *)
2121   REWRITE_ALL[APPEND;TL;HD;interpsigns;interpsign;ALL2;];
2122   REPEAT STRIP_TAC;
2123   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] pos_neg_neq_thm);
2124   REPEAT STRIP_TAC;
2125   LABEL_ALL_TAC;
2126   PROVE_ASSUM_ANTECEDENT_TAC 0;
2127   REPEAT STRIP_TAC;
2128   ASM_REWRITE_TAC[];
2129   ASM_MESON_TAC[real_gt;];
2130   ASM_MESON_TAC[real_gt;];
2131   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2132   POP_ASSUM MP_TAC THEN STRIP_TAC;
2133   EXISTS_TAC `X`;
2134   REWRITE_ALL[interpsign;real_gt];
2135   (* save *)
2136   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[interpsigns;interpsign];
2137   FIRST_ASSUM (MP_TAC o MATCH_MP ROL_APPEND);
2138   REPEAT STRIP_TAC;
2139   ASM_MESON_TAC[ROL_APPEND_INSERT];
2140   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
2141   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
2142   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
2143   ARITH_TAC;
2144   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
2145   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
2146   REPEAT STRIP_TAC;
2147   MATCH_MP_TAC ALL2_APPEND;
2148   ASM_REWRITE_TAC[];
2149   REWRITE_ALL[ALL2;interpsigns;interpsign];
2150   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2151   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2152   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2153   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2154   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2155   EXISTS_TAC `\x. y < x /\ x < z`;
2156   REWRITE_TAC[SUBSET;IN];
2157   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2158   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2159   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2160   EXISTS_TAC `\x. y < x /\ x < z`;
2161   REWRITE_TAC[SUBSET;IN];
2162   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2163   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2164   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2165   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2166   EXISTS_TAC `\x. y < x /\ x < z`;
2167   REWRITE_TAC[SUBSET;IN];
2168   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2169   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2170 ]);;
2171 (* }}} *)
2172
2173
2174 let INFERISIGN_POS_NEG_NEG = prove_by_refinement(
2175   `!y z p pts qts eqs sgns rgns r1 r2 r3.
2176      interpmat (APPEND pts (CONS y (CONS z qts)))
2177       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
2178         (APPEND sgns
2179           (CONS (CONS Pos r1)
2180            (CONS (CONS Unknown (CONS Neg r2))
2181             (CONS (CONS Neg r3) rgns)))) ==>
2182      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
2183     ?w. interpmat (APPEND pts (CONS y (CONS w (CONS z qts))))
2184       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
2185         (APPEND sgns
2186           (CONS (CONS Pos r1)
2187           (CONS (CONS Pos (CONS Neg r2))
2188           (CONS (CONS Zero (CONS Neg r2))
2189           (CONS (CONS Neg (CONS Neg r2))
2190           (CONS (CONS Neg r3) rgns))))))`,
2191 (* {{{ Proof *)
2192 [
2193   REWRITE_TAC[interpmat];
2194   REPEAT STRIP_TAC;
2195   CLAIM `~(sgns = [])`;
2196   REWRITE_TAC[GSYM LENGTH_0];
2197   DISCH_THEN (REWRITE_ALL o list);
2198   POP_ASSUM MP_TAC THEN ARITH_TAC;
2199   STRIP_TAC;
2200   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) = LENGTH (APPEND sgns (CONS (CONS Pos r1) (CONS (CONS Unknown (CONS Neg r2)) (CONS (CONS Neg r3) rgns))))`;
2201   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
2202   STRIP_TAC;
2203   (* save *)
2204   CASES_ON `pts = []`;
2205   POP_ASSUM (REWRITE_ALL o list);
2206   REWRITE_ALL[APPEND;];
2207   CLAIM `LENGTH sgns = 1`;
2208   POP_ASSUM (fun x -> ALL_TAC);
2209   REWRITE_ALL[LENGTH];
2210   ASM_REWRITE_TAC[];
2211   POP_ASSUM MP_TAC THEN ARITH_TAC;
2212   REWRITE_TAC[LENGTH_1];
2213   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
2214   REWRITE_ALL[APPEND];
2215   REPEAT (POP_ASSUM MP_TAC);
2216   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
2217   COND_CASES_TAC;
2218   POP_ASSUM (REWRITE_ALL o list);
2219   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
2220   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2221   REWRITE_ALL[interpsigns;ALL2;];
2222   ASM_REWRITE_TAC[];
2223   REWRITE_TAC[interpsign];
2224   REWRITE_ALL[real_gt];
2225   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] pos_neg_neq_thm);
2226   REWRITE_ALL[real_ordered_list;HD;NOT_CONS_NIL;];
2227   ASM_REWRITE_TAC[];
2228   STRIP_TAC;
2229   LABEL_ALL_TAC;
2230   PROVE_ASSUM_ANTECEDENT_TAC 0;
2231   REPEAT STRIP_TAC;
2232   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;];
2233   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;];
2234   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2235   POP_ASSUM MP_TAC THEN STRIP_TAC;
2236   EXISTS_TAC `X`;
2237   REWRITE_ALL[interpsign;real_gt];
2238   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2239   ASM_MESON_TAC[real_gt;];
2240   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2241   FIRST_ASSUM MATCH_MP_TAC;
2242   ASM_REWRITE_TAC[];
2243   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2244   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2245   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2246   EXISTS_TAC `\x. y < x /\ x < z`;
2247   ASM_REWRITE_TAC[];
2248   REWRITE_TAC[SUBSET;IN];
2249   REPEAT STRIP_TAC;
2250   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2251   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2252   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2253   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2254   EXISTS_TAC `\x. y < x /\ x < z`;
2255   ASM_REWRITE_TAC[];
2256   REWRITE_TAC[SUBSET;IN];
2257   REPEAT STRIP_TAC;
2258   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2259   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2260   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2261   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2262   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2263   EXISTS_TAC `\x. y < x /\ x < z`;
2264   ASM_REWRITE_TAC[];
2265   REWRITE_TAC[SUBSET;IN];
2266   REPEAT STRIP_TAC;
2267   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2268   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2269   (* save *)
2270   REWRITE_TAC[TL;APPEND;ALL2;real_gt;interpsigns;interpsign];
2271   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2272   REWRITE_ALL[interpsigns;ALL2;];
2273   ASM_REWRITE_TAC[];
2274   REWRITE_TAC[interpsign];
2275   REWRITE_ALL[real_gt];
2276   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] pos_neg_neq_thm);
2277   REWRITE_ALL[real_ordered_list;HD;NOT_CONS_NIL;];
2278   ASM_REWRITE_TAC[];
2279   STRIP_TAC;
2280   LABEL_ALL_TAC;
2281   PROVE_ASSUM_ANTECEDENT_TAC 0;
2282   REPEAT STRIP_TAC;
2283   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;];
2284   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;];
2285   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2286   POP_ASSUM MP_TAC THEN STRIP_TAC;
2287   EXISTS_TAC `X`;
2288   REWRITE_ALL[interpsign;real_gt];
2289   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2290   ASM_MESON_TAC[real_gt;];
2291   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2292   FIRST_ASSUM MATCH_MP_TAC;
2293   ASM_REWRITE_TAC[];
2294   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2295   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2296   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2297   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2298   EXISTS_TAC `\x. y < x /\ x < z`;
2299   ASM_REWRITE_TAC[];
2300   REWRITE_TAC[SUBSET;IN];
2301   REPEAT STRIP_TAC;
2302   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2303   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2304   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2305   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2306   EXISTS_TAC `\x. y < x /\ x < z`;
2307   ASM_REWRITE_TAC[];
2308   REWRITE_TAC[SUBSET;IN];
2309   REPEAT STRIP_TAC;
2310   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2311   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2312   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2313   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2314   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2315   EXISTS_TAC `\x. y < x /\ x < z`;
2316   ASM_REWRITE_TAC[];
2317   REWRITE_TAC[SUBSET;IN];
2318   REPEAT STRIP_TAC;
2319   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2320   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2321   (* save *)
2322   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
2323   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
2324   CLAIM `!rts. APPEND (BUTLAST (partition_line pts))
2325        (CONS (\x. LAST pts < x /\ x < y) rts) =
2326      APPEND (APPEND (BUTLAST (partition_line pts))
2327         [\x. LAST pts < x /\ x < y]) rts`;
2328   MESON_TAC[real_gt;APPEND;APPEND_CONS];
2329   DISCH_THEN (ONCE_REWRITE_TAC o list);
2330   REPEAT STRIP_TAC;
2331   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
2332   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
2333   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
2334   ARITH_TAC;
2335   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
2336   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
2337   REPEAT STRIP_TAC;
2338   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
2339   ASM_MESON_TAC[real_gt;real_gt;ROL_APPEND];
2340   REWRITE_TAC[real_ordered_list;NOT_CONS_NIL;HD;];
2341   REPEAT (POP_ASSUM MP_TAC);
2342   REWRITE_ALL[ALL2;partition_line;HD;TL;NOT_CONS_NIL;];
2343   (* save *)
2344   COND_CASES_TAC;
2345   POP_ASSUM (REWRITE_ALL o list);
2346   REWRITE_ALL[APPEND;TL;HD;interpsigns;interpsign;ALL2;];
2347   REPEAT STRIP_TAC;
2348   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] pos_neg_neq_thm);
2349   REPEAT STRIP_TAC;
2350   LABEL_ALL_TAC;
2351   PROVE_ASSUM_ANTECEDENT_TAC 0;
2352   REPEAT STRIP_TAC;
2353   ASM_REWRITE_TAC[];
2354   ASM_MESON_TAC[real_gt;real_gt;];
2355   ASM_MESON_TAC[real_gt;real_gt;];
2356   ASM_MESON_TAC[real_gt;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2357   POP_ASSUM MP_TAC THEN STRIP_TAC;
2358   EXISTS_TAC `X`;
2359   REWRITE_ALL[interpsign;real_gt];
2360   (* save *)
2361   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[interpsigns;interpsign];
2362   FIRST_ASSUM (MP_TAC o MATCH_MP ROL_APPEND);
2363   REPEAT STRIP_TAC;
2364   ASM_MESON_TAC[real_gt;ROL_APPEND_INSERT];
2365   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
2366   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
2367   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
2368   ARITH_TAC;
2369   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
2370   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
2371   REPEAT STRIP_TAC;
2372   MATCH_MP_TAC ALL2_APPEND;
2373   ASM_REWRITE_TAC[];
2374   REWRITE_ALL[ALL2;interpsigns;interpsign];
2375   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2376   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2377   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2378   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2379   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2380   EXISTS_TAC `\x. y < x /\ x < z`;
2381   REWRITE_TAC[SUBSET;IN];
2382   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2383   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2384   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2385   EXISTS_TAC `\x. y < x /\ x < z`;
2386   REWRITE_TAC[SUBSET;IN];
2387   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2388   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2389   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2390   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2391   EXISTS_TAC `\x. y < x /\ x < z`;
2392   REWRITE_TAC[SUBSET;IN];
2393   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2394   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2395   (* save *)
2396   REWRITE_ALL[APPEND;TL;HD;interpsigns;interpsign;ALL2;];
2397   REPEAT STRIP_TAC;
2398   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] pos_neg_neq_thm);
2399   REPEAT STRIP_TAC;
2400   LABEL_ALL_TAC;
2401   PROVE_ASSUM_ANTECEDENT_TAC 0;
2402   REPEAT STRIP_TAC;
2403   ASM_REWRITE_TAC[];
2404   ASM_MESON_TAC[real_gt;real_gt;];
2405   ASM_MESON_TAC[real_gt;real_gt;];
2406   ASM_MESON_TAC[real_gt;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2407   POP_ASSUM MP_TAC THEN STRIP_TAC;
2408   EXISTS_TAC `X`;
2409   REWRITE_ALL[interpsign;real_gt];
2410   (* save *)
2411   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[interpsigns;interpsign];
2412   FIRST_ASSUM (MP_TAC o MATCH_MP ROL_APPEND);
2413   REPEAT STRIP_TAC;
2414   ASM_MESON_TAC[real_gt;ROL_APPEND_INSERT];
2415   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
2416   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
2417   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
2418   ARITH_TAC;
2419   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
2420   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
2421   REPEAT STRIP_TAC;
2422   MATCH_MP_TAC ALL2_APPEND;
2423   ASM_REWRITE_TAC[];
2424   REWRITE_ALL[ALL2;interpsigns;interpsign];
2425   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2426   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2427   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2428   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2429   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2430   EXISTS_TAC `\x. y < x /\ x < z`;
2431   REWRITE_TAC[SUBSET;IN];
2432   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2433   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2434   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2435   EXISTS_TAC `\x. y < x /\ x < z`;
2436   REWRITE_TAC[SUBSET;IN];
2437   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2438   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2439   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2440   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2441   EXISTS_TAC `\x. y < x /\ x < z`;
2442   REWRITE_TAC[SUBSET;IN];
2443   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2444   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2445 ]);;
2446 (* }}} *)
2447
2448
2449 let INFERISIGN_NEG_POS_NEG = prove_by_refinement(
2450   `!y z p pts qts eqs sgns rgns r1 r2 r3.
2451      interpmat (APPEND pts (CONS y (CONS z qts)))
2452       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
2453         (APPEND sgns
2454           (CONS (CONS Neg r1)
2455            (CONS (CONS Unknown (CONS Neg r2))
2456             (CONS (CONS Pos r3) rgns)))) ==>
2457      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
2458     ?w. interpmat (APPEND pts (CONS y (CONS w (CONS z qts))))
2459       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
2460         (APPEND sgns
2461           (CONS (CONS Neg r1)
2462           (CONS (CONS Neg (CONS Neg r2))
2463           (CONS (CONS Zero (CONS Neg r2))
2464           (CONS (CONS Pos (CONS Neg r2))
2465           (CONS (CONS Pos r3) rgns))))))`,
2466 (* {{{ Proof *)
2467 [
2468   REWRITE_TAC[interpmat];
2469   REPEAT STRIP_TAC;
2470   CLAIM `~(sgns = [])`;
2471   REWRITE_TAC[GSYM LENGTH_0];
2472   DISCH_THEN (REWRITE_ALL o list);
2473   POP_ASSUM MP_TAC THEN ARITH_TAC;
2474   STRIP_TAC;
2475   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) =
2476          LENGTH (APPEND sgns (CONS (CONS Neg r1)
2477           (CONS (CONS Unknown (CONS Neg r2))
2478           (CONS (CONS Pos r3) rgns))))`;
2479   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
2480   STRIP_TAC;
2481   (* save *)
2482   CASES_ON `pts = []`;
2483   POP_ASSUM (REWRITE_ALL o list);
2484   REWRITE_ALL[APPEND;];
2485   CLAIM `LENGTH sgns = 1`;
2486   POP_ASSUM (fun x -> ALL_TAC);
2487   REWRITE_ALL[LENGTH];
2488   ASM_REWRITE_TAC[];
2489   POP_ASSUM MP_TAC THEN ARITH_TAC;
2490   REWRITE_TAC[LENGTH_1];
2491   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
2492   REWRITE_ALL[APPEND];
2493   REPEAT (POP_ASSUM MP_TAC);
2494   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
2495   COND_CASES_TAC;
2496   POP_ASSUM (REWRITE_ALL o list);
2497   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
2498   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2499   REWRITE_ALL[interpsigns;ALL2;];
2500   ASM_REWRITE_TAC[];
2501   REWRITE_TAC[interpsign];
2502   REWRITE_ALL[real_gt];
2503   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] neg_pos_neq_thm);
2504   REWRITE_ALL[real_ordered_list;HD;NOT_CONS_NIL;];
2505   ASM_REWRITE_TAC[];
2506   STRIP_TAC;
2507   LABEL_ALL_TAC;
2508   PROVE_ASSUM_ANTECEDENT_TAC 0;
2509   REPEAT STRIP_TAC;
2510   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;];
2511   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;];
2512   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2513   POP_ASSUM MP_TAC THEN STRIP_TAC;
2514   EXISTS_TAC `X`;
2515   REWRITE_ALL[interpsign;real_gt];
2516   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2517   ASM_MESON_TAC[real_gt;];
2518   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2519   FIRST_ASSUM MATCH_MP_TAC;
2520   ASM_REWRITE_TAC[];
2521   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2522   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2523   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2524   EXISTS_TAC `\x. y < x /\ x < z`;
2525   ASM_REWRITE_TAC[];
2526   REWRITE_TAC[SUBSET;IN];
2527   REPEAT STRIP_TAC;
2528   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2529   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2530   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2531   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2532   EXISTS_TAC `\x. y < x /\ x < z`;
2533   ASM_REWRITE_TAC[];
2534   REWRITE_TAC[SUBSET;IN];
2535   REPEAT STRIP_TAC;
2536   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2537   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2538   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2539   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2540   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2541   EXISTS_TAC `\x. y < x /\ x < z`;
2542   ASM_REWRITE_TAC[];
2543   REWRITE_TAC[SUBSET;IN];
2544   REPEAT STRIP_TAC;
2545   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2546   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2547   (* save *)
2548   REWRITE_TAC[TL;APPEND;ALL2;real_gt;interpsigns;interpsign];
2549   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2550   REWRITE_ALL[interpsigns;ALL2;];
2551   ASM_REWRITE_TAC[];
2552   REWRITE_TAC[interpsign];
2553   REWRITE_ALL[real_gt];
2554   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] neg_pos_neq_thm);
2555   REWRITE_ALL[real_ordered_list;HD;NOT_CONS_NIL;];
2556   ASM_REWRITE_TAC[];
2557   STRIP_TAC;
2558   LABEL_ALL_TAC;
2559   PROVE_ASSUM_ANTECEDENT_TAC 0;
2560   REPEAT STRIP_TAC;
2561   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;];
2562   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;];
2563   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2564   POP_ASSUM MP_TAC THEN STRIP_TAC;
2565   EXISTS_TAC `X`;
2566   REWRITE_ALL[interpsign;real_gt];
2567   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2568   ASM_MESON_TAC[real_gt;];
2569   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2570   FIRST_ASSUM MATCH_MP_TAC;
2571   ASM_REWRITE_TAC[];
2572   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2573   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2574   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2575   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2576   EXISTS_TAC `\x. y < x /\ x < z`;
2577   ASM_REWRITE_TAC[];
2578   REWRITE_TAC[SUBSET;IN];
2579   REPEAT STRIP_TAC;
2580   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2581   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2582   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2583   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2584   EXISTS_TAC `\x. y < x /\ x < z`;
2585   ASM_REWRITE_TAC[];
2586   REWRITE_TAC[SUBSET;IN];
2587   REPEAT STRIP_TAC;
2588   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2589   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2590   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2591   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2592   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2593   EXISTS_TAC `\x. y < x /\ x < z`;
2594   ASM_REWRITE_TAC[];
2595   REWRITE_TAC[SUBSET;IN];
2596   REPEAT STRIP_TAC;
2597   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2598   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2599   (* save *)
2600   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
2601   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
2602   CLAIM `!rts. APPEND (BUTLAST (partition_line pts))
2603        (CONS (\x. LAST pts < x /\ x < y) rts) =
2604      APPEND (APPEND (BUTLAST (partition_line pts))
2605         [\x. LAST pts < x /\ x < y]) rts`;
2606   MESON_TAC[real_gt;APPEND;APPEND_CONS];
2607   DISCH_THEN (ONCE_REWRITE_TAC o list);
2608   REPEAT STRIP_TAC;
2609   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
2610   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
2611   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
2612   ARITH_TAC;
2613   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
2614   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
2615   REPEAT STRIP_TAC;
2616   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
2617   ASM_MESON_TAC[real_gt;real_gt;ROL_APPEND];
2618   REWRITE_TAC[real_ordered_list;NOT_CONS_NIL;HD;];
2619   REPEAT (POP_ASSUM MP_TAC);
2620   REWRITE_ALL[ALL2;partition_line;HD;TL;NOT_CONS_NIL;];
2621   (* save *)
2622   COND_CASES_TAC;
2623   POP_ASSUM (REWRITE_ALL o list);
2624   REWRITE_ALL[APPEND;TL;HD;interpsigns;interpsign;ALL2;];
2625   REPEAT STRIP_TAC;
2626   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] neg_pos_neq_thm);
2627   REPEAT STRIP_TAC;
2628   LABEL_ALL_TAC;
2629   PROVE_ASSUM_ANTECEDENT_TAC 0;
2630   REPEAT STRIP_TAC;
2631   ASM_REWRITE_TAC[];
2632   ASM_MESON_TAC[real_gt;real_gt;];
2633   ASM_MESON_TAC[real_gt;real_gt;];
2634   ASM_MESON_TAC[real_gt;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2635   POP_ASSUM MP_TAC THEN STRIP_TAC;
2636   EXISTS_TAC `X`;
2637   REWRITE_ALL[interpsign;real_gt];
2638   (* save *)
2639   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[interpsigns;interpsign];
2640   FIRST_ASSUM (MP_TAC o MATCH_MP ROL_APPEND);
2641   REPEAT STRIP_TAC;
2642   ASM_MESON_TAC[real_gt;ROL_APPEND_INSERT];
2643   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
2644   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
2645   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
2646   ARITH_TAC;
2647   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
2648   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
2649   REPEAT STRIP_TAC;
2650   MATCH_MP_TAC ALL2_APPEND;
2651   ASM_REWRITE_TAC[];
2652   REWRITE_ALL[ALL2;interpsigns;interpsign];
2653   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2654   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2655   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2656   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2657   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2658   EXISTS_TAC `\x. y < x /\ x < z`;
2659   REWRITE_TAC[SUBSET;IN];
2660   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2661   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2662   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2663   EXISTS_TAC `\x. y < x /\ x < z`;
2664   REWRITE_TAC[SUBSET;IN];
2665   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2666   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2667   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2668   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2669   EXISTS_TAC `\x. y < x /\ x < z`;
2670   REWRITE_TAC[SUBSET;IN];
2671   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2672   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2673   (* save *)
2674   REWRITE_ALL[APPEND;TL;HD;interpsigns;interpsign;ALL2;];
2675   REPEAT STRIP_TAC;
2676   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] neg_pos_neq_thm);
2677   REPEAT STRIP_TAC;
2678   LABEL_ALL_TAC;
2679   PROVE_ASSUM_ANTECEDENT_TAC 0;
2680   REPEAT STRIP_TAC;
2681   ASM_REWRITE_TAC[];
2682   ASM_MESON_TAC[real_gt;real_gt;];
2683   ASM_MESON_TAC[real_gt;real_gt;];
2684   ASM_MESON_TAC[real_gt;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2685   POP_ASSUM MP_TAC THEN STRIP_TAC;
2686   EXISTS_TAC `X`;
2687   REWRITE_ALL[interpsign;real_gt];
2688   (* save *)
2689   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[interpsigns;interpsign];
2690   FIRST_ASSUM (MP_TAC o MATCH_MP ROL_APPEND);
2691   REPEAT STRIP_TAC;
2692   ASM_MESON_TAC[real_gt;ROL_APPEND_INSERT];
2693   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
2694   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
2695   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
2696   ARITH_TAC;
2697   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
2698   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
2699   REPEAT STRIP_TAC;
2700   MATCH_MP_TAC ALL2_APPEND;
2701   ASM_REWRITE_TAC[];
2702   REWRITE_ALL[ALL2;interpsigns;interpsign];
2703   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2704   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2705   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2706   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2707   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2708   EXISTS_TAC `\x. y < x /\ x < z`;
2709   REWRITE_TAC[SUBSET;IN];
2710   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2711   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2712   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2713   EXISTS_TAC `\x. y < x /\ x < z`;
2714   REWRITE_TAC[SUBSET;IN];
2715   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2716   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2717   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2718   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2719   EXISTS_TAC `\x. y < x /\ x < z`;
2720   REWRITE_TAC[SUBSET;IN];
2721   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2722   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2723 ]);;
2724 (* }}} *)
2725
2726 let INFERISIGN_NEG_POS_POS = prove_by_refinement(
2727   `!y z p pts qts eqs sgns rgns r1 r2 r3.
2728      interpmat (APPEND pts (CONS y (CONS z qts)))
2729       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
2730         (APPEND sgns
2731           (CONS (CONS Neg r1)
2732            (CONS (CONS Unknown (CONS Pos r2))
2733             (CONS (CONS Pos r3) rgns)))) ==>
2734      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
2735     ?w. interpmat (APPEND pts (CONS y (CONS w (CONS z qts))))
2736       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
2737         (APPEND sgns
2738           (CONS (CONS Neg r1)
2739           (CONS (CONS Neg (CONS Pos r2))
2740           (CONS (CONS Zero (CONS Pos r2))
2741           (CONS (CONS Pos (CONS Pos r2))
2742           (CONS (CONS Pos r3) rgns))))))`,
2743 (* {{{ Proof *)
2744 [
2745   REWRITE_TAC[interpmat];
2746   REPEAT STRIP_TAC;
2747   CLAIM `~(sgns = [])`;
2748   REWRITE_TAC[GSYM LENGTH_0];
2749   DISCH_THEN (REWRITE_ALL o list);
2750   POP_ASSUM MP_TAC THEN ARITH_TAC;
2751   STRIP_TAC;
2752   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) =
2753          LENGTH (APPEND sgns (CONS (CONS Neg r1)
2754           (CONS (CONS Unknown (CONS Pos r2))
2755           (CONS (CONS Pos r3) rgns))))`;
2756   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
2757   STRIP_TAC;
2758   (* save *)
2759   CASES_ON `pts = []`;
2760   POP_ASSUM (REWRITE_ALL o list);
2761   REWRITE_ALL[APPEND;];
2762   CLAIM `LENGTH sgns = 1`;
2763   POP_ASSUM (fun x -> ALL_TAC);
2764   REWRITE_ALL[LENGTH];
2765   ASM_REWRITE_TAC[];
2766   POP_ASSUM MP_TAC THEN ARITH_TAC;
2767   REWRITE_TAC[LENGTH_1];
2768   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
2769   REWRITE_ALL[APPEND];
2770   REPEAT (POP_ASSUM MP_TAC);
2771   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
2772   COND_CASES_TAC;
2773   POP_ASSUM (REWRITE_ALL o list);
2774   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
2775   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2776   REWRITE_ALL[interpsigns;ALL2;];
2777   ASM_REWRITE_TAC[];
2778   REWRITE_TAC[interpsign];
2779   REWRITE_ALL[real_gt];
2780   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] neg_pos_neq_thm);
2781   REWRITE_ALL[real_ordered_list;HD;NOT_CONS_NIL;];
2782   ASM_REWRITE_TAC[];
2783   STRIP_TAC;
2784   LABEL_ALL_TAC;
2785   PROVE_ASSUM_ANTECEDENT_TAC 0;
2786   REPEAT STRIP_TAC;
2787   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;];
2788   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;];
2789   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2790   POP_ASSUM MP_TAC THEN STRIP_TAC;
2791   EXISTS_TAC `X`;
2792   REWRITE_ALL[interpsign;real_gt];
2793   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2794   ASM_MESON_TAC[real_gt;];
2795   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2796   FIRST_ASSUM MATCH_MP_TAC;
2797   ASM_REWRITE_TAC[];
2798   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2799   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2800   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2801   EXISTS_TAC `\x. y < x /\ x < z`;
2802   ASM_REWRITE_TAC[];
2803   REWRITE_TAC[SUBSET;IN];
2804   REPEAT STRIP_TAC;
2805   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2806   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2807   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2808   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2809   EXISTS_TAC `\x. y < x /\ x < z`;
2810   ASM_REWRITE_TAC[];
2811   REWRITE_TAC[SUBSET;IN];
2812   REPEAT STRIP_TAC;
2813   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2814   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2815   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2816   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2817   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2818   EXISTS_TAC `\x. y < x /\ x < z`;
2819   ASM_REWRITE_TAC[];
2820   REWRITE_TAC[SUBSET;IN];
2821   REPEAT STRIP_TAC;
2822   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2823   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2824   (* save *)
2825   REWRITE_TAC[TL;APPEND;ALL2;real_gt;interpsigns;interpsign];
2826   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2827   REWRITE_ALL[interpsigns;ALL2;];
2828   ASM_REWRITE_TAC[];
2829   REWRITE_TAC[interpsign];
2830   REWRITE_ALL[real_gt];
2831   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] neg_pos_neq_thm);
2832   REWRITE_ALL[real_ordered_list;HD;NOT_CONS_NIL;];
2833   ASM_REWRITE_TAC[];
2834   STRIP_TAC;
2835   LABEL_ALL_TAC;
2836   PROVE_ASSUM_ANTECEDENT_TAC 0;
2837   REPEAT STRIP_TAC;
2838   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;];
2839   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;];
2840   ASM_MESON_TAC[real_gt;interpsigns;ALL2;interpsign;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2841   POP_ASSUM MP_TAC THEN STRIP_TAC;
2842   EXISTS_TAC `X`;
2843   REWRITE_ALL[interpsign;real_gt];
2844   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2845   ASM_MESON_TAC[real_gt;];
2846   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2847   FIRST_ASSUM MATCH_MP_TAC;
2848   ASM_REWRITE_TAC[];
2849   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2850   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
2851   ASM_MESON_TAC[real_gt;REAL_LT_TRANS;];
2852   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2853   EXISTS_TAC `\x. y < x /\ x < z`;
2854   ASM_REWRITE_TAC[];
2855   REWRITE_TAC[SUBSET;IN];
2856   REPEAT STRIP_TAC;
2857   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2858   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2859   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2860   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2861   EXISTS_TAC `\x. y < x /\ x < z`;
2862   ASM_REWRITE_TAC[];
2863   REWRITE_TAC[SUBSET;IN];
2864   REPEAT STRIP_TAC;
2865   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2866   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2867   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2868   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2869   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2870   EXISTS_TAC `\x. y < x /\ x < z`;
2871   ASM_REWRITE_TAC[];
2872   REWRITE_TAC[SUBSET;IN];
2873   REPEAT STRIP_TAC;
2874   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2875   ASM_MESON_TAC[real_gt;REAL_LT_TRANS];
2876   (* save *)
2877   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
2878   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
2879   CLAIM `!rts. APPEND (BUTLAST (partition_line pts))
2880        (CONS (\x. LAST pts < x /\ x < y) rts) =
2881      APPEND (APPEND (BUTLAST (partition_line pts))
2882         [\x. LAST pts < x /\ x < y]) rts`;
2883   MESON_TAC[real_gt;APPEND;APPEND_CONS];
2884   DISCH_THEN (ONCE_REWRITE_TAC o list);
2885   REPEAT STRIP_TAC;
2886   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
2887   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
2888   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
2889   ARITH_TAC;
2890   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
2891   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
2892   REPEAT STRIP_TAC;
2893   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
2894   ASM_MESON_TAC[real_gt;real_gt;ROL_APPEND];
2895   REWRITE_TAC[real_ordered_list;NOT_CONS_NIL;HD;];
2896   REPEAT (POP_ASSUM MP_TAC);
2897   REWRITE_ALL[ALL2;partition_line;HD;TL;NOT_CONS_NIL;];
2898   (* save *)
2899   COND_CASES_TAC;
2900   POP_ASSUM (REWRITE_ALL o list);
2901   REWRITE_ALL[APPEND;TL;HD;interpsigns;interpsign;ALL2;];
2902   REPEAT STRIP_TAC;
2903   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] neg_pos_neq_thm);
2904   REPEAT STRIP_TAC;
2905   LABEL_ALL_TAC;
2906   PROVE_ASSUM_ANTECEDENT_TAC 0;
2907   REPEAT STRIP_TAC;
2908   ASM_REWRITE_TAC[];
2909   ASM_MESON_TAC[real_gt;real_gt;];
2910   ASM_MESON_TAC[real_gt;real_gt;];
2911   ASM_MESON_TAC[real_gt;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2912   POP_ASSUM MP_TAC THEN STRIP_TAC;
2913   EXISTS_TAC `X`;
2914   REWRITE_ALL[interpsign;real_gt];
2915   (* save *)
2916   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[interpsigns;interpsign];
2917   FIRST_ASSUM (MP_TAC o MATCH_MP ROL_APPEND);
2918   REPEAT STRIP_TAC;
2919   ASM_MESON_TAC[real_gt;ROL_APPEND_INSERT];
2920   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
2921   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
2922   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
2923   ARITH_TAC;
2924   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
2925   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
2926   REPEAT STRIP_TAC;
2927   MATCH_MP_TAC ALL2_APPEND;
2928   ASM_REWRITE_TAC[];
2929   REWRITE_ALL[ALL2;interpsigns;interpsign];
2930   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2931   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2932   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2933   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2934   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2935   EXISTS_TAC `\x. y < x /\ x < z`;
2936   REWRITE_TAC[SUBSET;IN];
2937   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2938   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2939   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2940   EXISTS_TAC `\x. y < x /\ x < z`;
2941   REWRITE_TAC[SUBSET;IN];
2942   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2943   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2944   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2945   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2946   EXISTS_TAC `\x. y < x /\ x < z`;
2947   REWRITE_TAC[SUBSET;IN];
2948   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2949   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2950   (* save *)
2951   REWRITE_ALL[APPEND;TL;HD;interpsigns;interpsign;ALL2;];
2952   REPEAT STRIP_TAC;
2953   MP_TAC (ISPECL [`y:real`;`z:real`;`p:real list`] neg_pos_neq_thm);
2954   REPEAT STRIP_TAC;
2955   LABEL_ALL_TAC;
2956   PROVE_ASSUM_ANTECEDENT_TAC 0;
2957   REPEAT STRIP_TAC;
2958   ASM_REWRITE_TAC[];
2959   ASM_MESON_TAC[real_gt;real_gt;];
2960   ASM_MESON_TAC[real_gt;real_gt;];
2961   ASM_MESON_TAC[real_gt;real_gt;REAL_ARITH `x < y ==> ~(x = y)`;REAL_ARITH `y < x ==> ~(x = y)`];
2962   POP_ASSUM MP_TAC THEN STRIP_TAC;
2963   EXISTS_TAC `X`;
2964   REWRITE_ALL[interpsign;real_gt];
2965   (* save *)
2966   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[interpsigns;interpsign];
2967   FIRST_ASSUM (MP_TAC o MATCH_MP ROL_APPEND);
2968   REPEAT STRIP_TAC;
2969   ASM_MESON_TAC[real_gt;ROL_APPEND_INSERT];
2970   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
2971   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
2972   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
2973   ARITH_TAC;
2974   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
2975   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
2976   REPEAT STRIP_TAC;
2977   MATCH_MP_TAC ALL2_APPEND;
2978   ASM_REWRITE_TAC[];
2979   REWRITE_ALL[ALL2;interpsigns;interpsign];
2980   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
2981   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2982   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2983   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2984   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2985   EXISTS_TAC `\x. y < x /\ x < z`;
2986   REWRITE_TAC[SUBSET;IN];
2987   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2988   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2989   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2990   EXISTS_TAC `\x. y < x /\ x < z`;
2991   REWRITE_TAC[SUBSET;IN];
2992   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2993   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2994   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2995   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
2996   EXISTS_TAC `\x. y < x /\ x < z`;
2997   REWRITE_TAC[SUBSET;IN];
2998   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
2999   ASM_MESON_TAC[real_gt;real_gt;REAL_LT_TRANS;];
3000 ]);;
3001 (* }}} *)
3002
3003
3004 let INFERISIGN_ZERO_POS_POS = prove_by_refinement(
3005   `!y z p pts qts eqs sgns rgns r1 r2 r3.
3006      interpmat (APPEND pts (CONS y (CONS z qts)))
3007       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3008         (APPEND sgns
3009           (CONS (CONS Zero r1)
3010            (CONS (CONS Unknown (CONS Pos r2))
3011             (CONS (CONS Pos r3) rgns)))) ==>
3012      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
3013     interpmat (APPEND pts (CONS y (CONS z qts)))
3014       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3015         (APPEND sgns
3016           (CONS (CONS Zero r1)
3017            (CONS (CONS Pos (CONS Pos r2))
3018             (CONS (CONS Pos r3) rgns))))`,
3019 (* {{{ Proof *)
3020
3021 [
3022   REWRITE_TAC[interpmat];
3023   REPEAT STRIP_TAC;
3024   ASM_REWRITE_TAC[];
3025   CLAIM `~(sgns = [])`;
3026   REWRITE_TAC[GSYM LENGTH_0];
3027   DISCH_THEN (REWRITE_ALL o list);
3028   POP_ASSUM MP_TAC THEN ARITH_TAC;
3029   STRIP_TAC;
3030   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) = LENGTH (APPEND sgns (CONS (CONS Zero r1) (CONS (CONS Unknown (CONS Pos r2)) (CONS (CONS Pos r3) rgns))))`;
3031   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
3032   STRIP_TAC;
3033   (* save *)
3034   CASES_ON `pts = []`;
3035   POP_ASSUM (REWRITE_ALL o list);
3036   REWRITE_ALL[APPEND;];
3037   CLAIM `LENGTH sgns = 1`;
3038   POP_ASSUM (fun x -> ALL_TAC);
3039   REWRITE_ALL[LENGTH];
3040   ASM_REWRITE_TAC[];
3041   POP_ASSUM MP_TAC THEN ARITH_TAC;
3042   REWRITE_TAC[LENGTH_1];
3043   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
3044   REWRITE_ALL[APPEND];
3045   REPEAT (POP_ASSUM MP_TAC);
3046   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
3047   COND_CASES_TAC;
3048   POP_ASSUM (REWRITE_ALL o list);
3049   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
3050   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3051   REWRITE_ALL[interpsigns;ALL2;];
3052   ASM_REWRITE_TAC[];
3053   REWRITE_TAC[interpsign];
3054   REWRITE_ALL[real_gt];
3055   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_pos_pos_thm);
3056   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
3057   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3058   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
3059   ASM_MESON_TAC[real_gt;];
3060   ASM_MESON_TAC[real_gt;real_gt;];
3061   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3062   (* save *)
3063   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
3064   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3065   REWRITE_TAC[interpsign;real_gt;];
3066   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_pos_pos_thm);
3067   REWRITE_ALL[interpsign;real_ordered_list;NOT_CONS_NIL;HD;ALL2;];
3068   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3069   REWRITE_ALL[real_gt];
3070   ASM_MESON_TAC[real_gt;];
3071   ASM_MESON_TAC[real_gt;real_gt;];
3072   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3073   (* save *)
3074   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
3075   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
3076   COND_CASES_TAC;
3077   POP_ASSUM (REWRITE_ALL o list);
3078   REWRITE_TAC[TL;HD;APPEND;ALL2;];
3079   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
3080   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3081   DISCH_THEN (REWRITE_ALL o list);
3082   REPEAT STRIP_TAC;
3083   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3084   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3085   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3086   ARITH_TAC;
3087   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3088   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3089   REPEAT STRIP_TAC;
3090   REPEAT STRIP_TAC;
3091   MATCH_MP_TAC ALL2_APPEND;
3092   ASM_REWRITE_TAC[];
3093   REWRITE_ALL[ALL2;interpsigns;];
3094   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3095   REWRITE_ALL[interpsign;real_gt];
3096   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_pos_pos_thm);
3097   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3098   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3099   CLAIM `real_ordered_list [y; z]`;
3100   ASM_MESON_TAC[real_gt;ROL_APPEND];
3101   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3102   ASM_MESON_TAC[real_gt;];
3103   ASM_MESON_TAC[real_gt;real_gt;];
3104   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3105   (* save *)
3106   REWRITE_TAC[APPEND;TL;HD;ALL2;];
3107   REPEAT STRIP_TAC;
3108   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
3109   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3110   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
3111   REPEAT STRIP_TAC;
3112   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3113   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3114   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3115   ARITH_TAC;
3116   REWRITE_ALL[TL;APPEND;HD];
3117   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3118   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3119   REPEAT STRIP_TAC;
3120   REPEAT STRIP_TAC;
3121   MATCH_MP_TAC ALL2_APPEND;
3122   ASM_REWRITE_TAC[];
3123   REWRITE_ALL[ALL2;interpsigns;];
3124   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3125   REWRITE_ALL[interpsign;real_gt];
3126   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_pos_pos_thm);
3127   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3128   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3129   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
3130   ASM_MESON_TAC[real_gt;ROL_APPEND];
3131   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3132   ASM_MESON_TAC[real_gt;];
3133   ASM_MESON_TAC[real_gt;real_gt;];
3134   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3135   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3136 ]);;
3137
3138 (* }}} *)
3139
3140 let INFERISIGN_ZERO_POS_NEG = prove_by_refinement(
3141   `!y z p pts qts eqs sgns rgns r1 r2 r3.
3142      interpmat (APPEND pts (CONS y (CONS z qts)))
3143       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3144         (APPEND sgns
3145           (CONS (CONS Zero r1)
3146            (CONS (CONS Unknown (CONS Neg r2))
3147             (CONS (CONS Pos r3) rgns)))) ==>
3148      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
3149     interpmat (APPEND pts (CONS y (CONS z qts)))
3150       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3151         (APPEND sgns
3152           (CONS (CONS Zero r1)
3153            (CONS (CONS Pos (CONS Neg r2))
3154             (CONS (CONS Pos r3) rgns))))`,
3155 (* {{{ Proof *)
3156 [
3157   REWRITE_TAC[interpmat];
3158   REPEAT STRIP_TAC;
3159   ASM_REWRITE_TAC[];
3160   CLAIM `~(sgns = [])`;
3161   REWRITE_TAC[GSYM LENGTH_0];
3162   DISCH_THEN (REWRITE_ALL o list);
3163   POP_ASSUM MP_TAC THEN ARITH_TAC;
3164   STRIP_TAC;
3165   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) = LENGTH (APPEND sgns (CONS (CONS Zero r1) (CONS (CONS Unknown (CONS Neg r2)) (CONS (CONS Pos r3) rgns))))`;
3166   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
3167   STRIP_TAC;
3168   (* save *)
3169   CASES_ON `pts = []`;
3170   POP_ASSUM (REWRITE_ALL o list);
3171   REWRITE_ALL[APPEND;];
3172   CLAIM `LENGTH sgns = 1`;
3173   POP_ASSUM (fun x -> ALL_TAC);
3174   REWRITE_ALL[LENGTH];
3175   ASM_REWRITE_TAC[];
3176   POP_ASSUM MP_TAC THEN ARITH_TAC;
3177   REWRITE_TAC[LENGTH_1];
3178   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
3179   REWRITE_ALL[APPEND];
3180   REPEAT (POP_ASSUM MP_TAC);
3181   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
3182   COND_CASES_TAC;
3183   POP_ASSUM (REWRITE_ALL o list);
3184   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
3185   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3186   REWRITE_ALL[interpsigns;ALL2;];
3187   ASM_REWRITE_TAC[];
3188   REWRITE_TAC[interpsign];
3189   REWRITE_ALL[real_gt];
3190   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_pos_pos_thm);
3191   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
3192   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3193   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
3194   ASM_MESON_TAC[real_gt;];
3195   ASM_MESON_TAC[real_gt;real_gt;];
3196   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3197   (* save *)
3198   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
3199   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3200   REWRITE_TAC[interpsign;real_gt;];
3201   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_pos_pos_thm);
3202   REWRITE_ALL[interpsign;real_ordered_list;NOT_CONS_NIL;HD;ALL2;];
3203   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3204   REWRITE_ALL[real_gt];
3205   ASM_MESON_TAC[real_gt;];
3206   ASM_MESON_TAC[real_gt;real_gt;];
3207   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3208   (* save *)
3209   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
3210   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
3211   COND_CASES_TAC;
3212   POP_ASSUM (REWRITE_ALL o list);
3213   REWRITE_TAC[TL;HD;APPEND;ALL2;];
3214   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
3215   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3216   DISCH_THEN (REWRITE_ALL o list);
3217   REPEAT STRIP_TAC;
3218   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3219   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3220   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3221   ARITH_TAC;
3222   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3223   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3224   REPEAT STRIP_TAC;
3225   REPEAT STRIP_TAC;
3226   MATCH_MP_TAC ALL2_APPEND;
3227   ASM_REWRITE_TAC[];
3228   REWRITE_ALL[ALL2;interpsigns;];
3229   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3230   REWRITE_ALL[interpsign;real_gt];
3231   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_pos_pos_thm);
3232   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3233   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3234   CLAIM `real_ordered_list [y; z]`;
3235   ASM_MESON_TAC[real_gt;ROL_APPEND];
3236   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3237   ASM_MESON_TAC[real_gt;];
3238   ASM_MESON_TAC[real_gt;real_gt;];
3239   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3240   (* save *)
3241   REWRITE_TAC[APPEND;TL;HD;ALL2;];
3242   REPEAT STRIP_TAC;
3243   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
3244   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3245   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
3246   REPEAT STRIP_TAC;
3247   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3248   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3249   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3250   ARITH_TAC;
3251   REWRITE_ALL[TL;APPEND;HD];
3252   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3253   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3254   REPEAT STRIP_TAC;
3255   REPEAT STRIP_TAC;
3256   MATCH_MP_TAC ALL2_APPEND;
3257   ASM_REWRITE_TAC[];
3258   REWRITE_ALL[ALL2;interpsigns;];
3259   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3260   REWRITE_ALL[interpsign;real_gt];
3261   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_pos_pos_thm);
3262   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3263   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3264   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
3265   ASM_MESON_TAC[real_gt;ROL_APPEND];
3266   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3267   ASM_MESON_TAC[real_gt;];
3268   ASM_MESON_TAC[real_gt;real_gt;];
3269   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3270   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3271 ]);;
3272 (* }}} *)
3273
3274 let INFERISIGN_POS_ZERO_POS = prove_by_refinement(
3275   `!y z p pts qts eqs sgns rgns r1 r2 r3.
3276      interpmat (APPEND pts (CONS y (CONS z qts)))
3277       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3278         (APPEND sgns
3279           (CONS (CONS Pos r1)
3280            (CONS (CONS Unknown (CONS Pos r2))
3281             (CONS (CONS Zero r3) rgns)))) ==>
3282      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
3283     interpmat (APPEND pts (CONS y (CONS z qts)))
3284       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3285         (APPEND sgns
3286           (CONS (CONS Pos r1)
3287            (CONS (CONS Pos (CONS Pos r2))
3288             (CONS (CONS Zero r3) rgns))))`,
3289 (* {{{ Proof *)
3290 [
3291   REWRITE_TAC[interpmat];
3292   REPEAT STRIP_TAC;
3293   ASM_REWRITE_TAC[];
3294   CLAIM `~(sgns = [])`;
3295   REWRITE_TAC[GSYM LENGTH_0];
3296   DISCH_THEN (REWRITE_ALL o list);
3297   POP_ASSUM MP_TAC THEN ARITH_TAC;
3298   STRIP_TAC;
3299   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) = LENGTH (APPEND sgns (CONS (CONS Pos r1) (CONS (CONS Unknown (CONS Pos r2)) (CONS (CONS Zero r3) rgns))))`;
3300   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
3301   STRIP_TAC;
3302   (* save *)
3303   CASES_ON `pts = []`;
3304   POP_ASSUM (REWRITE_ALL o list);
3305   REWRITE_ALL[APPEND;];
3306   CLAIM `LENGTH sgns = 1`;
3307   POP_ASSUM (fun x -> ALL_TAC);
3308   REWRITE_ALL[LENGTH];
3309   ASM_REWRITE_TAC[];
3310   POP_ASSUM MP_TAC THEN ARITH_TAC;
3311   REWRITE_TAC[LENGTH_1];
3312   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
3313   REWRITE_ALL[APPEND];
3314   REPEAT (POP_ASSUM MP_TAC);
3315   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
3316   COND_CASES_TAC;
3317   POP_ASSUM (REWRITE_ALL o list);
3318   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
3319   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3320   REWRITE_ALL[interpsigns;ALL2;];
3321   ASM_REWRITE_TAC[];
3322   REWRITE_TAC[interpsign];
3323   REWRITE_ALL[real_gt];
3324   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] pos_zero_pos_thm);
3325   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
3326   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3327   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
3328   ASM_MESON_TAC[real_gt;];
3329   ASM_MESON_TAC[real_gt;real_gt;];
3330   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3331   (* save *)
3332   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
3333   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3334   REWRITE_TAC[interpsign;real_gt;];
3335   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] pos_zero_pos_thm);
3336   REWRITE_ALL[interpsign;real_ordered_list;NOT_CONS_NIL;HD;ALL2;];
3337   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3338   REWRITE_ALL[real_gt];
3339   ASM_MESON_TAC[real_gt;];
3340   ASM_MESON_TAC[real_gt;real_gt;];
3341   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3342   (* save *)
3343   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
3344   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
3345   COND_CASES_TAC;
3346   POP_ASSUM (REWRITE_ALL o list);
3347   REWRITE_TAC[TL;HD;APPEND;ALL2;];
3348   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
3349   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3350   DISCH_THEN (REWRITE_ALL o list);
3351   REPEAT STRIP_TAC;
3352   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3353   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3354   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3355   ARITH_TAC;
3356   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3357   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3358   REPEAT STRIP_TAC;
3359   REPEAT STRIP_TAC;
3360   MATCH_MP_TAC ALL2_APPEND;
3361   ASM_REWRITE_TAC[];
3362   REWRITE_ALL[ALL2;interpsigns;];
3363   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3364   REWRITE_ALL[interpsign;real_gt];
3365   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] pos_zero_pos_thm);
3366   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3367   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3368   CLAIM `real_ordered_list [y; z]`;
3369   ASM_MESON_TAC[real_gt;ROL_APPEND];
3370   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3371   ASM_MESON_TAC[real_gt;];
3372   ASM_MESON_TAC[real_gt;real_gt;];
3373   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3374   (* save *)
3375   REWRITE_TAC[APPEND;TL;HD;ALL2;];
3376   REPEAT STRIP_TAC;
3377   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
3378   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3379   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
3380   REPEAT STRIP_TAC;
3381   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3382   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3383   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3384   ARITH_TAC;
3385   REWRITE_ALL[TL;APPEND;HD];
3386   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3387   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3388   REPEAT STRIP_TAC;
3389   REPEAT STRIP_TAC;
3390   MATCH_MP_TAC ALL2_APPEND;
3391   ASM_REWRITE_TAC[];
3392   REWRITE_ALL[ALL2;interpsigns;];
3393   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3394   REWRITE_ALL[interpsign;real_gt];
3395   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] pos_zero_pos_thm);
3396   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3397   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3398   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
3399   ASM_MESON_TAC[real_gt;ROL_APPEND];
3400   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3401   ASM_MESON_TAC[real_gt;];
3402   ASM_MESON_TAC[real_gt;real_gt;];
3403   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3404   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3405 ]);;
3406 (* }}} *)
3407
3408 let INFERISIGN_POS_ZERO_NEG = prove_by_refinement(
3409   `!y z p pts qts eqs sgns rgns r1 r2 r3.
3410      interpmat (APPEND pts (CONS y (CONS z qts)))
3411       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3412         (APPEND sgns
3413           (CONS (CONS Pos r1)
3414            (CONS (CONS Unknown (CONS Neg r2))
3415             (CONS (CONS Zero r3) rgns)))) ==>
3416      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
3417     interpmat (APPEND pts (CONS y (CONS z qts)))
3418       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3419         (APPEND sgns
3420           (CONS (CONS Pos r1)
3421            (CONS (CONS Pos (CONS Neg r2))
3422             (CONS (CONS Zero r3) rgns))))`,
3423 (* {{{ Proof *)
3424 [
3425   REWRITE_TAC[interpmat];
3426   REPEAT STRIP_TAC;
3427   ASM_REWRITE_TAC[];
3428   CLAIM `~(sgns = [])`;
3429   REWRITE_TAC[GSYM LENGTH_0];
3430   DISCH_THEN (REWRITE_ALL o list);
3431   POP_ASSUM MP_TAC THEN ARITH_TAC;
3432   STRIP_TAC;
3433   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) = LENGTH (APPEND sgns (CONS (CONS Pos r1) (CONS (CONS Unknown (CONS Neg r2)) (CONS (CONS Zero r3) rgns))))`;
3434   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
3435   STRIP_TAC;
3436   (* save *)
3437   CASES_ON `pts = []`;
3438   POP_ASSUM (REWRITE_ALL o list);
3439   REWRITE_ALL[APPEND;];
3440   CLAIM `LENGTH sgns = 1`;
3441   POP_ASSUM (fun x -> ALL_TAC);
3442   REWRITE_ALL[LENGTH];
3443   ASM_REWRITE_TAC[];
3444   POP_ASSUM MP_TAC THEN ARITH_TAC;
3445   REWRITE_TAC[LENGTH_1];
3446   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
3447   REWRITE_ALL[APPEND];
3448   REPEAT (POP_ASSUM MP_TAC);
3449   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
3450   COND_CASES_TAC;
3451   POP_ASSUM (REWRITE_ALL o list);
3452   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
3453   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3454   REWRITE_ALL[interpsigns;ALL2;];
3455   ASM_REWRITE_TAC[];
3456   REWRITE_TAC[interpsign];
3457   REWRITE_ALL[real_gt];
3458   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] pos_zero_pos_thm);
3459   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
3460   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3461   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
3462   ASM_MESON_TAC[real_gt;];
3463   ASM_MESON_TAC[real_gt;real_gt;];
3464   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3465   (* save *)
3466   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
3467   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3468   REWRITE_TAC[interpsign;real_gt;];
3469   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] pos_zero_pos_thm);
3470   REWRITE_ALL[interpsign;real_ordered_list;NOT_CONS_NIL;HD;ALL2;];
3471   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3472   REWRITE_ALL[real_gt];
3473   ASM_MESON_TAC[real_gt;];
3474   ASM_MESON_TAC[real_gt;real_gt;];
3475   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3476   (* save *)
3477   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
3478   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
3479   COND_CASES_TAC;
3480   POP_ASSUM (REWRITE_ALL o list);
3481   REWRITE_TAC[TL;HD;APPEND;ALL2;];
3482   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
3483   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3484   DISCH_THEN (REWRITE_ALL o list);
3485   REPEAT STRIP_TAC;
3486   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3487   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3488   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3489   ARITH_TAC;
3490   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3491   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3492   REPEAT STRIP_TAC;
3493   REPEAT STRIP_TAC;
3494   MATCH_MP_TAC ALL2_APPEND;
3495   ASM_REWRITE_TAC[];
3496   REWRITE_ALL[ALL2;interpsigns;];
3497   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3498   REWRITE_ALL[interpsign;real_gt];
3499   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] pos_zero_pos_thm);
3500   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3501   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3502   CLAIM `real_ordered_list [y; z]`;
3503   ASM_MESON_TAC[real_gt;ROL_APPEND];
3504   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3505   ASM_MESON_TAC[real_gt;];
3506   ASM_MESON_TAC[real_gt;real_gt;];
3507   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3508   (* save *)
3509   REWRITE_TAC[APPEND;TL;HD;ALL2;];
3510   REPEAT STRIP_TAC;
3511   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
3512   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3513   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
3514   REPEAT STRIP_TAC;
3515   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3516   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3517   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3518   ARITH_TAC;
3519   REWRITE_ALL[TL;APPEND;HD];
3520   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3521   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3522   REPEAT STRIP_TAC;
3523   REPEAT STRIP_TAC;
3524   MATCH_MP_TAC ALL2_APPEND;
3525   ASM_REWRITE_TAC[];
3526   REWRITE_ALL[ALL2;interpsigns;];
3527   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3528   REWRITE_ALL[interpsign;real_gt];
3529   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] pos_zero_pos_thm);
3530   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3531   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3532   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
3533   ASM_MESON_TAC[real_gt;ROL_APPEND];
3534   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3535   ASM_MESON_TAC[real_gt;];
3536   ASM_MESON_TAC[real_gt;real_gt;];
3537   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3538   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3539 ]);;
3540 (* }}} *)
3541
3542 let INFERISIGN_ZERO_NEG_POS = prove_by_refinement(
3543   `!y z p pts qts eqs sgns rgns r1 r2 r3.
3544      interpmat (APPEND pts (CONS y (CONS z qts)))
3545       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3546         (APPEND sgns
3547           (CONS (CONS Zero r1)
3548            (CONS (CONS Unknown (CONS Pos r2))
3549             (CONS (CONS Neg r3) rgns)))) ==>
3550      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
3551     interpmat (APPEND pts (CONS y (CONS z qts)))
3552       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3553         (APPEND sgns
3554           (CONS (CONS Zero r1)
3555            (CONS (CONS Neg (CONS Pos r2))
3556             (CONS (CONS Neg r3) rgns))))`,
3557 (* {{{ Proof *)
3558 [
3559   REWRITE_TAC[interpmat];
3560   REPEAT STRIP_TAC;
3561   ASM_REWRITE_TAC[];
3562   CLAIM `~(sgns = [])`;
3563   REWRITE_TAC[GSYM LENGTH_0];
3564   DISCH_THEN (REWRITE_ALL o list);
3565   POP_ASSUM MP_TAC THEN ARITH_TAC;
3566   STRIP_TAC;
3567   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) =
3568    LENGTH (APPEND sgns (CONS (CONS Zero r1)
3569    (CONS (CONS Unknown (CONS Pos r2)) (CONS (CONS Neg r3) rgns))))`;
3570   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
3571   STRIP_TAC;
3572   (* save *)
3573   CASES_ON `pts = []`;
3574   POP_ASSUM (REWRITE_ALL o list);
3575   REWRITE_ALL[APPEND;];
3576   CLAIM `LENGTH sgns = 1`;
3577   POP_ASSUM (fun x -> ALL_TAC);
3578   REWRITE_ALL[LENGTH];
3579   ASM_REWRITE_TAC[];
3580   POP_ASSUM MP_TAC THEN ARITH_TAC;
3581   REWRITE_TAC[LENGTH_1];
3582   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
3583   REWRITE_ALL[APPEND];
3584   REPEAT (POP_ASSUM MP_TAC);
3585   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
3586   COND_CASES_TAC;
3587   POP_ASSUM (REWRITE_ALL o list);
3588   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
3589   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3590   REWRITE_ALL[interpsigns;ALL2;];
3591   ASM_REWRITE_TAC[];
3592   REWRITE_TAC[interpsign];
3593   REWRITE_ALL[real_gt];
3594   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_neg_neg_thm);
3595   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
3596   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3597   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
3598   ASM_MESON_TAC[real_gt;];
3599   ASM_MESON_TAC[real_gt;real_gt;];
3600   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3601   (* save *)
3602   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
3603   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3604   REWRITE_TAC[interpsign;real_gt;];
3605   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_neg_neg_thm);
3606   REWRITE_ALL[interpsign;real_ordered_list;NOT_CONS_NIL;HD;ALL2;];
3607   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3608   REWRITE_ALL[real_gt];
3609   ASM_MESON_TAC[real_gt;];
3610   ASM_MESON_TAC[real_gt;real_gt;];
3611   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3612   (* save *)
3613   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
3614   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
3615   COND_CASES_TAC;
3616   POP_ASSUM (REWRITE_ALL o list);
3617   REWRITE_TAC[TL;HD;APPEND;ALL2;];
3618   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
3619   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3620   DISCH_THEN (REWRITE_ALL o list);
3621   REPEAT STRIP_TAC;
3622   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3623   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3624   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3625   ARITH_TAC;
3626   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3627   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3628   REPEAT STRIP_TAC;
3629   REPEAT STRIP_TAC;
3630   MATCH_MP_TAC ALL2_APPEND;
3631   ASM_REWRITE_TAC[];
3632   REWRITE_ALL[ALL2;interpsigns;];
3633   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3634   REWRITE_ALL[interpsign;real_gt];
3635   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_neg_neg_thm);
3636   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3637   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3638   CLAIM `real_ordered_list [y; z]`;
3639   ASM_MESON_TAC[real_gt;ROL_APPEND];
3640   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3641   ASM_MESON_TAC[real_gt;];
3642   ASM_MESON_TAC[real_gt;real_gt;];
3643   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3644   (* save *)
3645   REWRITE_TAC[APPEND;TL;HD;ALL2;];
3646   REPEAT STRIP_TAC;
3647   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
3648   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3649   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
3650   REPEAT STRIP_TAC;
3651   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3652   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3653   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3654   ARITH_TAC;
3655   REWRITE_ALL[TL;APPEND;HD];
3656   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3657   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3658   REPEAT STRIP_TAC;
3659   REPEAT STRIP_TAC;
3660   MATCH_MP_TAC ALL2_APPEND;
3661   ASM_REWRITE_TAC[];
3662   REWRITE_ALL[ALL2;interpsigns;];
3663   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3664   REWRITE_ALL[interpsign;real_gt];
3665   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_neg_neg_thm);
3666   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3667   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3668   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
3669   ASM_MESON_TAC[real_gt;ROL_APPEND];
3670   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3671   ASM_MESON_TAC[real_gt;];
3672   ASM_MESON_TAC[real_gt;real_gt;];
3673   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3674   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3675 ]);;
3676 (* }}} *)
3677
3678 let INFERISIGN_ZERO_NEG_NEG = prove_by_refinement(
3679   `!y z p pts qts eqs sgns rgns r1 r2 r3.
3680      interpmat (APPEND pts (CONS y (CONS z qts)))
3681       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3682         (APPEND sgns
3683           (CONS (CONS Zero r1)
3684            (CONS (CONS Unknown (CONS Neg r2))
3685             (CONS (CONS Neg r3) rgns)))) ==>
3686      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
3687     interpmat (APPEND pts (CONS y (CONS z qts)))
3688       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3689         (APPEND sgns
3690           (CONS (CONS Zero r1)
3691            (CONS (CONS Neg (CONS Neg r2))
3692             (CONS (CONS Neg r3) rgns))))`,
3693 (* {{{ Proof *)
3694 [
3695   REWRITE_TAC[interpmat];
3696   REPEAT STRIP_TAC;
3697   ASM_REWRITE_TAC[];
3698   CLAIM `~(sgns = [])`;
3699   REWRITE_TAC[GSYM LENGTH_0];
3700   DISCH_THEN (REWRITE_ALL o list);
3701   POP_ASSUM MP_TAC THEN ARITH_TAC;
3702   STRIP_TAC;
3703   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) =
3704    LENGTH (APPEND sgns (CONS (CONS Zero r1)
3705    (CONS (CONS Unknown (CONS Neg r2)) (CONS (CONS Neg r3) rgns))))`;
3706   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
3707   STRIP_TAC;
3708   (* save *)
3709   CASES_ON `pts = []`;
3710   POP_ASSUM (REWRITE_ALL o list);
3711   REWRITE_ALL[APPEND;];
3712   CLAIM `LENGTH sgns = 1`;
3713   POP_ASSUM (fun x -> ALL_TAC);
3714   REWRITE_ALL[LENGTH];
3715   ASM_REWRITE_TAC[];
3716   POP_ASSUM MP_TAC THEN ARITH_TAC;
3717   REWRITE_TAC[LENGTH_1];
3718   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
3719   REWRITE_ALL[APPEND];
3720   REPEAT (POP_ASSUM MP_TAC);
3721   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
3722   COND_CASES_TAC;
3723   POP_ASSUM (REWRITE_ALL o list);
3724   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
3725   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3726   REWRITE_ALL[interpsigns;ALL2;];
3727   ASM_REWRITE_TAC[];
3728   REWRITE_TAC[interpsign];
3729   REWRITE_ALL[real_gt];
3730   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_neg_neg_thm);
3731   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
3732   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3733   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
3734   ASM_MESON_TAC[real_gt;];
3735   ASM_MESON_TAC[real_gt;real_gt;];
3736   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3737   (* save *)
3738   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
3739   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3740   REWRITE_TAC[interpsign;real_gt;];
3741   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_neg_neg_thm);
3742   REWRITE_ALL[interpsign;real_ordered_list;NOT_CONS_NIL;HD;ALL2;];
3743   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3744   REWRITE_ALL[real_gt];
3745   ASM_MESON_TAC[real_gt;];
3746   ASM_MESON_TAC[real_gt;real_gt;];
3747   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3748   (* save *)
3749   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
3750   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
3751   COND_CASES_TAC;
3752   POP_ASSUM (REWRITE_ALL o list);
3753   REWRITE_TAC[TL;HD;APPEND;ALL2;];
3754   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
3755   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3756   DISCH_THEN (REWRITE_ALL o list);
3757   REPEAT STRIP_TAC;
3758   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3759   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3760   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3761   ARITH_TAC;
3762   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3763   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3764   REPEAT STRIP_TAC;
3765   REPEAT STRIP_TAC;
3766   MATCH_MP_TAC ALL2_APPEND;
3767   ASM_REWRITE_TAC[];
3768   REWRITE_ALL[ALL2;interpsigns;];
3769   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3770   REWRITE_ALL[interpsign;real_gt];
3771   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_neg_neg_thm);
3772   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3773   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3774   CLAIM `real_ordered_list [y; z]`;
3775   ASM_MESON_TAC[real_gt;ROL_APPEND];
3776   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3777   ASM_MESON_TAC[real_gt;];
3778   ASM_MESON_TAC[real_gt;real_gt;];
3779   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3780   (* save *)
3781   REWRITE_TAC[APPEND;TL;HD;ALL2;];
3782   REPEAT STRIP_TAC;
3783   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
3784   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3785   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
3786   REPEAT STRIP_TAC;
3787   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3788   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3789   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3790   ARITH_TAC;
3791   REWRITE_ALL[TL;APPEND;HD];
3792   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3793   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3794   REPEAT STRIP_TAC;
3795   REPEAT STRIP_TAC;
3796   MATCH_MP_TAC ALL2_APPEND;
3797   ASM_REWRITE_TAC[];
3798   REWRITE_ALL[ALL2;interpsigns;];
3799   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3800   REWRITE_ALL[interpsign;real_gt];
3801   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] zero_neg_neg_thm);
3802   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3803   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3804   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
3805   ASM_MESON_TAC[real_gt;ROL_APPEND];
3806   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3807   ASM_MESON_TAC[real_gt;];
3808   ASM_MESON_TAC[real_gt;real_gt;];
3809   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3810   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3811 ]);;
3812 (* }}} *)
3813
3814
3815
3816 let INFERISIGN_NEG_ZERO_NEG = prove_by_refinement(
3817   `!y z p pts qts eqs sgns rgns r1 r2 r3.
3818      interpmat (APPEND pts (CONS y (CONS z qts)))
3819       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3820         (APPEND sgns
3821           (CONS (CONS Neg r1)
3822            (CONS (CONS Unknown (CONS Neg r2))
3823             (CONS (CONS Zero r3) rgns)))) ==>
3824      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
3825     interpmat (APPEND pts (CONS y (CONS z qts)))
3826       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3827         (APPEND sgns
3828           (CONS (CONS Neg r1)
3829            (CONS (CONS Neg (CONS Neg r2))
3830             (CONS (CONS Zero r3) rgns))))`,
3831 (* {{{ Proof *)
3832 [
3833   REWRITE_TAC[interpmat];
3834   REPEAT STRIP_TAC;
3835   ASM_REWRITE_TAC[];
3836   CLAIM `~(sgns = [])`;
3837   REWRITE_TAC[GSYM LENGTH_0];
3838   DISCH_THEN (REWRITE_ALL o list);
3839   POP_ASSUM MP_TAC THEN ARITH_TAC;
3840   STRIP_TAC;
3841   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) =
3842    LENGTH (APPEND sgns (CONS (CONS Neg r1)
3843    (CONS (CONS Unknown (CONS Neg r2)) (CONS (CONS Zero r3) rgns))))`;
3844   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
3845   STRIP_TAC;
3846   (* save *)
3847   CASES_ON `pts = []`;
3848   POP_ASSUM (REWRITE_ALL o list);
3849   REWRITE_ALL[APPEND;];
3850   CLAIM `LENGTH sgns = 1`;
3851   POP_ASSUM (fun x -> ALL_TAC);
3852   REWRITE_ALL[LENGTH];
3853   ASM_REWRITE_TAC[];
3854   POP_ASSUM MP_TAC THEN ARITH_TAC;
3855   REWRITE_TAC[LENGTH_1];
3856   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
3857   REWRITE_ALL[APPEND];
3858   REPEAT (POP_ASSUM MP_TAC);
3859   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
3860   COND_CASES_TAC;
3861   POP_ASSUM (REWRITE_ALL o list);
3862   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
3863   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3864   REWRITE_ALL[interpsigns;ALL2;];
3865   ASM_REWRITE_TAC[];
3866   REWRITE_TAC[interpsign];
3867   REWRITE_ALL[real_gt];
3868   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] neg_zero_neg_thm);
3869   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
3870   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3871   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
3872   ASM_MESON_TAC[real_gt;];
3873   ASM_MESON_TAC[real_gt;real_gt;];
3874   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3875   (* save *)
3876   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
3877   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3878   REWRITE_TAC[interpsign;real_gt;];
3879   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] neg_zero_neg_thm);
3880   REWRITE_ALL[interpsign;real_ordered_list;NOT_CONS_NIL;HD;ALL2;];
3881   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3882   REWRITE_ALL[real_gt];
3883   ASM_MESON_TAC[real_gt;];
3884   ASM_MESON_TAC[real_gt;real_gt;];
3885   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
3886   (* save *)
3887   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
3888   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
3889   COND_CASES_TAC;
3890   POP_ASSUM (REWRITE_ALL o list);
3891   REWRITE_TAC[TL;HD;APPEND;ALL2;];
3892   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
3893   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3894   DISCH_THEN (REWRITE_ALL o list);
3895   REPEAT STRIP_TAC;
3896   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3897   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3898   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3899   ARITH_TAC;
3900   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3901   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3902   REPEAT STRIP_TAC;
3903   REPEAT STRIP_TAC;
3904   MATCH_MP_TAC ALL2_APPEND;
3905   ASM_REWRITE_TAC[];
3906   REWRITE_ALL[ALL2;interpsigns;];
3907   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3908   REWRITE_ALL[interpsign;real_gt];
3909   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] neg_zero_neg_thm);
3910   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3911   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3912   CLAIM `real_ordered_list [y; z]`;
3913   ASM_MESON_TAC[real_gt;ROL_APPEND];
3914   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3915   ASM_MESON_TAC[real_gt;];
3916   ASM_MESON_TAC[real_gt;real_gt;];
3917   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3918   (* save *)
3919   REWRITE_TAC[APPEND;TL;HD;ALL2;];
3920   REPEAT STRIP_TAC;
3921   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
3922   MESON_TAC[real_gt;APPEND;APPEND_CONS];
3923   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
3924   REPEAT STRIP_TAC;
3925   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
3926   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
3927   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
3928   ARITH_TAC;
3929   REWRITE_ALL[TL;APPEND;HD];
3930   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
3931   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
3932   REPEAT STRIP_TAC;
3933   REPEAT STRIP_TAC;
3934   MATCH_MP_TAC ALL2_APPEND;
3935   ASM_REWRITE_TAC[];
3936   REWRITE_ALL[ALL2;interpsigns;];
3937   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3938   REWRITE_ALL[interpsign;real_gt];
3939   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] neg_zero_neg_thm);
3940   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
3941   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
3942   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
3943   ASM_MESON_TAC[real_gt;ROL_APPEND];
3944   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
3945   ASM_MESON_TAC[real_gt;];
3946   ASM_MESON_TAC[real_gt;real_gt;];
3947   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3948   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
3949 ]);;
3950 (* }}} *)
3951
3952 let INFERISIGN_NEG_ZERO_POS = prove_by_refinement(
3953   `!y z p pts qts eqs sgns rgns r1 r2 r3.
3954      interpmat (APPEND pts (CONS y (CONS z qts)))
3955       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3956         (APPEND sgns
3957           (CONS (CONS Neg r1)
3958            (CONS (CONS Unknown (CONS Pos r2))
3959             (CONS (CONS Zero r3) rgns)))) ==>
3960      (LENGTH sgns = 2 * LENGTH pts + 1) ==>
3961     interpmat (APPEND pts (CONS y (CONS z qts)))
3962       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
3963         (APPEND sgns
3964           (CONS (CONS Neg r1)
3965            (CONS (CONS Neg (CONS Pos r2))
3966             (CONS (CONS Zero r3) rgns))))`,
3967 (* {{{ Proof *)
3968 [
3969   REWRITE_TAC[interpmat];
3970   REPEAT STRIP_TAC;
3971   ASM_REWRITE_TAC[];
3972   CLAIM `~(sgns = [])`;
3973   REWRITE_TAC[GSYM LENGTH_0];
3974   DISCH_THEN (REWRITE_ALL o list);
3975   POP_ASSUM MP_TAC THEN ARITH_TAC;
3976   STRIP_TAC;
3977   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) =
3978    LENGTH (APPEND sgns (CONS (CONS Neg r1)
3979    (CONS (CONS Unknown (CONS Pos r2)) (CONS (CONS Zero r3) rgns))))`;
3980   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
3981   STRIP_TAC;
3982   (* save *)
3983   CASES_ON `pts = []`;
3984   POP_ASSUM (REWRITE_ALL o list);
3985   REWRITE_ALL[APPEND;];
3986   CLAIM `LENGTH sgns = 1`;
3987   POP_ASSUM (fun x -> ALL_TAC);
3988   REWRITE_ALL[LENGTH];
3989   ASM_REWRITE_TAC[];
3990   POP_ASSUM MP_TAC THEN ARITH_TAC;
3991   REWRITE_TAC[LENGTH_1];
3992   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
3993   REWRITE_ALL[APPEND];
3994   REPEAT (POP_ASSUM MP_TAC);
3995   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
3996   COND_CASES_TAC;
3997   POP_ASSUM (REWRITE_ALL o list);
3998   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
3999   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4000   REWRITE_ALL[interpsigns;ALL2;];
4001   ASM_REWRITE_TAC[];
4002   REWRITE_TAC[interpsign];
4003   REWRITE_ALL[real_gt];
4004   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] neg_zero_neg_thm);
4005   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
4006   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4007   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
4008   ASM_MESON_TAC[real_gt;];
4009   ASM_MESON_TAC[real_gt;real_gt;];
4010   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
4011   (* save *)
4012   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
4013   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4014   REWRITE_TAC[interpsign;real_gt;];
4015   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] neg_zero_neg_thm);
4016   REWRITE_ALL[interpsign;real_ordered_list;NOT_CONS_NIL;HD;ALL2;];
4017   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4018   REWRITE_ALL[real_gt];
4019   ASM_MESON_TAC[real_gt;];
4020   ASM_MESON_TAC[real_gt;real_gt;];
4021   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
4022   (* save *)
4023   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
4024   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
4025   COND_CASES_TAC;
4026   POP_ASSUM (REWRITE_ALL o list);
4027   REWRITE_TAC[TL;HD;APPEND;ALL2;];
4028   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
4029   MESON_TAC[real_gt;APPEND;APPEND_CONS];
4030   DISCH_THEN (REWRITE_ALL o list);
4031   REPEAT STRIP_TAC;
4032   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
4033   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
4034   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
4035   ARITH_TAC;
4036   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
4037   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
4038   REPEAT STRIP_TAC;
4039   REPEAT STRIP_TAC;
4040   MATCH_MP_TAC ALL2_APPEND;
4041   ASM_REWRITE_TAC[];
4042   REWRITE_ALL[ALL2;interpsigns;];
4043   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4044   REWRITE_ALL[interpsign;real_gt];
4045   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] neg_zero_neg_thm);
4046   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
4047   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4048   CLAIM `real_ordered_list [y; z]`;
4049   ASM_MESON_TAC[real_gt;ROL_APPEND];
4050   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
4051   ASM_MESON_TAC[real_gt;];
4052   ASM_MESON_TAC[real_gt;real_gt;];
4053   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
4054   (* save *)
4055   REWRITE_TAC[APPEND;TL;HD;ALL2;];
4056   REPEAT STRIP_TAC;
4057   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
4058   MESON_TAC[real_gt;APPEND;APPEND_CONS];
4059   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
4060   REPEAT STRIP_TAC;
4061   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH sgns`;
4062   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
4063   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
4064   ARITH_TAC;
4065   REWRITE_ALL[TL;APPEND;HD];
4066   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
4067   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
4068   REPEAT STRIP_TAC;
4069   REPEAT STRIP_TAC;
4070   MATCH_MP_TAC ALL2_APPEND;
4071   ASM_REWRITE_TAC[];
4072   REWRITE_ALL[ALL2;interpsigns;];
4073   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4074   REWRITE_ALL[interpsign;real_gt];
4075   MATCH_MP_TAC (REWRITE_RULE[real_gt;IMP_AND_THM] neg_zero_neg_thm);
4076   REWRITE_ALL[interpsign;real_ordered_list;ROL_APPEND;NOT_CONS_NIL;HD;ALL2;real_ordered_list;APPEND;];
4077   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4078   CLAIM `real_ordered_list (CONS y (CONS z qts))`;
4079   ASM_MESON_TAC[real_gt;ROL_APPEND];
4080   REWRITE_ALL[NOT_CONS_NIL;real_gt;real_ordered_list;HD;];
4081   ASM_MESON_TAC[real_gt;];
4082   ASM_MESON_TAC[real_gt;real_gt;];
4083   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
4084   ASM_MESON_TAC[real_gt;REAL_ARITH `x < y ==> ~(x = y)`];
4085 ]);;
4086 (* }}} *)
4087
4088 let INFERISIGN_ZERO_ZERO_POS = prove_by_refinement(
4089   `!y z p pts qts eqs sgns rgns r1 r2 r3.
4090      interpmat (APPEND pts (CONS y (CONS z qts)))
4091       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
4092         (APPEND sgns
4093           (CONS (CONS Zero r1)
4094            (CONS (CONS Unknown (CONS Pos r2))
4095             (CONS (CONS Zero r3) rgns)))) ==>
4096      (LENGTH sgns = 2 * LENGTH pts + 1) ==> F`,
4097 (* {{{ Proof *)
4098 [
4099   REWRITE_TAC[interpmat];
4100   REPEAT STRIP_TAC;
4101   ASM_REWRITE_TAC[];
4102   CLAIM `~((sgns:(sign list) list) = [])`;
4103   REWRITE_TAC[GSYM LENGTH_0];
4104   DISCH_THEN (REWRITE_ALL o list);
4105   POP_ASSUM MP_TAC THEN ARITH_TAC;
4106   STRIP_TAC;
4107   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) =
4108    LENGTH (APPEND sgns (CONS (CONS Zero r1)
4109    (CONS (CONS Unknown (CONS Pos r2)) (CONS (CONS Zero r3) rgns))))`;
4110   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
4111   STRIP_TAC;
4112   (* save *)
4113   CASES_ON `pts = []`;
4114   POP_ASSUM (REWRITE_ALL o list);
4115   REWRITE_ALL[APPEND;];
4116   CLAIM `LENGTH (sgns:(sign list) list) = 1`;
4117   POP_ASSUM (fun x -> ALL_TAC);
4118   REWRITE_ALL[LENGTH];
4119   ASM_REWRITE_TAC[];
4120   POP_ASSUM MP_TAC THEN ARITH_TAC;
4121   REWRITE_TAC[LENGTH_1];
4122   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
4123   REWRITE_ALL[APPEND];
4124   REPEAT (POP_ASSUM MP_TAC);
4125   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
4126   COND_CASES_TAC;
4127   POP_ASSUM (REWRITE_ALL o list);
4128   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
4129   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4130   REWRITE_ALL[interpsigns;ALL2;];
4131   ASM_REWRITE_TAC[];
4132   REWRITE_TAC[interpsign];
4133   REWRITE_ALL[real_gt];
4134   MATCH_MP_TAC (PURE_REWRITE_RULE[real_gt;IMP_AND_THM] eq_eq_false_thm);
4135   EXISTS_TAC `y`;
4136   EXISTS_TAC `z`;
4137   EXISTS_TAC `p`;
4138   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
4139   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
4140   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4141   ASM_MESON_TAC[real_gt;];
4142   ASM_MESON_TAC[real_gt;real_gt;];
4143   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
4144   (* save *)
4145   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
4146   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4147   REWRITE_TAC[interpsign;real_gt;];
4148   MATCH_MP_TAC (PURE_REWRITE_RULE[real_gt;IMP_AND_THM] eq_eq_false_thm);
4149   EXISTS_TAC `y`;
4150   EXISTS_TAC `z`;
4151   EXISTS_TAC `p`;
4152   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
4153   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
4154   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4155   ASM_MESON_TAC[real_gt;];
4156   ASM_MESON_TAC[real_gt;real_gt;];
4157   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
4158   (* save *)
4159   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
4160   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
4161   COND_CASES_TAC;
4162   POP_ASSUM (REWRITE_ALL o list);
4163   REWRITE_TAC[TL;HD;APPEND;ALL2;];
4164   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
4165   MESON_TAC[real_gt;APPEND;APPEND_CONS];
4166   DISCH_THEN (REWRITE_ALL o list);
4167   REPEAT STRIP_TAC;
4168   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH (sgns:(sign list) list)`;
4169   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
4170   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
4171   ARITH_TAC;
4172   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
4173   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
4174   REPEAT STRIP_TAC;
4175   MATCH_MP_TAC (PURE_REWRITE_RULE[real_gt;IMP_AND_THM] eq_eq_false_thm);
4176   EXISTS_TAC `y`;
4177   EXISTS_TAC `z`;
4178   EXISTS_TAC `p`;
4179   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
4180   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
4181   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4182   CLAIM `real_ordered_list [y; z]`;
4183   ASM_MESON_TAC[ROL_APPEND];
4184   REWRITE_TAC[HD;NOT_CONS_NIL;real_ordered_list];
4185   ASM_MESON_TAC[real_gt;];
4186   ASM_MESON_TAC[real_gt;real_gt;];
4187   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
4188   (* save *)
4189   REWRITE_TAC[APPEND;TL;HD;ALL2;];
4190   REPEAT STRIP_TAC;
4191   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
4192   MESON_TAC[APPEND;APPEND_CONS];
4193   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
4194   REPEAT STRIP_TAC;
4195   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH (sgns:(sign list)list)`;
4196   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
4197   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
4198   ARITH_TAC;
4199   REWRITE_ALL[TL;APPEND;HD];
4200   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
4201   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
4202   REPEAT STRIP_TAC;
4203   REPEAT STRIP_TAC;
4204   REWRITE_ALL[ALL2;interpsigns;];
4205   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4206   REWRITE_ALL[interpsign;real_gt];
4207   MATCH_MP_TAC (PURE_REWRITE_RULE[real_gt;IMP_AND_THM] eq_eq_false_thm);
4208   EXISTS_TAC `y`;
4209   EXISTS_TAC `z`;
4210   EXISTS_TAC `p`;
4211   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
4212   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
4213   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4214   CLAIM `real_ordered_list (CONS y(CONS  z qts))`;
4215   ASM_MESON_TAC[ROL_APPEND];
4216   REWRITE_TAC[HD;NOT_CONS_NIL;real_ordered_list];
4217   STRIP_TAC;
4218   ASM_MESON_TAC[real_gt;];
4219   ASM_MESON_TAC[real_gt;real_gt;];
4220   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
4221 ]);;
4222 (* }}} *)
4223
4224 let INFERISIGN_ZERO_ZERO_NEG = prove_by_refinement(
4225   `!y z p pts qts eqs sgns rgns r1 r2 r3.
4226      interpmat (APPEND pts (CONS y (CONS z qts)))
4227       (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) eqs))
4228         (APPEND sgns
4229           (CONS (CONS Zero r1)
4230            (CONS (CONS Unknown (CONS Neg r2))
4231             (CONS (CONS Zero r3) rgns)))) ==>
4232      (LENGTH sgns = 2 * LENGTH pts + 1) ==> F`,
4233 (* {{{ Proof *)
4234 [
4235   REWRITE_TAC[interpmat];
4236   REPEAT STRIP_TAC;
4237   ASM_REWRITE_TAC[];
4238   CLAIM `~((sgns:(sign list) list) = [])`;
4239   REWRITE_TAC[GSYM LENGTH_0];
4240   DISCH_THEN (REWRITE_ALL o list);
4241   POP_ASSUM MP_TAC THEN ARITH_TAC;
4242   STRIP_TAC;
4243   CLAIM `LENGTH (partition_line (APPEND pts (CONS y (CONS z qts)))) =
4244    LENGTH (APPEND sgns (CONS (CONS Zero r1)
4245    (CONS (CONS Unknown (CONS Neg r2)) (CONS (CONS Zero r3) rgns))))`;
4246   ASM_MESON_TAC[real_gt;ALL2_LENGTH];
4247   STRIP_TAC;
4248   (* save *)
4249   CASES_ON `pts = []`;
4250   POP_ASSUM (REWRITE_ALL o list);
4251   REWRITE_ALL[APPEND;];
4252   CLAIM `LENGTH (sgns:(sign list) list) = 1`;
4253   POP_ASSUM (fun x -> ALL_TAC);
4254   REWRITE_ALL[LENGTH];
4255   ASM_REWRITE_TAC[];
4256   POP_ASSUM MP_TAC THEN ARITH_TAC;
4257   REWRITE_TAC[LENGTH_1];
4258   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
4259   REWRITE_ALL[APPEND];
4260   REPEAT (POP_ASSUM MP_TAC);
4261   REWRITE_TAC[partition_line;TL;HD;NOT_CONS_NIL;];
4262   COND_CASES_TAC;
4263   POP_ASSUM (REWRITE_ALL o list);
4264   REWRITE_TAC[TL;APPEND;ALL2;real_gt];
4265   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4266   REWRITE_ALL[interpsigns;ALL2;];
4267   ASM_REWRITE_TAC[];
4268   REWRITE_TAC[interpsign];
4269   REWRITE_ALL[real_gt];
4270   MATCH_MP_TAC (PURE_REWRITE_RULE[real_gt;IMP_AND_THM] eq_eq_false_thm);
4271   EXISTS_TAC `y`;
4272   EXISTS_TAC `z`;
4273   EXISTS_TAC `p`;
4274   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
4275   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
4276   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4277   ASM_MESON_TAC[real_gt;];
4278   ASM_MESON_TAC[real_gt;real_gt;];
4279   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
4280   (* save *)
4281   REWRITE_TAC[LENGTH;APPEND;TL;HD;ALL2;interpsigns];
4282   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4283   REWRITE_TAC[interpsign;real_gt;];
4284   MATCH_MP_TAC (PURE_REWRITE_RULE[real_gt;IMP_AND_THM] eq_eq_false_thm);
4285   EXISTS_TAC `y`;
4286   EXISTS_TAC `z`;
4287   EXISTS_TAC `p`;
4288   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
4289   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
4290   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4291   ASM_MESON_TAC[real_gt;];
4292   ASM_MESON_TAC[real_gt;real_gt;];
4293   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
4294   (* save *)
4295   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
4296   ASM_SIMP_TAC[PARTITION_LINE_APPEND;partition_line;NOT_CONS_NIL;];
4297   COND_CASES_TAC;
4298   POP_ASSUM (REWRITE_ALL o list);
4299   REWRITE_TAC[TL;HD;APPEND;ALL2;];
4300   CLAIM `APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y; \x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x] = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) [\x. x = y; \x. y < x /\ x < z; \x. x = z; \x. z < x]`;
4301   MESON_TAC[real_gt;APPEND;APPEND_CONS];
4302   DISCH_THEN (REWRITE_ALL o list);
4303   REPEAT STRIP_TAC;
4304   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH (sgns:(sign list) list)`;
4305   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
4306   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
4307   ARITH_TAC;
4308   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
4309   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
4310   REPEAT STRIP_TAC;
4311   MATCH_MP_TAC (PURE_REWRITE_RULE[real_gt;IMP_AND_THM] eq_eq_false_thm);
4312   EXISTS_TAC `y`;
4313   EXISTS_TAC `z`;
4314   EXISTS_TAC `p`;
4315   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
4316   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
4317   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4318   CLAIM `real_ordered_list [y; z]`;
4319   ASM_MESON_TAC[ROL_APPEND];
4320   REWRITE_TAC[HD;NOT_CONS_NIL;real_ordered_list];
4321   ASM_MESON_TAC[real_gt;];
4322   ASM_MESON_TAC[real_gt;real_gt;];
4323   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
4324   (* save *)
4325   REWRITE_TAC[APPEND;TL;HD;ALL2;];
4326   REPEAT STRIP_TAC;
4327   CLAIM `!j. APPEND (BUTLAST (partition_line pts)) (CONS (\x. LAST pts < x /\ x < y) j) = APPEND (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) j`;
4328   MESON_TAC[APPEND;APPEND_CONS];
4329   DISCH_THEN (fun x -> ONCE_REWRITE_TAC[x] THEN ONCE_REWRITE_ASSUMS[x]);
4330   REPEAT STRIP_TAC;
4331   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts)) [\x. LAST pts < x /\ x < y]) = LENGTH (sgns:(sign list)list)`;
4332   REWRITE_TAC[LENGTH_APPEND;LENGTH;];
4333   ASM_SIMP_TAC[LENGTH_APPEND;BUTLAST_LENGTH;LENGTH;PARTITION_LINE_NOT_NIL;PARTITION_LINE_LENGTH];
4334   ARITH_TAC;
4335   REWRITE_ALL[TL;APPEND;HD];
4336   DISCH_THEN (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
4337   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
4338   REPEAT STRIP_TAC;
4339   REPEAT STRIP_TAC;
4340   REWRITE_ALL[ALL2;interpsigns;];
4341   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4342   REWRITE_ALL[interpsign;real_gt];
4343   MATCH_MP_TAC (PURE_REWRITE_RULE[real_gt;IMP_AND_THM] eq_eq_false_thm);
4344   EXISTS_TAC `y`;
4345   EXISTS_TAC `z`;
4346   EXISTS_TAC `p`;
4347   REWRITE_ALL[real_ordered_list;NOT_CONS_NIL;HD;interpsign];
4348   REWRITE_ALL[real_gt;ALL2;interpsigns;interpsign;];
4349   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4350   CLAIM `real_ordered_list (CONS y(CONS  z qts))`;
4351   ASM_MESON_TAC[ROL_APPEND];
4352   REWRITE_TAC[HD;NOT_CONS_NIL;real_ordered_list];
4353   STRIP_TAC;
4354   ASM_MESON_TAC[real_gt;];
4355   ASM_MESON_TAC[real_gt;real_gt;];
4356   ASM_MESON_TAC[real_gt;REAL_ARITH `x > y ==> ~(x = y)`];
4357 ]);;
4358 (* }}} *)
4359
4360 let BUTLAST_ID = prove_by_refinement(
4361   `!l. ~(l = []) ==> (APPEND (BUTLAST l) [LAST l] = l)`,
4362 (* {{{ Proof *)
4363 [
4364   LIST_INDUCT_TAC;
4365   REWRITE_TAC[];
4366   DISCH_THEN (fun x -> ALL_TAC);
4367   REWRITE_TAC[BUTLAST;APPEND;LAST;];
4368   COND_CASES_TAC;
4369   ASM_REWRITE_TAC[BUTLAST;APPEND;LAST;];
4370   ASM_REWRITE_TAC[APPEND;];
4371   ASM_MESON_TAC[];
4372 ]);;
4373 (* }}} *)
4374
4375 let BUTLAST_ID = prove_by_refinement(
4376   `!l. ~(l = []) ==> (l = APPEND (BUTLAST l) [LAST l])`,
4377 (* {{{ Proof *)
4378 [
4379   MESON_TAC[BUTLAST_ID];
4380 ]);;
4381 (* }}} *)
4382
4383 let BUTLAST_NIL = prove_by_refinement(
4384   `!l. (BUTLAST l = []) <=> (l = []) \/ (?x. l = [x])`,
4385 (* {{{ Proof *)
4386 [
4387   LIST_INDUCT_TAC;
4388   REWRITE_TAC[BUTLAST;];
4389   REWRITE_TAC[BUTLAST;NOT_CONS_NIL;];
4390   COND_CASES_TAC;
4391   ASM_REWRITE_TAC[];
4392   MESON_TAC[];
4393   ASM_REWRITE_TAC[];
4394   POP_ASSUM (fun x -> REWRITE_ALL[x] THEN ASSUME_TAC x);
4395   REWRITE_TAC[NOT_CONS_NIL];
4396   STRIP_TAC;
4397   ASM_MESON_TAC[NOT_CONS_NIL;CONS_11];
4398 ]);;
4399 (* }}} *)
4400
4401 let INFIN_HD_POS_LEM = prove_by_refinement(
4402   `!pts p ps r1 sgns.
4403   interpmat pts
4404     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4405     (CONS (CONS Unknown (CONS Pos r1)) sgns)  ==>
4406    nonconstant p ==>
4407   ?xminf.
4408    interpmat (CONS xminf pts)
4409     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4410       (CONS (CONS Neg (CONS Pos r1))
4411       (CONS (CONS Neg (CONS Pos r1))
4412       (CONS (CONS Unknown (CONS Pos r1)) sgns)))`,
4413 (* {{{ Proof *)
4414 [
4415   REWRITE_TAC[interpmat;partition_line;];
4416   REPEAT STRIP_TAC;
4417   DISJ_CASES_TAC (ISPEC `pts:real list` list_CASES);
4418   POP_ASSUM (REWRITE_ALL o list);
4419   REWRITE_ALL[partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4420   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
4421   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`&0`] POLY_DIFF_DOWN_LEFT5));
4422   ASM_REWRITE_TAC[real_gt;];
4423   STRIP_TAC;
4424   EXISTS_TAC `Y`;
4425   REPEAT STRIP_TAC;
4426   FIRST_ASSUM MATCH_MP_TAC;
4427   ASM_MESON_TAC[real_gt;REAL_LT_IMP_LE];
4428   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4429   EXISTS_TAC `\x. T`;
4430   ASM_MESON_TAC[SUBSET;IN];
4431   FIRST_ASSUM MATCH_MP_TAC;
4432   ASM_MESON_TAC[REAL_EQ_IMP_LE];
4433   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4434   EXISTS_TAC `\x. T`;
4435   ASM_MESON_TAC[SUBSET;IN];
4436   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4437   EXISTS_TAC `\x. T`;
4438   ASM_MESON_TAC[SUBSET;IN];
4439   (* save *)
4440   POP_ASSUM MP_TAC THEN STRIP_TAC;
4441   POP_ASSUM (REWRITE_ALL o list);
4442   REWRITE_ALL[NOT_CONS_NIL;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4443   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
4444   COND_CASES_TAC;
4445   POP_ASSUM (REWRITE_ALL o list);
4446   REWRITE_ALL[NOT_CONS_NIL;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4447   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
4448   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`h:real`] POLY_DIFF_DOWN_LEFT5));
4449   ASM_REWRITE_TAC[real_gt;];
4450   STRIP_TAC;
4451   EXISTS_TAC `Y`;
4452   ASM_REWRITE_TAC[real_ordered_list;HD;NOT_CONS_NIL;];
4453   REWRITE_ALL[APPEND;TL;NOT_CONS_NIL;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4454   ASM_REWRITE_TAC[];
4455   REPEAT STRIP_TAC;
4456   FIRST_ASSUM MATCH_MP_TAC;
4457   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4458   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4459   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_INTERPSIGN_SUBSET);
4460   EXISTS_TAC `\x. x < h`;
4461   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE;];
4462   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4463   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4464   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_INTERPSIGN_SUBSET);
4465   EXISTS_TAC `\x. x < h`;
4466   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE;];
4467   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4468   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_INTERPSIGN_SUBSET);
4469   EXISTS_TAC `\x. x < h`;
4470   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE;];
4471   (* save *)
4472   POP_ASSUM (fun x -> (REWRITE_ALL[x] THEN ASSUME_TAC x));
4473   REWRITE_ALL[APPEND;NOT_CONS_NIL;HD;TL;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4474   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
4475   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`h:real`] POLY_DIFF_DOWN_LEFT5));
4476   ASM_REWRITE_TAC[real_gt;];
4477   STRIP_TAC;
4478   EXISTS_TAC `Y`;
4479   ASM_REWRITE_TAC[real_ordered_list;HD;NOT_CONS_NIL;];
4480   REWRITE_ALL[APPEND;TL;NOT_CONS_NIL;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4481   ASM_REWRITE_TAC[];
4482   REPEAT STRIP_TAC;
4483   FIRST_ASSUM MATCH_MP_TAC;
4484   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4485   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4486   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_INTERPSIGN_SUBSET);
4487   EXISTS_TAC `\x. x < h`;
4488   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE;];
4489   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4490   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4491   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_INTERPSIGN_SUBSET);
4492   EXISTS_TAC `\x. x < h`;
4493   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE;];
4494   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4495   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_INTERPSIGN_SUBSET);
4496   EXISTS_TAC `\x. x < h`;
4497   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE;];
4498 ]);;
4499 (* }}} *)
4500
4501 let INFIN_TL_POS_LEM = prove_by_refinement(
4502   `!pts p ps r1 sgns r2.
4503   interpmat pts
4504     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4505     (APPEND sgns [a; b; CONS Unknown (CONS Pos r2)]) ==>
4506    nonconstant p ==>
4507   ?xinf.
4508    interpmat (APPEND pts [xinf])
4509     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4510     (APPEND sgns
4511      [a; b; CONS Unknown (CONS Pos r2);
4512       CONS Pos (CONS Pos r2);
4513       CONS Pos (CONS Pos r2)])`,
4514 (* {{{ Proof *)
4515
4516 [
4517   REWRITE_TAC[interpmat;partition_line;];
4518   REPEAT STRIP_TAC;
4519   CLAIM `LENGTH (partition_line pts) = LENGTH (APPEND sgns [a; b; CONS Unknown (CONS Pos r2)])`;
4520   ASM_MESON_TAC[ALL2_LENGTH];
4521   STRIP_TAC;
4522   CLAIM `LENGTH sgns = LENGTH (partition_line pts) - 3`;
4523   REWRITE_ALL[PARTITION_LINE_LENGTH];
4524   ASM_REWRITE_TAC[LENGTH_APPEND;LENGTH;];
4525   ARITH_TAC;
4526   STRIP_TAC;
4527   CASES_ON `pts = []`;
4528   POP_ASSUM (REWRITE_ALL o list);
4529   REWRITE_ALL[LENGTH;LENGTH_APPEND;APPEND;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4530   POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN FALSE_ANTECEDENT_TAC;
4531   ARITH_TAC;
4532   (* save *)
4533   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
4534   CLAIM `pts = APPEND (BUTLAST pts) [LAST (pts:real list)]`;
4535   MATCH_MP_TAC BUTLAST_ID;
4536   ASM_MESON_TAC[];
4537   STRIP_TAC;
4538   CLAIM `ALL2
4539        (interpsigns
4540        (CONS (\x. poly p x)
4541        (CONS (\x. poly (poly_diff p) x) ps)))
4542        (partition_line (APPEND (BUTLAST pts) [LAST pts]))
4543        (APPEND sgns [a; b; CONS Unknown (CONS Pos r2)])`;
4544   ASM_MESON_TAC[];
4545   CASES_ON `BUTLAST (pts:real list) = []`;
4546   CLAIM `?w. pts = [w:real]`;
4547   ASM_MESON_TAC[BUTLAST_NIL];
4548   STRIP_TAC;
4549   POP_ASSUM (REWRITE_ALL o list);
4550   REWRITE_ALL[LAST;LENGTH;LENGTH_APPEND;APPEND;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4551   CLAIM `sgns = []`;
4552   REPEAT_N 3 (POP_ASSUM (fun x -> ALL_TAC));
4553   REWRITE_TAC[GSYM LENGTH_0];
4554   POP_ASSUM MP_TAC THEN ARITH_TAC;
4555   DISCH_THEN (REWRITE_ALL o list);
4556   REWRITE_ALL[LAST;LENGTH;LENGTH_APPEND;APPEND;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4557   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
4558   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`w:real`] POLY_DIFF_UP_RIGHT3));
4559   ASM_REWRITE_TAC[real_gt;];
4560   STRIP_TAC;
4561   EXISTS_TAC `Y`;
4562   REPEAT STRIP_TAC;
4563   ASM_REWRITE_TAC[ROL_CONS_CONS;ROL_SING];
4564   REWRITE_ALL[BUTLAST;TL;NOT_CONS_NIL;LAST;LENGTH;LENGTH_APPEND;APPEND;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4565   ASM_REWRITE_TAC[];
4566   REPEAT STRIP_TAC;
4567   ASM_MESON_TAC[REAL_EQ_IMP_LE;REAL_LT_TRANS;];
4568   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4569   EXISTS_TAC `\x. w < x`;
4570   ASM_MESON_TAC[SUBSET;IN];
4571   FIRST_ASSUM MATCH_MP_TAC;
4572   ASM_MESON_TAC[REAL_EQ_IMP_LE];
4573   ASM_MESON_TAC[REAL_LT_TRANS];
4574   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4575   EXISTS_TAC `\x. w < x`;
4576   ASM_MESON_TAC[SUBSET;IN];
4577   FIRST_ASSUM MATCH_MP_TAC;
4578   ASM_MESON_TAC[REAL_LT_IMP_LE];
4579   ASM_MESON_TAC[REAL_LT_IMP_LE;REAL_LT_TRANS;];
4580   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4581   EXISTS_TAC `\x. w < x`;
4582   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
4583   (* save *)
4584   CLAIM `LENGTH (BUTLAST (partition_line (BUTLAST pts))) = LENGTH sgns`;
4585   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;];
4586   REWRITE_ALL[PARTITION_LINE_LENGTH;LENGTH_APPEND;LENGTH;];
4587   MP_TAC (ISPEC `pts:real list` BUTLAST_LENGTH);
4588   STRIP_TAC;
4589   LABEL_ALL_TAC;
4590   PROVE_ASSUM_ANTECEDENT_TAC 0;
4591   ASM_MESON_TAC[];
4592   POP_ASSUM SUBST1_TAC;
4593   REPEAT_N 4 (POP_ASSUM (fun x -> ALL_TAC));
4594   POP_ASSUM SUBST1_TAC;
4595   ARITH_TAC;
4596   STRIP_TAC;
4597   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
4598   STRIP_TAC;
4599   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
4600   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
4601   REWRITE_ALL[BUTLAST;TL;NOT_CONS_NIL;LAST;LENGTH;LENGTH_APPEND;APPEND;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4602   REPEAT STRIP_TAC;
4603   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`LAST pts:real`] POLY_DIFF_UP_RIGHT3));
4604   ASM_REWRITE_TAC[real_gt;];
4605   STRIP_TAC;
4606   EXISTS_TAC `Y`;
4607   REPEAT STRIP_TAC;
4608   MATCH_MP_TAC ROL_INSERT_BACK_THM;
4609   ASM_REWRITE_TAC[];
4610   ONCE_ASM_REWRITE_TAC[];
4611   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
4612   REWRITE_TAC[partition_line;TL;];
4613   SIMP_TAC[NOT_CONS_NIL;LAST_APPEND];
4614   REWRITE_TAC[LAST];
4615   SIMP_TAC[BUTLAST_APPEND;NOT_CONS_NIL;];
4616   REWRITE_TAC[BUTLAST;NOT_CONS_NIL;];
4617   REWRITE_TAC[APPEND_APPEND];
4618   MATCH_MP_TAC ALL2_APPEND;
4619   ASM_REWRITE_TAC[];
4620   REWRITE_ALL[ALL2;BUTLAST;TL;NOT_CONS_NIL;LAST;LENGTH;LENGTH_APPEND;APPEND;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4621   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4622   ASM_MESON_TAC[real_gt;REAL_LT_IMP_LE];
4623   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4624   EXISTS_TAC `\x. LAST pts < x`;
4625   ASM_MESON_TAC[SUBSET;IN];
4626   FIRST_ASSUM MATCH_MP_TAC;
4627   ASM_MESON_TAC[REAL_EQ_IMP_LE];
4628   ASM_MESON_TAC[REAL_EQ_IMP_LE];
4629   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4630   EXISTS_TAC `\x. LAST pts < x`;
4631   ASM_MESON_TAC[SUBSET;IN];
4632   FIRST_ASSUM MATCH_MP_TAC;
4633   ASM_MESON_TAC[REAL_EQ_IMP_LE;REAL_LT_IMP_LE];
4634   FIRST_ASSUM MATCH_MP_TAC;
4635   ASM_MESON_TAC[REAL_EQ_IMP_LE;REAL_LT_IMP_LE;REAL_LT_TRANS;];
4636   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4637   EXISTS_TAC `\x. LAST pts < x`;
4638   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
4639 ]);;
4640
4641 (* }}} *)
4642
4643 let INFIN_HD_NEG_LEM = prove_by_refinement(
4644   `!pts p ps r1 sgns.
4645   interpmat pts
4646     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4647     (CONS (CONS Unknown (CONS Neg r1)) sgns)  ==>
4648    nonconstant p ==>
4649   ?xminf.
4650    interpmat (CONS xminf pts)
4651     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4652       (CONS (CONS Pos (CONS Neg r1))
4653       (CONS (CONS Pos (CONS Neg r1))
4654       (CONS (CONS Unknown (CONS Neg r1)) sgns)))`,
4655 (* {{{ Proof *)
4656 [
4657   REWRITE_TAC[interpmat;partition_line;];
4658   REPEAT STRIP_TAC;
4659   DISJ_CASES_TAC (ISPEC `pts:real list` list_CASES);
4660   POP_ASSUM (REWRITE_ALL o list);
4661   REWRITE_ALL[partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4662   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
4663   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`&0`] POLY_DIFF_UP_LEFT5));
4664   ASM_REWRITE_TAC[real_gt;];
4665   STRIP_TAC;
4666   EXISTS_TAC `Y`;
4667   REPEAT STRIP_TAC;
4668   FIRST_ASSUM MATCH_MP_TAC;
4669   ASM_MESON_TAC[real_gt;REAL_LT_IMP_LE];
4670   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4671   EXISTS_TAC `\x. T`;
4672   ASM_MESON_TAC[SUBSET;IN];
4673   FIRST_ASSUM MATCH_MP_TAC;
4674   ASM_MESON_TAC[REAL_EQ_IMP_LE];
4675   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4676   EXISTS_TAC `\x. T`;
4677   ASM_MESON_TAC[SUBSET;IN];
4678   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4679   EXISTS_TAC `\x. T`;
4680   ASM_MESON_TAC[SUBSET;IN];
4681   (* save *)
4682   POP_ASSUM MP_TAC THEN STRIP_TAC;
4683   POP_ASSUM (REWRITE_ALL o list);
4684   REWRITE_ALL[NOT_CONS_NIL;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4685   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
4686   COND_CASES_TAC;
4687   POP_ASSUM (REWRITE_ALL o list);
4688   REWRITE_ALL[NOT_CONS_NIL;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4689   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
4690   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`h:real`] POLY_DIFF_UP_LEFT5));
4691   ASM_REWRITE_TAC[real_gt;];
4692   STRIP_TAC;
4693   EXISTS_TAC `Y`;
4694   ASM_REWRITE_TAC[real_ordered_list;HD;NOT_CONS_NIL;];
4695   REWRITE_ALL[APPEND;TL;NOT_CONS_NIL;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4696   ASM_REWRITE_TAC[];
4697   REPEAT STRIP_TAC;
4698   FIRST_ASSUM MATCH_MP_TAC;
4699   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4700   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4701   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_INTERPSIGN_SUBSET);
4702   EXISTS_TAC `\x. x < h`;
4703   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE;];
4704   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4705   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4706   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_INTERPSIGN_SUBSET);
4707   EXISTS_TAC `\x. x < h`;
4708   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE;];
4709   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4710   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_INTERPSIGN_SUBSET);
4711   EXISTS_TAC `\x. x < h`;
4712   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE;];
4713   (* save *)
4714   POP_ASSUM (fun x -> (REWRITE_ALL[x] THEN ASSUME_TAC x));
4715   REWRITE_ALL[APPEND;NOT_CONS_NIL;HD;TL;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4716   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
4717   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`h:real`] POLY_DIFF_UP_LEFT5));
4718   ASM_REWRITE_TAC[real_gt;];
4719   STRIP_TAC;
4720   EXISTS_TAC `Y`;
4721   ASM_REWRITE_TAC[real_ordered_list;HD;NOT_CONS_NIL;];
4722   REWRITE_ALL[APPEND;TL;NOT_CONS_NIL;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4723   ASM_REWRITE_TAC[];
4724   REPEAT STRIP_TAC;
4725   FIRST_ASSUM MATCH_MP_TAC;
4726   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4727   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4728   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_INTERPSIGN_SUBSET);
4729   EXISTS_TAC `\x. x < h`;
4730   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE;];
4731   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4732   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4733   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_INTERPSIGN_SUBSET);
4734   EXISTS_TAC `\x. x < h`;
4735   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE;];
4736   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
4737   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]ALL2_INTERPSIGN_SUBSET);
4738   EXISTS_TAC `\x. x < h`;
4739   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE;];
4740 ]);;
4741 (* }}} *)
4742
4743 let INFIN_TL_NEG_LEM = prove_by_refinement(
4744   `!pts p ps r1 sgns r2.
4745   interpmat pts
4746     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4747     (APPEND sgns [a; b; CONS Unknown (CONS Neg r2)]) ==>
4748    nonconstant p ==>
4749   ?xinf.
4750    interpmat (APPEND pts [xinf])
4751     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4752     (APPEND sgns
4753      [a; b; CONS Unknown (CONS Neg r2);
4754       CONS Neg (CONS Neg r2);
4755       CONS Neg (CONS Neg r2)])`,
4756 (* {{{ Proof *)
4757 [
4758   REWRITE_TAC[interpmat;partition_line;];
4759   REPEAT STRIP_TAC;
4760   CLAIM `LENGTH (partition_line pts) = LENGTH (APPEND sgns [a; b; CONS Unknown (CONS Neg r2)])`;
4761   ASM_MESON_TAC[ALL2_LENGTH];
4762   STRIP_TAC;
4763   CLAIM `LENGTH sgns = LENGTH (partition_line pts) - 3`;
4764   REWRITE_ALL[PARTITION_LINE_LENGTH];
4765   ASM_REWRITE_TAC[LENGTH_APPEND;LENGTH;];
4766   ARITH_TAC;
4767   STRIP_TAC;
4768   CASES_ON `pts = []`;
4769   POP_ASSUM (REWRITE_ALL o list);
4770   REWRITE_ALL[LENGTH;LENGTH_APPEND;APPEND;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4771   POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN FALSE_ANTECEDENT_TAC;
4772   ARITH_TAC;
4773   (* save *)
4774   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
4775   CLAIM `pts = APPEND (BUTLAST pts) [LAST (pts:real list)]`;
4776   MATCH_MP_TAC BUTLAST_ID;
4777   ASM_MESON_TAC[];
4778   STRIP_TAC;
4779   CLAIM `ALL2
4780        (interpsigns
4781        (CONS (\x. poly p x)
4782        (CONS (\x. poly (poly_diff p) x) ps)))
4783        (partition_line (APPEND (BUTLAST pts) [LAST pts]))
4784        (APPEND sgns [a; b; CONS Unknown (CONS Neg r2)])`;
4785   ASM_MESON_TAC[];
4786   CASES_ON `BUTLAST (pts:real list) = []`;
4787   CLAIM `?w. pts = [w:real]`;
4788   ASM_MESON_TAC[BUTLAST_NIL];
4789   STRIP_TAC;
4790   POP_ASSUM (REWRITE_ALL o list);
4791   REWRITE_ALL[LAST;LENGTH;LENGTH_APPEND;APPEND;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4792   CLAIM `sgns = []`;
4793   REPEAT_N 3 (POP_ASSUM (fun x -> ALL_TAC));
4794   REWRITE_TAC[GSYM LENGTH_0];
4795   POP_ASSUM MP_TAC THEN ARITH_TAC;
4796   DISCH_THEN (REWRITE_ALL o list);
4797   REWRITE_ALL[LAST;LENGTH;LENGTH_APPEND;APPEND;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4798   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
4799   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`w:real`] POLY_DIFF_DOWN_RIGHT3));
4800   ASM_REWRITE_TAC[real_gt;];
4801   STRIP_TAC;
4802   EXISTS_TAC `Y`;
4803   REPEAT STRIP_TAC;
4804   ASM_REWRITE_TAC[ROL_CONS_CONS;ROL_SING];
4805   REWRITE_ALL[BUTLAST;TL;NOT_CONS_NIL;LAST;LENGTH;LENGTH_APPEND;APPEND;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4806   ASM_REWRITE_TAC[];
4807   REPEAT STRIP_TAC;
4808   ASM_MESON_TAC[REAL_EQ_IMP_LE;REAL_LT_TRANS;];
4809   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4810   EXISTS_TAC `\x. w < x`;
4811   ASM_MESON_TAC[SUBSET;IN];
4812   ASM_MESON_TAC[REAL_EQ_IMP_LE;REAL_LT_TRANS;];
4813   ASM_MESON_TAC[REAL_EQ_IMP_LE];
4814   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4815   EXISTS_TAC `\x. w < x`;
4816   ASM_MESON_TAC[SUBSET;IN];
4817   FIRST_ASSUM MATCH_MP_TAC;
4818   ASM_MESON_TAC[REAL_LT_IMP_LE];
4819   ASM_MESON_TAC[REAL_LT_IMP_LE;REAL_LT_TRANS;];
4820   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4821   EXISTS_TAC `\x. w < x`;
4822   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
4823   (* save *)
4824   CLAIM `LENGTH (BUTLAST (partition_line (BUTLAST pts))) = LENGTH sgns`;
4825   ASM_SIMP_TAC[BUTLAST_LENGTH;PARTITION_LINE_NOT_NIL;];
4826   REWRITE_ALL[PARTITION_LINE_LENGTH;LENGTH_APPEND;LENGTH;];
4827   MP_TAC (ISPEC `pts:real list` BUTLAST_LENGTH);
4828   STRIP_TAC;
4829   LABEL_ALL_TAC;
4830   PROVE_ASSUM_ANTECEDENT_TAC 0;
4831   ASM_MESON_TAC[];
4832   POP_ASSUM SUBST1_TAC;
4833   REPEAT_N 4 (POP_ASSUM (fun x -> ALL_TAC));
4834   POP_ASSUM SUBST1_TAC;
4835   ARITH_TAC;
4836   STRIP_TAC;
4837   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
4838   STRIP_TAC;
4839   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
4840   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP x y)));
4841   REWRITE_ALL[BUTLAST;TL;NOT_CONS_NIL;LAST;LENGTH;LENGTH_APPEND;APPEND;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4842   REPEAT STRIP_TAC;
4843   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`LAST pts:real`] POLY_DIFF_DOWN_RIGHT3));
4844   ASM_REWRITE_TAC[real_gt;];
4845   STRIP_TAC;
4846   EXISTS_TAC `Y`;
4847   REPEAT STRIP_TAC;
4848   MATCH_MP_TAC ROL_INSERT_BACK_THM;
4849   ASM_REWRITE_TAC[];
4850   ONCE_ASM_REWRITE_TAC[];
4851   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
4852   REWRITE_TAC[partition_line;TL;];
4853   SIMP_TAC[NOT_CONS_NIL;LAST_APPEND];
4854   REWRITE_TAC[LAST];
4855   SIMP_TAC[BUTLAST_APPEND;NOT_CONS_NIL;];
4856   REWRITE_TAC[BUTLAST;NOT_CONS_NIL;];
4857   REWRITE_TAC[APPEND_APPEND];
4858   MATCH_MP_TAC ALL2_APPEND;
4859   ASM_REWRITE_TAC[];
4860   REWRITE_ALL[ALL2;BUTLAST;TL;NOT_CONS_NIL;LAST;LENGTH;LENGTH_APPEND;APPEND;partition_line;ALL2;interpsigns;interpsign;real_gt;ROL_SING];
4861   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[];
4862   ASM_MESON_TAC[real_gt;REAL_LT_IMP_LE];
4863   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4864   EXISTS_TAC `\x. LAST pts < x`;
4865   ASM_MESON_TAC[SUBSET;IN];
4866   FIRST_ASSUM MATCH_MP_TAC;
4867   ASM_MESON_TAC[REAL_EQ_IMP_LE];
4868   ASM_MESON_TAC[REAL_EQ_IMP_LE];
4869   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4870   EXISTS_TAC `\x. LAST pts < x`;
4871   ASM_MESON_TAC[SUBSET;IN];
4872   FIRST_ASSUM MATCH_MP_TAC;
4873   ASM_MESON_TAC[REAL_EQ_IMP_LE;REAL_LT_IMP_LE];
4874   FIRST_ASSUM MATCH_MP_TAC;
4875   ASM_MESON_TAC[REAL_EQ_IMP_LE;REAL_LT_IMP_LE;REAL_LT_TRANS;];
4876   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
4877   EXISTS_TAC `\x. LAST pts < x`;
4878   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
4879 ]);;
4880 (* }}} *)
4881
4882 let INFIN_POS_POS = prove_by_refinement(
4883   `!pts p ps r1 sgns r2.
4884   interpmat pts
4885     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4886     (APPEND (CONS (CONS Unknown (CONS Pos r1)) sgns)
4887      [a; b; CONS Unknown (CONS Pos r2)]) ==>
4888    nonconstant p ==>
4889   ?xminf xinf.
4890    interpmat (APPEND (CONS xminf pts) [xinf])
4891     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4892     (APPEND
4893       (CONS (CONS Neg (CONS Pos r1))
4894       (CONS (CONS Neg (CONS Pos r1))
4895       (CONS (CONS Unknown (CONS Pos r1)) sgns)))
4896      [a; b; CONS Unknown (CONS Pos r2);
4897       CONS Pos (CONS Pos r2);
4898       CONS Pos (CONS Pos r2)])`,
4899 (* {{{ Proof *)
4900 [
4901   REPEAT STRIP_TAC;
4902   REWRITE_ASSUMS[APPEND];
4903   FIRST_ASSUM (MP_TAC o MATCH_MP INFIN_HD_POS_LEM);
4904   ASM_REWRITE_TAC[];
4905   STRIP_TAC;
4906   EXISTS_TAC `xminf`;
4907   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]INFIN_TL_POS_LEM);
4908   ASM_REWRITE_TAC[APPEND;];
4909 ]);;
4910 (* }}} *)
4911
4912 let INFIN_POS_NEG = prove_by_refinement(
4913   `!pts p ps r1 sgns r2.
4914   interpmat pts
4915     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4916     (APPEND (CONS (CONS Unknown (CONS Pos r1)) sgns)
4917      [a; b; CONS Unknown (CONS Neg r2)]) ==>
4918    nonconstant p ==>
4919   ?xminf xinf.
4920    interpmat (APPEND (CONS xminf pts) [xinf])
4921     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4922     (APPEND
4923       (CONS (CONS Neg (CONS Pos r1))
4924       (CONS (CONS Neg (CONS Pos r1))
4925       (CONS (CONS Unknown (CONS Pos r1)) sgns)))
4926      [a; b; CONS Unknown (CONS Neg r2);
4927       CONS Neg (CONS Neg r2);
4928       CONS Neg (CONS Neg r2)])`,
4929 (* {{{ Proof *)
4930 [
4931   REPEAT STRIP_TAC;
4932   REWRITE_ASSUMS[APPEND];
4933   FIRST_ASSUM (MP_TAC o MATCH_MP INFIN_HD_POS_LEM);
4934   ASM_REWRITE_TAC[];
4935   STRIP_TAC;
4936   EXISTS_TAC `xminf`;
4937   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]INFIN_TL_NEG_LEM);
4938   ASM_REWRITE_TAC[APPEND;];
4939 ]);;
4940 (* }}} *)
4941
4942 let INFIN_NEG_POS = prove_by_refinement(
4943   `!pts p ps r1 sgns r2.
4944   interpmat pts
4945     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4946     (APPEND (CONS (CONS Unknown (CONS Neg r1)) sgns)
4947      [a; b; CONS Unknown (CONS Pos r2)]) ==>
4948    nonconstant p ==>
4949   ?xminf xinf.
4950    interpmat (APPEND (CONS xminf pts) [xinf])
4951     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4952     (APPEND
4953       (CONS (CONS Pos (CONS Neg r1))
4954       (CONS (CONS Pos (CONS Neg r1))
4955       (CONS (CONS Unknown (CONS Neg r1)) sgns)))
4956      [a; b; CONS Unknown (CONS Pos r2);
4957       CONS Pos (CONS Pos r2);
4958       CONS Pos (CONS Pos r2)])`,
4959 (* {{{ Proof *)
4960 [
4961   REPEAT STRIP_TAC;
4962   REWRITE_ASSUMS[APPEND];
4963   FIRST_ASSUM (MP_TAC o MATCH_MP INFIN_HD_NEG_LEM);
4964   ASM_REWRITE_TAC[];
4965   STRIP_TAC;
4966   EXISTS_TAC `xminf`;
4967   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]INFIN_TL_POS_LEM);
4968   ASM_REWRITE_TAC[APPEND;];
4969 ]);;
4970 (* }}} *)
4971
4972 let INFIN_NEG_NEG = prove_by_refinement(
4973   `!pts p ps r1 sgns r2.
4974   interpmat pts
4975     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4976     (APPEND (CONS (CONS Unknown (CONS Neg r1)) sgns)
4977      [a; b; CONS Unknown (CONS Neg r2)]) ==>
4978    nonconstant p ==>
4979   ?xminf xinf.
4980    interpmat (APPEND (CONS xminf pts) [xinf])
4981     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
4982     (APPEND
4983       (CONS (CONS Pos (CONS Neg r1))
4984       (CONS (CONS Pos (CONS Neg r1))
4985       (CONS (CONS Unknown (CONS Neg r1)) sgns)))
4986      [a; b; CONS Unknown (CONS Neg r2);
4987       CONS Neg (CONS Neg r2);
4988       CONS Neg (CONS Neg r2)])`,
4989 (* {{{ Proof *)
4990 [
4991   REPEAT STRIP_TAC;
4992   REWRITE_ASSUMS[APPEND];
4993   FIRST_ASSUM (MP_TAC o MATCH_MP INFIN_HD_NEG_LEM);
4994   ASM_REWRITE_TAC[];
4995   STRIP_TAC;
4996   EXISTS_TAC `xminf`;
4997   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM]INFIN_TL_NEG_LEM);
4998   ASM_REWRITE_TAC[APPEND;];
4999 ]);;
5000 (* }}} *)
5001
5002 let INFIN_NIL_POS = prove_by_refinement(
5003   `!p ps r1.
5004   interpmat []
5005     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
5006     [CONS Unknown (CONS Pos r1)]  ==>
5007    nonconstant p ==>
5008   ?xminf xinf.
5009    interpmat [xminf; xinf]
5010     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
5011       [CONS Neg (CONS Pos r1);
5012        CONS Neg (CONS Pos r1);
5013        CONS Unknown (CONS Pos r1);
5014        CONS Pos (CONS Pos r1);
5015        CONS Pos (CONS Pos r1)]`,
5016 (* {{{ Proof *)
5017 [
5018   REWRITE_TAC[real_gt;interpmat;partition_line;ROL_NIL;ALL2;interpsigns;interpsign];
5019   REPEAT STRIP_TAC;
5020   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`&0`] POLY_DIFF_UP_RIGHT3));
5021   ASM_REWRITE_TAC[real_gt];
5022   STRIP_TAC;
5023   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`&0`] POLY_DIFF_DOWN_LEFT5));
5024   ASM_REWRITE_TAC[real_gt];
5025   STRIP_TAC;
5026   EXISTS_TAC `Y'`;
5027   EXISTS_TAC `Y`;
5028   ASM_REWRITE_TAC[real_gt;NOT_CONS_NIL;HD;TL;APPEND;ALL2;interpsigns;interpsign];
5029   REWRITE_TAC[ROL_CONS_CONS;ROL_SING];
5030   REPEAT STRIP_TAC;
5031   ASM_MESON_TAC[REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
5032   ASM_MESON_TAC[REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
5033   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
5034   EXISTS_TAC `\x. T`;
5035   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
5036   ASM_MESON_TAC[REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
5037   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
5038   EXISTS_TAC `\x. T`;
5039   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
5040   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
5041   EXISTS_TAC `\x. T`;
5042   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
5043   ASM_MESON_TAC[REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
5044   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
5045   EXISTS_TAC `\x. T`;
5046   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
5047   ASM_MESON_TAC[REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
5048   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
5049   EXISTS_TAC `\x. T`;
5050   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
5051 ]);;
5052 (* }}} *)
5053
5054 let INFIN_NIL_NEG = prove_by_refinement(
5055   `!p ps r1.
5056   interpmat []
5057     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
5058     [CONS Unknown (CONS Neg r1)]  ==>
5059    nonconstant p ==>
5060   ?xminf xinf.
5061    interpmat [xminf; xinf]
5062     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
5063       [CONS Pos (CONS Neg r1);
5064        CONS Pos (CONS Neg r1);
5065        CONS Unknown (CONS Neg r1);
5066        CONS Neg (CONS Neg r1);
5067        CONS Neg (CONS Neg r1)]`,
5068 (* {{{ Proof *)
5069 [
5070   REWRITE_TAC[real_gt;interpmat;partition_line;ROL_NIL;ALL2;interpsigns;interpsign];
5071   REPEAT STRIP_TAC;
5072   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`&0`] POLY_DIFF_DOWN_RIGHT3));
5073   ASM_REWRITE_TAC[real_gt];
5074   STRIP_TAC;
5075   FIRST_ASSUM (MP_TAC o MATCH_MP (ISPECL [`p:real list`;`poly_diff p`;`&0`] POLY_DIFF_UP_LEFT5));
5076   ASM_REWRITE_TAC[real_gt];
5077   STRIP_TAC;
5078   EXISTS_TAC `Y'`;
5079   EXISTS_TAC `Y`;
5080   ASM_REWRITE_TAC[real_gt;NOT_CONS_NIL;HD;TL;APPEND;ALL2;interpsigns;interpsign];
5081   REWRITE_TAC[ROL_CONS_CONS;ROL_SING];
5082   REPEAT STRIP_TAC;
5083   ASM_MESON_TAC[REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
5084   ASM_MESON_TAC[REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
5085   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
5086   EXISTS_TAC `\x. T`;
5087   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
5088   ASM_MESON_TAC[REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
5089   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
5090   EXISTS_TAC `\x. T`;
5091   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
5092   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
5093   EXISTS_TAC `\x. T`;
5094   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
5095   ASM_MESON_TAC[REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
5096   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
5097   EXISTS_TAC `\x. T`;
5098   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
5099   ASM_MESON_TAC[REAL_LT_TRANS;REAL_LT_IMP_LE;REAL_EQ_IMP_LE];
5100   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] ALL2_INTERPSIGN_SUBSET);
5101   EXISTS_TAC `\x. T`;
5102   ASM_MESON_TAC[SUBSET;IN;REAL_LT_TRANS;];
5103 ]);;
5104 (* }}} *)
5105
5106 let INFIN_SING_POS_POS = prove_by_refinement(
5107   `!p ps r1 x s2 r2 r3.
5108   interpmat [x]
5109     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
5110     [CONS Unknown (CONS Pos r1);CONS s2 r2;CONS Unknown (CONS Pos r3)]  ==>
5111    nonconstant p ==>
5112   ?xminf xinf.
5113    interpmat [xminf; x; xinf]
5114     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
5115       [CONS Neg (CONS Pos r1);
5116        CONS Neg (CONS Pos r1);
5117        CONS Unknown (CONS Pos r1);
5118        CONS s2 r2;
5119        CONS Unknown (CONS Pos r3);
5120        CONS Pos (CONS Pos r3);
5121        CONS Pos (CONS Pos r3)]`,
5122 (* {{{ Proof *)
5123 [
5124   REPEAT STRIP_TAC;
5125   ONCE_REWRITE_ASSUMS[prove(`[x; y; z] = APPEND [] [x; y; z]`,REWRITE_TAC[APPEND])];
5126   FIRST_ASSUM (MP_TAC o MATCH_MP INFIN_TL_POS_LEM);
5127   ASM_REWRITE_TAC[];
5128   STRIP_TAC;
5129   MATCH_MP_TAC (prove(`(?y x. P x y) ==> (?x y. P x y)`,MESON_TAC[]));
5130   EXISTS_TAC `xinf`;
5131   REWRITE_ALL[APPEND];
5132   FIRST_ASSUM (MP_TAC o MATCH_MP INFIN_HD_POS_LEM);
5133   ASM_REWRITE_TAC[];
5134 ]);;
5135 (* }}} *)
5136
5137 let INFIN_SING_POS_NEG = prove_by_refinement(
5138   `!p ps r1 x s2 r2 r3.
5139   interpmat [x]
5140     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
5141     [CONS Unknown (CONS Pos r1);CONS s2 r2;CONS Unknown (CONS Neg r3)]  ==>
5142    nonconstant p ==>
5143   ?xminf xinf.
5144    interpmat [xminf; x; xinf]
5145     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
5146       [CONS Neg (CONS Pos r1);
5147        CONS Neg (CONS Pos r1);
5148        CONS Unknown (CONS Pos r1);
5149        CONS s2 r2;
5150        CONS Unknown (CONS Neg r3);
5151        CONS Neg (CONS Neg r3);
5152        CONS Neg (CONS Neg r3)]`,
5153 (* {{{ Proof *)
5154 [
5155   REPEAT STRIP_TAC;
5156   ONCE_REWRITE_ASSUMS[prove(`[x; y; z] = APPEND [] [x; y; z]`,REWRITE_TAC[APPEND])];
5157   FIRST_ASSUM (MP_TAC o MATCH_MP INFIN_TL_NEG_LEM);
5158   ASM_REWRITE_TAC[];
5159   STRIP_TAC;
5160   MATCH_MP_TAC (prove(`(?y x. P x y) ==> (?x y. P x y)`,MESON_TAC[]));
5161   EXISTS_TAC `xinf`;
5162   REWRITE_ALL[APPEND];
5163   FIRST_ASSUM (MP_TAC o MATCH_MP INFIN_HD_POS_LEM);
5164   ASM_REWRITE_TAC[];
5165 ]);;
5166 (* }}} *)
5167
5168 let INFIN_SING_NEG_POS = prove_by_refinement(
5169   `!p ps r1 x s2 r2 r3.
5170   interpmat [x]
5171     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
5172     [CONS Unknown (CONS Neg r1);CONS s2 r2;CONS Unknown (CONS Pos r3)]  ==>
5173    nonconstant p ==>
5174   ?xminf xinf.
5175    interpmat [xminf; x; xinf]
5176     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
5177       [CONS Pos (CONS Neg r1);
5178        CONS Pos (CONS Neg r1);
5179        CONS Unknown (CONS Neg r1);
5180        CONS s2 r2;
5181        CONS Unknown (CONS Pos r3);
5182        CONS Pos (CONS Pos r3);
5183        CONS Pos (CONS Pos r3)]`,
5184 (* {{{ Proof *)
5185 [
5186   REPEAT STRIP_TAC;
5187   ONCE_REWRITE_ASSUMS[prove(`[x; y; z] = APPEND [] [x; y; z]`,REWRITE_TAC[APPEND])];
5188   FIRST_ASSUM (MP_TAC o MATCH_MP INFIN_TL_POS_LEM);
5189   ASM_REWRITE_TAC[];
5190   STRIP_TAC;
5191   MATCH_MP_TAC (prove(`(?y x. P x y) ==> (?x y. P x y)`,MESON_TAC[]));
5192   EXISTS_TAC `xinf`;
5193   REWRITE_ALL[APPEND];
5194   FIRST_ASSUM (MP_TAC o MATCH_MP INFIN_HD_NEG_LEM);
5195   ASM_REWRITE_TAC[];
5196 ]);;
5197 (* }}} *)
5198
5199 let INFIN_SING_NEG_NEG = prove_by_refinement(
5200   `!p ps r1 x s2 r2 r3.
5201   interpmat [x]
5202     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
5203     [CONS Unknown (CONS Neg r1);CONS s2 r2;CONS Unknown (CONS Neg r3)]  ==>
5204    nonconstant p ==>
5205   ?xminf xinf.
5206    interpmat [xminf; x; xinf]
5207     (CONS (\x. poly p x) (CONS (\x. poly (poly_diff p) x) ps))
5208       [CONS Pos (CONS Neg r1);
5209        CONS Pos (CONS Neg r1);
5210        CONS Unknown (CONS Neg r1);
5211        CONS s2 r2;
5212        CONS Unknown (CONS Neg r3);
5213        CONS Neg (CONS Neg r3);
5214        CONS Neg (CONS Neg r3)]`,
5215 (* {{{ Proof *)
5216 [
5217   REPEAT STRIP_TAC;
5218   ONCE_REWRITE_ASSUMS[prove(`[x; y; z] = APPEND [] [x; y; z]`,REWRITE_TAC[APPEND])];
5219   FIRST_ASSUM (MP_TAC o MATCH_MP INFIN_TL_NEG_LEM);
5220   ASM_REWRITE_TAC[];
5221   STRIP_TAC;
5222   MATCH_MP_TAC (prove(`(?y x. P x y) ==> (?x y. P x y)`,MESON_TAC[]));
5223   EXISTS_TAC `xinf`;
5224   REWRITE_ALL[APPEND];
5225   FIRST_ASSUM (MP_TAC o MATCH_MP INFIN_HD_NEG_LEM);
5226   ASM_REWRITE_TAC[];
5227 ]);;
5228 (* }}} *)
5229
5230 let EL_SUC = prove_by_refinement(
5231   `!i h t. EL (SUC i) (CONS h t) = EL i t`,
5232 (* {{{ Proof *)
5233 [
5234   REWRITE_TAC[EL;TL];
5235 ]);;
5236 (* }}} *)
5237
5238 let EL_PRE = prove_by_refinement(
5239   `!i h t. ~(i = 0) ==> (EL i (CONS h t) = EL (PRE i) t)`,
5240 (* {{{ Proof *)
5241 [
5242   INDUCT_TAC;
5243   REWRITE_TAC[];
5244   REPEAT STRIP_TAC;
5245   REWRITE_TAC[EL;TL;PRE];
5246 ]);;
5247 (* }}} *)
5248
5249 let ALL2_EL_LT_LEM = prove_by_refinement(
5250   `!k P l1 l2 n.
5251     (k = LENGTH l1) /\ ALL2 P l1 l2 /\ n < k ==>
5252        P (EL n l1) (EL n l2)`,
5253 (* {{{ Proof *)
5254 [
5255   INDUCT_TAC;
5256   REPEAT STRIP_TAC;
5257   POP_ASSUM MP_TAC THEN ARITH_TAC;
5258   REPEAT STRIP_TAC;
5259   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_LENGTH);
5260   STRIP_TAC;
5261   CLAIM `~(l1 = [])`;
5262   REWRITE_TAC[GSYM LENGTH_0];
5263   REPEAT_N 3 (POP_ASSUM (fun x -> ALL_TAC));
5264   POP_ASSUM MP_TAC THEN ARITH_TAC;
5265   REWRITE_TAC[NOT_NIL;];
5266   STRIP_TAC;
5267   CLAIM `~(l2 = [])`;
5268   REWRITE_TAC[GSYM LENGTH_0];
5269   POP_ASSUM (fun x -> ALL_TAC);
5270   POP_ASSUM (SUBST1_TAC o GSYM);
5271   REPEAT_N 2 (POP_ASSUM (fun x -> ALL_TAC));
5272   POP_ASSUM MP_TAC THEN ARITH_TAC;
5273   REWRITE_TAC[NOT_NIL;];
5274   STRIP_TAC;
5275   POP_ASSUM (REWRITE_ALL o list);
5276   POP_ASSUM (REWRITE_ALL o list);
5277   REWRITE_ASSUMS[LENGTH;SUC_INJ;ALL2;];
5278   REPEAT_N 3 (POP_ASSUM MP_TAC);
5279   POP_ASSUM (REWRITE_ALL o list);
5280   REPEAT STRIP_TAC;
5281   (* save *)
5282   DISJ_CASES_TAC (ISPEC `n:num` num_CASES);
5283   POP_ASSUM (REWRITE_ALL o list);
5284   ASM_REWRITE_TAC[EL;HD];
5285   POP_ASSUM MP_TAC THEN STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
5286   REWRITE_TAC[EL;TL;];
5287   REWRITE_ASSUMS[LENGTH;SUC_INJ;ALL2;LT_SUC];
5288   FIRST_ASSUM MATCH_MP_TAC;
5289   ASM_REWRITE_TAC[];
5290 ]);;
5291 (* }}} *)
5292
5293 let ALL2_EL_LT = prove_by_refinement(
5294   `!P l1 l2 n. ALL2 P l1 l2 /\ n < LENGTH l1 ==> P (EL n l1) (EL n l2)`,
5295 (* {{{ Proof *)
5296 [
5297   MESON_TAC[ALL2_EL_LT_LEM];
5298 ]);;
5299 (* }}} *)
5300
5301 let ALL2_EL_LEM = prove_by_refinement(
5302   `!k P (l1:A list) (l2:B list).  (k = LENGTH l1) /\ (k = LENGTH l2) /\
5303     ~(?i. i < LENGTH l1 /\ ~(P (EL i l1) (EL i l2))) ==> ALL2 P l1 l2`,
5304 (* {{{ Proof *)
5305 [
5306   INDUCT_TAC;
5307   REPEAT STRIP_TAC;
5308   EVERY_ASSUM (MP_TAC o GSYM);
5309   ASM_MESON_TAC[LENGTH_0;ALL2];
5310   REPEAT STRIP_TAC;
5311   CLAIM `~(l1 = [])`;
5312   REWRITE_TAC[GSYM LENGTH_0];
5313   REPEAT_N 2 (POP_ASSUM (fun x -> ALL_TAC));
5314   POP_ASSUM MP_TAC THEN ARITH_TAC;
5315   REWRITE_TAC[NOT_NIL;];
5316   STRIP_TAC;
5317   CLAIM `~(l2 = [])`;
5318   REWRITE_TAC[GSYM LENGTH_0];
5319   REPEAT_N 2 (POP_ASSUM (fun x -> ALL_TAC));
5320   POP_ASSUM MP_TAC THEN ARITH_TAC;
5321   REWRITE_TAC[NOT_NIL;];
5322   STRIP_TAC;
5323   POP_ASSUM (REWRITE_ALL o list);
5324   POP_ASSUM (REWRITE_ALL o list);
5325   REWRITE_ALL[LENGTH;SUC_INJ;ALL2;];
5326   STRIP_TAC;
5327   ASM_MESON_TAC[LT_0;EL;HD;];
5328   (* save *)
5329   FIRST_ASSUM MATCH_MP_TAC;
5330   ASM_REWRITE_TAC[];
5331   STRIP_TAC;
5332   ASM_MESON_TAC[];
5333   REPEAT STRIP_TAC;
5334   CLAIM `SUC i < SUC (LENGTH t)`;
5335   POP_ASSUM (fun x -> ALL_TAC);
5336   POP_ASSUM MP_TAC THEN ARITH_TAC;
5337   STRIP_TAC;
5338   REPEAT_N 3 (POP_ASSUM MP_TAC);
5339   REWRITE_ASSUMS[NOT_EXISTS_THM];
5340   POP_ASSUM (ASSUME_TAC o ISPEC `SUC i`);
5341   REWRITE_ALL[LT_SUC];
5342   REWRITE_ALL[EL;TL;];
5343   ASM_MESON_TAC[];
5344 ]);;
5345 (* }}} *)
5346
5347 let ALL2_EL = prove_by_refinement(
5348   `!P (l1:A list) (l2:B list). ALL2 P l1 l2 <=> (LENGTH l1 = LENGTH l2) /\
5349     ~(?i. i < LENGTH l1 /\ ~(P (EL i l1) (EL i l2)))`,
5350 (* {{{ Proof *)
5351 [
5352   REPEAT STRIP_TAC;
5353   EQ_TAC;
5354   REPEAT STRIP_TAC;
5355   MATCH_MP_TAC ALL2_LENGTH;
5356   ASM_MESON_TAC[];
5357   ASM_MESON_TAC[ALL2_EL_LT];
5358   (* save *)
5359   ASM_MESON_TAC[ALL2_EL_LEM];
5360 ]);;
5361 (* }}} *)
5362
5363 let EL_MAP = prove_by_refinement(
5364   `!f l n. n < LENGTH l ==> (EL n (MAP f l) = f (EL n l))`,
5365 (* {{{ Proof *)
5366 [
5367   STRIP_TAC;
5368   LIST_INDUCT_TAC;
5369   REWRITE_TAC[LENGTH];
5370   ARITH_TAC;
5371   REWRITE_TAC[MAP;LENGTH;];
5372   INDUCT_TAC;
5373   REWRITE_TAC[MAP;LENGTH;EL;HD;];
5374   REWRITE_ALL[LT_SUC;TL;MAP;LENGTH;EL;HD;];
5375   ASM_REWRITE_TAC[];
5376 ]);;
5377 (* }}} *)
5378
5379 let REMOVE_HD_COL = prove_by_refinement(
5380   `!p ps sgns pts.
5381     interpmat pts (CONS p ps) sgns ==> interpmat pts ps (MAP TL sgns)`,
5382 (* {{{ Proof *)
5383 [
5384   REWRITE_TAC[interpmat;ALL2_EL];
5385   REPEAT STRIP_TAC;
5386   ASM_REWRITE_TAC[];
5387   REWRITE_ALL[ALL2_EL];
5388   ASM_MESON_TAC[LENGTH_MAP];
5389   REWRITE_ASSUMS[NOT_EXISTS_THM];
5390   REPEAT_N 2 (POP_ASSUM MP_TAC);
5391   POP_ASSUM (MP_TAC o ISPEC `i:num`);
5392   REWRITE_TAC[DE_MORGAN_THM];
5393   REPEAT STRIP_TAC;
5394   ASM_MESON_TAC[];
5395   REWRITE_ALL[interpsigns];
5396   CLAIM `i < LENGTH sgns`;
5397   ASM_MESON_TAC[];
5398   STRIP_TAC;
5399   ASM_SIMP_TAC[EL_MAP];
5400   REWRITE_ALL[interpsigns];
5401   CLAIM `~(EL i sgns = [])`;
5402   REWRITE_TAC[GSYM LENGTH_0];
5403   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_LENGTH);
5404   REWRITE_TAC[LENGTH];
5405   ARITH_TAC;
5406   (* save *)
5407   DISCH_THEN (MP_TAC o MATCH_MP HD_TL);
5408   DISCH_THEN (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN SUBST1_TAC x);
5409   REWRITE_TAC[ALL2;TL;];
5410   REPEAT STRIP_TAC;
5411   FIRST_ASSUM MATCH_ACCEPT_TAC;
5412 ]);;
5413 (* }}} *)
5414
5415 let REMOVE_COL1 = prove_by_refinement(
5416   `!sgns pts p1 p2 ps.
5417    interpmat pts (CONS p1 (CONS p2 ps)) sgns ==>
5418    interpmat pts (CONS p1 ps) (MAP (\x. CONS (HD x) (TL (TL x))) sgns)`,
5419 (* {{{ Proof *)
5420 [
5421   REWRITE_TAC[interpmat;ALL2_EL];
5422   REPEAT STRIP_TAC;
5423   ASM_REWRITE_TAC[];
5424   ASM_MESON_TAC[LENGTH_MAP];
5425   REWRITE_ASSUMS[NOT_EXISTS_THM];
5426   REPEAT_N 2 (POP_ASSUM MP_TAC);
5427   POP_ASSUM (MP_TAC o ISPEC `i:num`);
5428   REWRITE_TAC[DE_MORGAN_THM];
5429   REPEAT STRIP_TAC;
5430   ASM_MESON_TAC[];
5431   REWRITE_ALL[interpsigns];
5432   CLAIM `i < LENGTH sgns`;
5433   ASM_MESON_TAC[];
5434   STRIP_TAC;
5435   ASM_SIMP_TAC[EL_MAP];
5436   REWRITE_ALL[interpsigns];
5437   CLAIM `~(EL i sgns = [])`;
5438   REWRITE_TAC[GSYM LENGTH_0];
5439   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_LENGTH);
5440   REWRITE_TAC[LENGTH];
5441   ARITH_TAC;
5442   (* save *)
5443   DISCH_THEN (MP_TAC o MATCH_MP HD_TL);
5444   DISCH_THEN (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN SUBST1_TAC x);
5445   REWRITE_TAC[ALL2;TL;];
5446   REPEAT STRIP_TAC;
5447   ASM_MESON_TAC[HD;];
5448   CLAIM `~(TL (EL i sgns) = [])`;
5449   REWRITE_TAC[GSYM LENGTH_0];
5450   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_LENGTH);
5451   REWRITE_TAC[LENGTH];
5452   ARITH_TAC;
5453   (* save *)
5454   DISCH_THEN (MP_TAC o MATCH_MP HD_TL);
5455   DISCH_THEN (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN SUBST1_TAC x);
5456   REWRITE_TAC[ALL2;TL;];
5457   REPEAT STRIP_TAC;
5458   ASM_MESON_TAC[HD;];
5459 ]);;
5460 (* }}} *)
5461
5462 let ALL_EL = prove_by_refinement(
5463   `!P l. ALL P l <=> !n. n < LENGTH l ==> P (EL n l)`,
5464 (* {{{ Proof *)
5465 [
5466   STRIP_TAC;
5467   LIST_INDUCT_TAC;
5468   REWRITE_TAC[ALL;LENGTH];
5469   ARITH_TAC;
5470   ASM_REWRITE_TAC[ALL];
5471   POP_ASSUM (fun x -> ALL_TAC);
5472   EQ_TAC;
5473   REPEAT STRIP_TAC;
5474   CASES_ON `n = 0`;
5475   POP_ASSUM (REWRITE_ALL o list);
5476   ASM_REWRITE_TAC[EL;HD;];
5477   REWRITE_ASSUMS[LENGTH];
5478   CLAIM `PRE n < LENGTH t`;
5479   POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
5480   DISCH_THEN (fun x -> FIRST_ASSUM (MP_TAC o C MATCH_MP x));
5481   ASM_MESON_TAC[EL_PRE];
5482   (* save *)
5483   REPEAT STRIP_TAC;
5484   REWRITE_ASSUMS[LENGTH];
5485   FIRST_ASSUM (MP_TAC o ISPEC `0`);
5486   REWRITE_TAC[EL;HD;];
5487   MESON_TAC[LT_0];
5488   REWRITE_ASSUMS[LENGTH];
5489   CLAIM `SUC n < SUC (LENGTH t)`;
5490   ASM_MESON_TAC[LT_SUC];
5491   DISCH_THEN (fun x -> FIRST_ASSUM (MP_TAC o C MATCH_MP x));
5492   REWRITE_TAC[EL_SUC];
5493 ]);;
5494 (* }}} *)
5495
5496 let INTERPMAT_POL_LENGTH_LEM = prove_by_refinement(
5497   `!k pols l1 l2. ALL2 (interpsigns pols) l1 l2 /\ (k = LENGTH l2) ==>
5498     ALL (\x. LENGTH x = LENGTH pols) l2`,
5499 (* {{{ Proof *)
5500 [
5501   INDUCT_TAC;
5502   REPEAT STRIP_TAC;
5503   CLAIM `l2 = []`;
5504   ASM_MESON_TAC[NOT_CONS_NIL;LENGTH_0;ALL2_LENGTH];
5505   DISCH_THEN (REWRITE_ALL o list);
5506   REWRITE_TAC[ALL];
5507   REPEAT STRIP_TAC;
5508   CLAIM `~(l2 = [])`;
5509   ASM_MESON_TAC[NOT_CONS_NIL;LENGTH_0;ALL2_LENGTH;NOT_SUC];
5510   REWRITE_TAC[NOT_NIL];
5511   STRIP_TAC THEN (POP_ASSUM (REWRITE_ALL o list));
5512   CLAIM `~(l1 = [])`;
5513   ASM_MESON_TAC[NOT_CONS_NIL;LENGTH_0;ALL2_LENGTH;NOT_SUC];
5514   REWRITE_TAC[NOT_NIL];
5515   STRIP_TAC THEN (POP_ASSUM (REWRITE_ALL o list));
5516   REWRITE_ALL[ALL2;ALL;interpsigns];
5517   STRIP_TAC;
5518   ASM_MESON_TAC[ALL2_LENGTH];
5519   FIRST_ASSUM MATCH_MP_TAC;
5520   EXISTS_TAC `t'`;
5521   ASM_REWRITE_TAC[];
5522   REWRITE_ALL[LENGTH];
5523   POP_ASSUM MP_TAC THEN ARITH_TAC;
5524 ]);;
5525 (* }}} *)
5526
5527 let INTERPMAT_POL_LENGTH = prove_by_refinement(
5528   `!pts pols sgns. interpmat pts pols sgns ==>
5529     ALL (\x. LENGTH x = LENGTH pols) sgns`,
5530 (* {{{ Proof *)
5531 [
5532   REWRITE_TAC[interpmat];
5533   MESON_TAC[INTERPMAT_POL_LENGTH_LEM];
5534 ]);;
5535 (* }}} *)
5536
5537 let RESTRIP_TAC = REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;;
5538
5539 let ALL2_BUTLAST = prove_by_refinement(
5540   `!P l1 l2. ALL2 P l1 l2 ==> ALL2 P (BUTLAST l1) (BUTLAST l2)`,
5541 (* {{{ Proof *)
5542
5543 [
5544   STRIP_TAC;
5545   REPEAT LIST_INDUCT_TAC;
5546   REWRITE_TAC[ALL2;BUTLAST];
5547   REWRITE_TAC[ALL2;BUTLAST];
5548   REWRITE_TAC[ALL2;BUTLAST];
5549   POP_ASSUM (fun x -> ALL_TAC);
5550   REWRITE_TAC[ALL2;BUTLAST;];
5551   REPEAT COND_CASES_TAC THEN ASM_REWRITE_TAC[NOT_CONS_NIL;ALL2;];
5552   REWRITE_ASSUMS[NOT_NIL];
5553   POP_ASSUM MP_TAC THEN STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
5554   REWRITE_TAC[ALL2];
5555   REWRITE_ASSUMS[NOT_NIL];
5556   RESTRIP_TAC;
5557   ASM_MESON_TAC[ALL2];
5558   REPEAT STRIP_TAC;
5559   ASM_REWRITE_TAC[];
5560   FIRST_ASSUM MATCH_MP_TAC;
5561   FIRST_ASSUM MATCH_ACCEPT_TAC;
5562 ]);;
5563
5564 (* }}} *)
5565
5566 let REMOVE_LAST = prove_by_refinement(
5567   `!pts pols sgns .
5568      interpmat pts pols sgns ==>
5569      interpmat pts (BUTLAST pols) (MAP BUTLAST sgns)`,
5570 (* {{{ Proof *)
5571 [
5572   REWRITE_TAC[interpmat;ALL2_EL];
5573   REPEAT STRIP_TAC;
5574   ASM_REWRITE_TAC[];
5575   ASM_MESON_TAC[LENGTH_MAP];
5576   REWRITE_ASSUMS[NOT_EXISTS_THM];
5577   REPEAT_N 2 (POP_ASSUM MP_TAC);
5578   POP_ASSUM (MP_TAC o ISPEC `i:num`);
5579   REWRITE_TAC[DE_MORGAN_THM];
5580   REPEAT STRIP_TAC;
5581   ASM_MESON_TAC[];
5582   REWRITE_ALL[interpsigns];
5583   CLAIM `i < LENGTH sgns`;
5584   ASM_MESON_TAC[];
5585   STRIP_TAC;
5586   (* save *)
5587   ASM_SIMP_TAC[EL_MAP];
5588   ASM_MESON_TAC[ALL2_BUTLAST];
5589 ]);;
5590 (* }}} *)
5591
5592 let INSERTAT = new_recursive_definition num_RECURSION
5593   `(INSERTAT 0 x l = CONS x l) /\
5594    (INSERTAT (SUC n) x l = CONS (HD l) (INSERTAT n x (TL l)))`;;
5595
5596 let MAP2_EL_LEM = prove_by_refinement(
5597   `!f k l1 l2 i. (LENGTH l1 = LENGTH l2) ==> i < LENGTH l1 ==>
5598     (k = LENGTH l1) ==>
5599      (EL i (MAP2 f l1 l2) = f (EL i l1) (EL i l2))`,
5600 (* {{{ Proof *)
5601 [
5602   STRIP_TAC;
5603   INDUCT_TAC;
5604   REPEAT STRIP_TAC;
5605   POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
5606   REPEAT STRIP_TAC;
5607   CLAIM `~(l1 = [])`;
5608   ASM_MESON_TAC[LENGTH_0;NOT_SUC];
5609   CLAIM `~(l2 = [])`;
5610   ASM_MESON_TAC[LENGTH_0;NOT_SUC];
5611   REWRITE_TAC[NOT_NIL];
5612   REPEAT STRIP_TAC;
5613   POP_ASSUM (REWRITE_ALL o list);
5614   POP_ASSUM (REWRITE_ALL o list);
5615   REWRITE_TAC[MAP2];
5616   REWRITE_ALL[LENGTH;SUC_INJ];
5617   DISJ_CASES_TAC (ISPEC `i:num` num_CASES);
5618   POP_ASSUM (REWRITE_ALL o list);
5619   REWRITE_TAC[EL;HD;];
5620   POP_ASSUM MP_TAC THEN STRIP_TAC;
5621   POP_ASSUM (REWRITE_ALL o list);
5622   REWRITE_TAC[EL;TL;];
5623   REWRITE_ASSUMS[LT_SUC];
5624   ASM_MESON_TAC[];
5625 ]);;
5626 (* }}} *)
5627
5628 let MAP2_EL = prove_by_refinement(
5629   `!f i l1 l2. (LENGTH l1 = LENGTH l2) ==> i < LENGTH l1 ==>
5630      (EL i (MAP2 f l1 l2) = f (EL i l1) (EL i l2))`,
5631 (* {{{ Proof *)
5632 [
5633   MESON_TAC[MAP2_EL_LEM];
5634 ]);;
5635 (* }}} *)
5636
5637 let INSERTAT_LENGTH = prove_by_refinement(
5638   `!x n l. n <= LENGTH l ==> (LENGTH (INSERTAT n x l) = SUC (LENGTH l))`,
5639 (* {{{ Proof *)
5640
5641 [
5642   STRIP_TAC;
5643   INDUCT_TAC;
5644   REWRITE_TAC[INSERTAT;LENGTH;];
5645   REWRITE_TAC[INSERTAT;LENGTH;];
5646   REPEAT STRIP_TAC;
5647   AP_TERM_TAC;
5648   CLAIM `~(l = [])`;
5649   ASM_MESON_TAC[LENGTH_0;NOT_LE;ARITH_RULE `~(SUC n <= 0)`];
5650   REWRITE_TAC[NOT_NIL];
5651   STRIP_TAC;
5652   POP_ASSUM (REWRITE_ALL o list);
5653   REWRITE_ALL[LENGTH;TL;LE_SUC];
5654   ASM_MESON_TAC[];
5655 ]);;
5656
5657 (* }}} *)
5658
5659 let NUM_CASES_TAC = TYPE_TAC (fun x -> DISJ_CASES_TAC (ISPEC x num_CASES));;
5660
5661 let INSERTAT_TL = prove_by_refinement(
5662   `!x n l. n < LENGTH l ==> (INSERTAT n x (TL l) = TL (INSERTAT (SUC n) x l))`,
5663 (* {{{ Proof *)
5664 [
5665   STRIP_TAC;
5666   INDUCT_TAC;
5667   REPEAT STRIP_TAC;
5668   REWRITE_TAC[INSERTAT;TL;];
5669   REPEAT STRIP_TAC;
5670   CLAIM `n < LENGTH l \/ (n = LENGTH l)`;
5671   POP_ASSUM MP_TAC THEN ARITH_TAC;
5672   STRIP_TAC;
5673   REWRITE_TAC[INSERTAT;HD;TL;];
5674   REWRITE_TAC[INSERTAT;HD;TL;];
5675 ]);;
5676 (* }}} *)
5677
5678 let INSERTAT_EL = prove_by_refinement(
5679   `!n (x:A) i l. n <= LENGTH l ==> i <= LENGTH l ==>
5680    ((i < n ==> (EL i (INSERTAT n x l) = EL i l)) /\
5681    ((i = n) ==> (EL i (INSERTAT n x l) = x)) /\
5682    (i > n ==> (EL i (INSERTAT n x l) = EL (PRE i) l)))`,
5683 (* {{{ Proof *)
5684 [
5685   INDUCT_TAC;
5686   REPEAT STRIP_TAC;
5687   POP_ASSUM MP_TAC THEN ARITH_TAC;
5688   ASM_REWRITE_TAC[INSERTAT;EL;HD;];
5689   ASM_REWRITE_TAC[INSERTAT;EL;HD;];
5690   DISJ_CASES_TAC (ISPEC `i:num` num_CASES);
5691   EVERY_ASSUM MP_TAC THEN ARITH_TAC;
5692   POP_ASSUM MP_TAC THEN STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
5693   REWRITE_TAC[EL;TL;PRE];
5694   (* save *)
5695   REPEAT_N 5 STRIP_TAC;
5696   CLAIM `~(l = [])`;
5697   ASM_MESON_TAC[LENGTH_0;NOT_LE;ARITH_RULE `~(SUC n <= 0)`];
5698   STRIP_TAC;
5699   CLAIM `n <= LENGTH (TL l)`;
5700   ASM_SIMP_TAC[LENGTH_TL];
5701   POP_ASSUM (fun x -> ALL_TAC);
5702   POP_ASSUM (fun x -> ALL_TAC);
5703   POP_ASSUM MP_TAC THEN ARITH_TAC;
5704   STRIP_TAC;
5705   (* save *)
5706   REPEAT STRIP_TAC;
5707   REWRITE_TAC[INSERTAT];
5708   NUM_CASES_TAC `i`;
5709   POP_ASSUM (REWRITE_ALL o list);
5710   REWRITE_TAC[EL;HD;];
5711   POP_ASSUM MP_TAC THEN STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
5712   REWRITE_TAC[EL;TL;];
5713   CLAIM `n' <= LENGTH (TL l)`;
5714   REWRITE_ASSUMS[LT_SUC];
5715   ASM_MESON_TAC[LTE_TRANS;LT_TRANS;LET_TRANS;LT_IMP_LE];
5716   STRIP_TAC;
5717   REWRITE_ASSUMS[LT_SUC];
5718   ASM_MESON_TAC[];
5719   (* save *)
5720   POP_ASSUM (REWRITE_ALL o list);
5721   REWRITE_TAC[EL;INSERTAT;TL;];
5722   ASM_MESON_TAC[];
5723   REWRITE_TAC[INSERTAT];
5724   NUM_CASES_TAC `i`;
5725   POP_ASSUM (REWRITE_ALL o list);
5726   REWRITE_TAC[EL;HD;PRE];
5727   (* save *)
5728   POP_ASSUM MP_TAC THEN STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
5729   REWRITE_TAC[EL;TL;PRE];
5730   CLAIM `n' <= LENGTH (TL l)`;
5731   ASM_SIMP_TAC[LENGTH_TL];
5732   REPEAT_N 3 (POP_ASSUM (fun x -> ALL_TAC));
5733   POP_ASSUM MP_TAC THEN ARITH_TAC;
5734   STRIP_TAC;
5735   REWRITE_ASSUMS[GT;LT_SUC];
5736   FIRST_X_ASSUM (MP_TAC o ISPECL[`x:A`;`n':num`;`TL l:A list`]);
5737   ASM_REWRITE_TAC[];
5738   REPEAT STRIP_TAC;
5739   ASM_REWRITE_TAC[];
5740   NUM_CASES_TAC `n'`;
5741   ASM_MESON_TAC[ARITH_RULE `x < y ==> ~(y = 0)`];
5742   POP_ASSUM MP_TAC THEN STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
5743   REWRITE_TAC[PRE;EL];
5744 ]);;
5745 (* }}} *)
5746
5747 let USE_X_ASSUM lab ttac =
5748     USE_THEN lab (fun th -> UNDISCH_THEN (concl th) ttac);;
5749
5750 let MATINSERT_THM = prove_by_refinement(
5751   `!pts p pols n psgns sgns.
5752      interpmat pts pols sgns ==>
5753      ALL2 (\x y. interpsign x p y) (partition_line pts) psgns ==>
5754      n <= LENGTH pols ==>
5755       interpmat pts (INSERTAT n p pols) (MAP2 (INSERTAT n) psgns sgns)`,
5756 (* {{{ Proof *)
5757 [
5758   REWRITE_TAC[interpmat;ALL2_EL;NOT_EXISTS_THM;DE_MORGAN_THM;];
5759   REPEAT STRIP_TAC;
5760   ASM_REWRITE_TAC[];
5761   ASM_REWRITE_TAC[];
5762   CLAIM `LENGTH (psgns:sign list) = LENGTH sgns`;
5763   ASM_MESON_TAC[LENGTH_MAP2];
5764   ASM_MESON_TAC[LENGTH_MAP2];
5765   DISJ_LCASE;
5766   REWRITE_ASSUMS[];
5767   (* save *)
5768   REWRITE_ALL[interpsigns];
5769   CLAIM `LENGTH psgns = LENGTH sgns`;
5770   ASM_MESON_TAC[];
5771   STRIP_TAC;
5772   CLAIM `i < LENGTH psgns`;
5773   ASM_MESON_TAC[];
5774   STRIP_TAC;
5775   ASM_SIMP_TAC[MAP2_EL];
5776   (* save *)
5777   REWRITE_TAC[ALL2_EL];
5778   REWRITE_TAC[NOT_EXISTS_THM;DE_MORGAN_THM];
5779   REPEAT STRIP_TAC;
5780   ASM_SIMP_TAC[INSERTAT_LENGTH];
5781   CLAIM `LENGTH (EL i (sgns:(sign list) list)) = LENGTH pols`;
5782   ASM_MESON_TAC[ALL2_LENGTH];
5783   STRIP_TAC;
5784   ASM_SIMP_TAC[INSERTAT_LENGTH];
5785   (* save *)
5786   DISJ_LCASE;
5787   REWRITE_ASSUMS[];
5788   MP_TAC (ARITH_RULE `i' < n \/ (i' = n) \/ i' > (n:num)`);
5789   REPEAT STRIP_TAC;
5790   CLAIM `LENGTH (EL i sgns) = LENGTH pols`;
5791   ASM_MESON_TAC[ALL2_LENGTH];
5792   STRIP_TAC;
5793   CLAIM `n <= LENGTH (EL i sgns)`;
5794   ASM_MESON_TAC[];
5795   STRIP_TAC;
5796   CLAIM `i' <= LENGTH (EL i sgns)`;
5797   ASM_MESON_TAC[LTE_TRANS;LET_TRANS;LT_TRANS;LT_IMP_LE];
5798   STRIP_TAC;
5799   ASM_SIMP_TAC[INSERTAT_EL];
5800   CLAIM `i' <= LENGTH pols`;
5801   ASM_MESON_TAC[LTE_TRANS;LET_TRANS;LT_TRANS;LT_IMP_LE];
5802   STRIP_TAC;
5803   ASM_SIMP_TAC[INSERTAT_EL];
5804   REPEAT_N 12 (POP_ASSUM MP_TAC);
5805   POP_ASSUM (MP_TAC o ISPEC `i:num`);
5806   REPEAT STRIP_TAC;
5807   ASM_MESON_TAC[];
5808   LABEL_ALL_TAC;
5809   USE_THEN "Z-12" MP_TAC;
5810   REWRITE_TAC[ALL2_EL];
5811   REWRITE_TAC[NOT_EXISTS_THM;DE_MORGAN_THM];
5812   STRIP_TAC;
5813   POP_ASSUM (MP_TAC o ISPEC `i':num`);
5814   POP_ASSUM (fun x -> ALL_TAC);
5815   ASM_REWRITE_TAC[];
5816   POP_ASSUM (fun x -> ALL_TAC);
5817   STRIP_TAC;
5818   ASM_MESON_TAC[ARITH_RULE `x <= y /\ z < x ==> z < (y:num)`];
5819   (* save *)
5820   POP_ASSUM (REWRITE_ALL o list);
5821   CLAIM `LENGTH (EL i sgns) = LENGTH pols`;
5822   ASM_MESON_TAC[ALL2_LENGTH];
5823   STRIP_TAC;
5824   CLAIM `n <= LENGTH (EL i sgns)`;
5825   ASM_MESON_TAC[];
5826   STRIP_TAC;
5827   ASM_SIMP_TAC[INSERTAT_EL];
5828   ASM_MESON_TAC[ALL2_EL];
5829   (* save *)
5830   CLAIM `LENGTH (EL i sgns) = LENGTH pols`;
5831   ASM_MESON_TAC[ALL2_LENGTH];
5832   STRIP_TAC;
5833   CLAIM `n <= LENGTH (EL i sgns)`;
5834   ASM_MESON_TAC[];
5835   STRIP_TAC;
5836   CLAIM `i' <= LENGTH (EL i sgns)`;
5837   ASM_REWRITE_TAC[];
5838   LABEL_ALL_TAC;
5839   USE_THEN "Z-7" (MP_TAC o MATCH_MP INSERTAT_LENGTH);
5840   TYPE_TAC (fun x -> DISCH_THEN (MP_TAC o ISPEC x)) `p`;
5841   USE_THEN "Z-3" MP_TAC THEN ARITH_TAC;
5842   STRIP_TAC;
5843   CLAIM `i' <= LENGTH pols`;
5844   ASM_MESON_TAC[];
5845   STRIP_TAC;
5846   ASM_SIMP_TAC[INSERTAT_EL];
5847   LABEL_ALL_TAC;
5848   (* save *)
5849   USE_X_ASSUM "Z-12" (MP_TAC o ISPEC `i:num`);
5850   ASM_REWRITE_TAC[];
5851   REWRITE_TAC[ALL2_EL];
5852   ASM_REWRITE_TAC[NOT_EXISTS_THM;DE_MORGAN_THM;];
5853   DISCH_THEN (MP_TAC o ISPEC `PRE i':num`);
5854   STRIP_TAC;
5855   CLAIM `~(i' = 0)`;
5856   USE_THEN "Z-4" MP_TAC THEN ARITH_TAC;
5857   POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
5858 ]);;
5859 (* }}} *)
5860
5861 let INTERP_CONST_POS = prove_by_refinement(
5862   `!c l. c > &0 ==>
5863     ALL2 (\x y. interpsign x (\x. c) y) l (REPLICATE (LENGTH l) Pos)`,
5864 (* {{{ Proof *)
5865 [
5866   REWRITE_TAC[real_gt;];
5867   STRIP_TAC;
5868   LIST_INDUCT_TAC;
5869   REWRITE_TAC[REPLICATE;LENGTH;ALL2;];
5870   DISCH_THEN (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
5871   REWRITE_TAC[REPLICATE;LENGTH;ALL2;interpsign;real_gt;];
5872   ASM_MESON_TAC[REPLICATE;LENGTH;ALL2;interpsign;real_gt;];
5873 ]);;
5874 (* }}} *)
5875
5876 let INTERP_CONST_NEG = prove_by_refinement(
5877   `!c l. c < &0 ==>
5878     ALL2 (\x y. interpsign x (\x. c) y) l (REPLICATE (LENGTH l) Neg)`,
5879 (* {{{ Proof *)
5880 [
5881   STRIP_TAC;
5882   LIST_INDUCT_TAC;
5883   REWRITE_TAC[REPLICATE;LENGTH;ALL2;];
5884   DISCH_THEN (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
5885   REWRITE_TAC[REPLICATE;LENGTH;ALL2;interpsign;real_gt;];
5886   ASM_MESON_TAC[];
5887 ]);;
5888 (* }}} *)
5889
5890 let INTERP_CONST_ZERO = prove_by_refinement(
5891   `!c l. (c = &0) ==>
5892     ALL2 (\x y. interpsign x (\x. c) y) l (REPLICATE (LENGTH l) Zero)`,
5893 (* {{{ Proof *)
5894 [
5895   STRIP_TAC;
5896   LIST_INDUCT_TAC;
5897   REWRITE_TAC[REPLICATE;LENGTH;ALL2;];
5898   DISCH_THEN (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
5899   REWRITE_TAC[REPLICATE;LENGTH;ALL2;interpsign;real_gt;];
5900   ASM_REWRITE_TAC[];
5901   (* XXX MESON FAILS HERE *)
5902 ]);;
5903 (* }}} *)
5904
5905 let QUANT_CONV conv = RAND_CONV(ABS_CONV conv);;
5906
5907 let rec PATH_CONV2 s cnv =
5908   match s with
5909     [] -> cnv
5910   | "l"::t -> RATOR_CONV (PATH_CONV2 t cnv)
5911   | "r"::t -> RAND_CONV (PATH_CONV2 t cnv)
5912   | "q"::t -> QUANT_CONV (PATH_CONV2 t cnv)
5913   | "a"::t -> ABS_CONV (PATH_CONV2 t cnv)
5914   | _ -> failwith "PATH_CONV2: unknown direction";;
5915
5916 let EL_REPLICATE = prove_by_refinement(
5917   `!n x i. i < n ==> (EL i (REPLICATE n x) = x)`,
5918 (* {{{ Proof *)
5919 [
5920   INDUCT_TAC;
5921   ARITH_TAC;
5922   REPEAT STRIP_TAC;
5923   REWRITE_TAC[REPLICATE];
5924   NUM_CASES_TAC `i`;
5925   POP_ASSUM (REWRITE_ALL o list);
5926   REWRITE_TAC[EL;HD;];
5927   POP_ASSUM MP_TAC THEN STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
5928   REWRITE_TAC[EL;TL;];
5929   ASM_MESON_TAC[LT_SUC];
5930 ]);;
5931 (* }}} *)
5932
5933 let ALL2_UNKNOWN = prove_by_refinement(
5934   `!p pts. ALL2 (\x y. interpsign x p y) (partition_line pts)
5935     (REPLICATE (LENGTH (partition_line pts)) Unknown)`,
5936 (* {{{ Proof *)
5937 [
5938   REWRITE_TAC[ALL2_EL];
5939   REWRITE_TAC[NOT_EXISTS_THM;DE_MORGAN_THM];
5940   REPEAT STRIP_TAC;
5941   ASM_MESON_TAC[LENGTH_REPLICATE];
5942   DISJ_LCASE;
5943   REWRITE_ASSUMS[];
5944   ASM_SIMP_TAC[EL_REPLICATE];
5945   REWRITE_TAC[interpsign];
5946 ]);;
5947 (* }}} *)
5948
5949 let MATINSERT_THM2 = prove_by_refinement(
5950   `!pts p pols n psgns sgns.
5951     ALL2 (\x y. interpsign x p y) (partition_line pts) psgns ==>
5952     n <= LENGTH pols ==>
5953     interpmat pts pols sgns ==>
5954      interpmat pts (INSERTAT n p pols) (MAP2 (INSERTAT n) psgns sgns)`,
5955 (* {{{ Proof *)
5956 [
5957   MESON_TAC[MATINSERT_THM]
5958 ]);;
5959 (* }}} *)
5960
5961 let FUN_EQ_TAC = MATCH_EQ_MP_TAC (GSYM FUN_EQ_THM);;
5962
5963 let INSERTAT_0 = prove_by_refinement(
5964   `INSERTAT 0 = CONS`,
5965 (* {{{ Proof *)
5966 [
5967   FUN_EQ_TAC;
5968   STRIP_TAC;
5969   FUN_EQ_TAC;
5970   REWRITE_TAC[INSERTAT];
5971 ]);;
5972 (* }}} *)
5973
5974 let INFERPSIGN_MATINSERT_THM = prove_by_refinement(
5975   `!pts p pols sgns.
5976     interpmat pts pols sgns ==>
5977      interpmat pts (CONS p pols)
5978       (MAP2 CONS
5979         (REPLICATE (2 * LENGTH pts + 1) Unknown) sgns)`,
5980 (* {{{ Proof *)
5981 [
5982   REPEAT STRIP_TAC;
5983   TYPE_TACL (fun l -> MP_TAC (ISPECL l MATINSERT_THM))
5984    [`pts`;`p`;`pols`;`0`;`REPLICATE (LENGTH (partition_line pts)) Unknown`;`sgns`];
5985   ASM_REWRITE_TAC[ALL2_UNKNOWN;ARITH_RULE `0 <= x`;INSERTAT;PARTITION_LINE_LENGTH];
5986   MESON_TAC[INSERTAT_0];
5987 ]);;
5988 (* }}} *)
5989
5990 let INFERPSIGN_POS = prove_by_refinement(
5991   `!p ps q qs r rs s x pts1 pts2  s1 s2 s3 rest sgns.
5992   interpmat (APPEND pts1 (CONS x pts2))
5993     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
5994     (APPEND sgns
5995       (CONS (APPEND (CONS Unknown s1)
5996         (APPEND (CONS Zero s2) (CONS Pos s3))) rest)) ==>
5997   (LENGTH ps = LENGTH s1) ==>
5998   (LENGTH qs = LENGTH s2) ==>
5999   ODD (LENGTH sgns) ==>
6000   (LENGTH sgns = 2 * LENGTH pts1 + 1) ==>
6001   (!x. p x = s x * q x + r x) ==>
6002   interpmat (APPEND pts1 (CONS x pts2))
6003     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
6004     (APPEND sgns
6005       (CONS (APPEND (CONS Pos s1)
6006         (APPEND (CONS Zero s2) (CONS Pos s3))) rest))`,
6007 (* {{{ Proof *)
6008
6009 [
6010   REWRITE_TAC[interpmat];
6011   REPEAT STRIP_TAC;
6012   FIRST_ASSUM MATCH_ACCEPT_TAC;
6013   CASES_ON `pts1 = []`;
6014   POP_ASSUM (REWRITE_ALL o list);
6015   REWRITE_ALL[APPEND;partition_line;];
6016   COND_CASES_TAC;
6017   CLAIM `?k. sgns = [k]`;
6018   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
6019   REWRITE_ALL[LENGTH];
6020   POP_ASSUM (fun x -> ALL_TAC);
6021   POP_ASSUM (fun x -> ALL_TAC);
6022   POP_ASSUM MP_TAC THEN ARITH_TAC;
6023   STRIP_TAC;
6024   POP_ASSUM (REWRITE_ALL o list);
6025   POP_ASSUM (REWRITE_ALL o list);
6026   REWRITE_ALL[APPEND;partition_line;ALL2;];
6027   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
6028   ASM_REWRITE_TAC[];
6029   REWRITE_ALL[interpsigns;interpsign;ALL2;];
6030   ASM_REWRITE_TAC[];
6031   REPEAT STRIP_TAC;
6032   REPEAT_N 5 (POP_ASSUM MP_TAC);
6033   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6034   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6035   REWRITE_TAC[ALL2;interpsign;];
6036   REPEAT STRIP_TAC;
6037   ASM_REWRITE_TAC[];
6038   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6039   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6040   REWRITE_TAC[ALL2;interpsign;];
6041   REPEAT STRIP_TAC;
6042   ASM_REWRITE_TAC[];
6043   CLAIM `q x = &0`;
6044   ASM_MESON_TAC[];
6045   DISCH_THEN (REWRITE_ALL o list);
6046   POP_ASSUM (fun x -> ALL_TAC);
6047   REWRITE_TAC[REAL_MUL_RZERO;REAL_ADD_LID;];
6048   FIRST_ASSUM MATCH_MP_TAC;
6049   REWRITE_TAC[];
6050   ASM_REWRITE_TAC[];
6051   (* save *)
6052   CLAIM `?k. sgns = [k]`;
6053   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
6054   REWRITE_ALL[LENGTH];
6055   POP_ASSUM (fun x -> ALL_TAC);
6056   POP_ASSUM (fun x -> ALL_TAC);
6057   POP_ASSUM MP_TAC THEN ARITH_TAC;
6058   STRIP_TAC;
6059   POP_ASSUM (REWRITE_ALL o list);
6060   POP_ASSUM (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
6061   REWRITE_ALL[APPEND;partition_line;ALL2;];
6062   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
6063   ASM_REWRITE_TAC[];
6064   REWRITE_ALL[interpsigns;interpsign;ALL2;];
6065   ASM_REWRITE_TAC[];
6066   REPEAT STRIP_TAC;
6067   REPEAT_N 6 (POP_ASSUM MP_TAC);
6068   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6069   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6070   REWRITE_TAC[ALL2;interpsign;];
6071   REPEAT STRIP_TAC;
6072   ASM_REWRITE_TAC[];
6073   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6074   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6075   REWRITE_TAC[ALL2;interpsign;];
6076   REPEAT STRIP_TAC;
6077   ASM_REWRITE_TAC[];
6078   CLAIM `q x = &0`;
6079   ASM_MESON_TAC[];
6080   DISCH_THEN (REWRITE_ALL o list);
6081   POP_ASSUM (fun x -> ALL_TAC);
6082   REWRITE_TAC[REAL_MUL_RZERO;REAL_ADD_LID;];
6083   FIRST_ASSUM MATCH_MP_TAC;
6084   REWRITE_TAC[];
6085   ASM_REWRITE_TAC[];
6086   (* save *)
6087   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
6088   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
6089   REPEAT STRIP_TAC;
6090   CLAIM `(APPEND (BUTLAST (partition_line pts1))
6091      (CONS (\x'. LAST pts1 < x' /\ x' < x)
6092      (TL (partition_line (CONS x pts2))))) =
6093      (APPEND
6094       (APPEND (BUTLAST (partition_line pts1))
6095       [\x'. LAST pts1 < x' /\ x' < x])
6096      (TL (partition_line (CONS x pts2))))`;
6097   ASM_MESON_TAC[APPEND_CONS];
6098   DISCH_THEN (REWRITE_ALL o list);
6099   REPEAT (POP_ASSUM MP_TAC);
6100   REWRITE_ALL[partition_line];
6101   COND_CASES_TAC;
6102   POP_ASSUM (REWRITE_ALL o list);
6103   REPEAT STRIP_TAC;
6104   REWRITE_ALL[TL;];
6105   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
6106       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
6107   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
6108   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
6109   ARITH_TAC;
6110   STRIP_TAC;
6111   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6112   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6113   REPEAT STRIP_TAC;
6114   MATCH_MP_TAC ALL2_APPEND;
6115   ASM_REWRITE_TAC[];
6116   (* save *)
6117   REPEAT_N 6 (POP_ASSUM MP_TAC);
6118   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
6119   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
6120   ASM_REWRITE_TAC[];
6121   REPEAT STRIP_TAC;
6122   RESTRIP_TAC;
6123   POP_ASSUM (REWRITE_ALL o list);
6124   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6125   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6126   REWRITE_TAC[ALL2;interpsign;];
6127   REPEAT STRIP_TAC;
6128   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6129   REPEAT_N 4 (POP_ASSUM MP_TAC);
6130   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
6131   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6132   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6133   REWRITE_TAC[ALL2;interpsign;];
6134   REPEAT STRIP_TAC;
6135   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6136   ASM_REWRITE_TAC[];
6137   CLAIM `q x = &0`;
6138   ASM_MESON_TAC[];
6139   DISCH_THEN (REWRITE_ALL o list);
6140   POP_ASSUM (fun x -> ALL_TAC);
6141   REWRITE_TAC[REAL_MUL_RZERO;REAL_ADD_LID;];
6142   FIRST_ASSUM MATCH_MP_TAC;
6143   REWRITE_TAC[];
6144   (* save *)
6145   REPEAT STRIP_TAC;
6146   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
6147       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
6148   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
6149   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
6150   ARITH_TAC;
6151   STRIP_TAC;
6152   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6153   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6154   REPEAT STRIP_TAC;
6155   MATCH_MP_TAC ALL2_APPEND;
6156   ASM_REWRITE_TAC[];
6157   (* save *)
6158   REWRITE_ALL[TL;ALL2;interpsign;interpsigns;APPEND];
6159   ASM_REWRITE_TAC[];
6160   REPEAT STRIP_TAC;
6161   REPEAT_N 7 (POP_ASSUM MP_TAC);
6162   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
6163   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
6164   ASM_REWRITE_TAC[];
6165   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6166   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6167   REWRITE_TAC[ALL2;interpsign;];
6168   REPEAT STRIP_TAC;
6169   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6170   REPEAT_N 4 (POP_ASSUM MP_TAC);
6171   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
6172   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6173   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6174   REWRITE_TAC[ALL2;interpsign;];
6175   REPEAT STRIP_TAC;
6176   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6177   ASM_REWRITE_TAC[];
6178   CLAIM `q x = &0`;
6179   ASM_MESON_TAC[];
6180   DISCH_THEN (REWRITE_ALL o list);
6181   POP_ASSUM (fun x -> ALL_TAC);
6182   REWRITE_TAC[REAL_MUL_RZERO;REAL_ADD_LID;];
6183   FIRST_ASSUM MATCH_MP_TAC;
6184   REWRITE_TAC[];
6185 ]);;
6186
6187 (* }}} *)
6188
6189 let INFERPSIGN_NEG = prove_by_refinement(
6190   `!p ps q qs r rs s x pts1 pts2  s1 s2 s3 rest sgns.
6191   interpmat (APPEND pts1 (CONS x pts2))
6192     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
6193     (APPEND sgns
6194       (CONS (APPEND (CONS Unknown s1)
6195         (APPEND (CONS Zero s2) (CONS Neg s3))) rest)) ==>
6196   (LENGTH ps = LENGTH s1) ==>
6197   (LENGTH qs = LENGTH s2) ==>
6198   ODD (LENGTH sgns) ==>
6199   (LENGTH sgns = 2 * LENGTH pts1 + 1) ==>
6200   (!x. p x = s x * q x + r x) ==>
6201   interpmat (APPEND pts1 (CONS x pts2))
6202     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
6203     (APPEND sgns
6204       (CONS (APPEND (CONS Neg s1)
6205         (APPEND (CONS Zero s2) (CONS Neg s3))) rest))`,
6206 (* {{{ Proof *)
6207 [
6208   REWRITE_TAC[interpmat];
6209   REPEAT STRIP_TAC;
6210   FIRST_ASSUM MATCH_ACCEPT_TAC;
6211   CASES_ON `pts1 = []`;
6212   POP_ASSUM (REWRITE_ALL o list);
6213   REWRITE_ALL[APPEND;partition_line;];
6214   COND_CASES_TAC;
6215   CLAIM `?k. sgns = [k]`;
6216   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
6217   REWRITE_ALL[LENGTH];
6218   POP_ASSUM (fun x -> ALL_TAC);
6219   POP_ASSUM (fun x -> ALL_TAC);
6220   POP_ASSUM MP_TAC THEN ARITH_TAC;
6221   STRIP_TAC;
6222   POP_ASSUM (REWRITE_ALL o list);
6223   POP_ASSUM (REWRITE_ALL o list);
6224   REWRITE_ALL[APPEND;partition_line;ALL2;];
6225   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
6226   ASM_REWRITE_TAC[];
6227   REWRITE_ALL[interpsigns;interpsign;ALL2;];
6228   ASM_REWRITE_TAC[];
6229   REPEAT STRIP_TAC;
6230   REPEAT_N 5 (POP_ASSUM MP_TAC);
6231   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6232   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6233   REWRITE_TAC[ALL2;interpsign;];
6234   REPEAT STRIP_TAC;
6235   ASM_REWRITE_TAC[];
6236   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6237   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6238   REWRITE_TAC[ALL2;interpsign;];
6239   REPEAT STRIP_TAC;
6240   ASM_REWRITE_TAC[];
6241   CLAIM `q x = &0`;
6242   ASM_MESON_TAC[];
6243   DISCH_THEN (REWRITE_ALL o list);
6244   POP_ASSUM (fun x -> ALL_TAC);
6245   REWRITE_TAC[REAL_MUL_RZERO;REAL_ADD_LID;];
6246   FIRST_ASSUM MATCH_MP_TAC;
6247   REWRITE_TAC[];
6248   ASM_REWRITE_TAC[];
6249   (* save *)
6250   CLAIM `?k. sgns = [k]`;
6251   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
6252   REWRITE_ALL[LENGTH];
6253   POP_ASSUM (fun x -> ALL_TAC);
6254   POP_ASSUM (fun x -> ALL_TAC);
6255   POP_ASSUM MP_TAC THEN ARITH_TAC;
6256   STRIP_TAC;
6257   POP_ASSUM (REWRITE_ALL o list);
6258   POP_ASSUM (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
6259   REWRITE_ALL[APPEND;partition_line;ALL2;];
6260   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
6261   ASM_REWRITE_TAC[];
6262   REWRITE_ALL[interpsigns;interpsign;ALL2;];
6263   ASM_REWRITE_TAC[];
6264   REPEAT STRIP_TAC;
6265   REPEAT_N 6 (POP_ASSUM MP_TAC);
6266   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6267   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6268   REWRITE_TAC[ALL2;interpsign;];
6269   REPEAT STRIP_TAC;
6270   ASM_REWRITE_TAC[];
6271   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6272   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6273   REWRITE_TAC[ALL2;interpsign;];
6274   REPEAT STRIP_TAC;
6275   ASM_REWRITE_TAC[];
6276   CLAIM `q x = &0`;
6277   ASM_MESON_TAC[];
6278   DISCH_THEN (REWRITE_ALL o list);
6279   POP_ASSUM (fun x -> ALL_TAC);
6280   REWRITE_TAC[REAL_MUL_RZERO;REAL_ADD_LID;];
6281   FIRST_ASSUM MATCH_MP_TAC;
6282   REWRITE_TAC[];
6283   ASM_REWRITE_TAC[];
6284   (* save *)
6285   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
6286   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
6287   REPEAT STRIP_TAC;
6288   CLAIM `(APPEND (BUTLAST (partition_line pts1))
6289      (CONS (\x'. LAST pts1 < x' /\ x' < x)
6290      (TL (partition_line (CONS x pts2))))) =
6291      (APPEND
6292       (APPEND (BUTLAST (partition_line pts1))
6293       [\x'. LAST pts1 < x' /\ x' < x])
6294      (TL (partition_line (CONS x pts2))))`;
6295   ASM_MESON_TAC[APPEND_CONS];
6296   DISCH_THEN (REWRITE_ALL o list);
6297   REPEAT (POP_ASSUM MP_TAC);
6298   REWRITE_ALL[partition_line];
6299   COND_CASES_TAC;
6300   POP_ASSUM (REWRITE_ALL o list);
6301   REPEAT STRIP_TAC;
6302   REWRITE_ALL[TL;];
6303   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
6304       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
6305   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
6306   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
6307   ARITH_TAC;
6308   STRIP_TAC;
6309   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6310   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6311   REPEAT STRIP_TAC;
6312   MATCH_MP_TAC ALL2_APPEND;
6313   ASM_REWRITE_TAC[];
6314   (* save *)
6315   REPEAT_N 6 (POP_ASSUM MP_TAC);
6316   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
6317   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
6318   ASM_REWRITE_TAC[];
6319   REPEAT STRIP_TAC;
6320   RESTRIP_TAC;
6321   POP_ASSUM (REWRITE_ALL o list);
6322   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6323   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6324   REWRITE_TAC[ALL2;interpsign;];
6325   REPEAT STRIP_TAC;
6326   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6327   REPEAT_N 4 (POP_ASSUM MP_TAC);
6328   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
6329   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6330   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6331   REWRITE_TAC[ALL2;interpsign;];
6332   REPEAT STRIP_TAC;
6333   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6334   ASM_REWRITE_TAC[];
6335   CLAIM `q x = &0`;
6336   ASM_MESON_TAC[];
6337   DISCH_THEN (REWRITE_ALL o list);
6338   POP_ASSUM (fun x -> ALL_TAC);
6339   REWRITE_TAC[REAL_MUL_RZERO;REAL_ADD_LID;];
6340   FIRST_ASSUM MATCH_MP_TAC;
6341   REWRITE_TAC[];
6342   (* save *)
6343   REPEAT STRIP_TAC;
6344   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
6345       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
6346   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
6347   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
6348   ARITH_TAC;
6349   STRIP_TAC;
6350   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6351   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6352   REPEAT STRIP_TAC;
6353   MATCH_MP_TAC ALL2_APPEND;
6354   ASM_REWRITE_TAC[];
6355   (* save *)
6356   REWRITE_ALL[TL;ALL2;interpsign;interpsigns;APPEND];
6357   ASM_REWRITE_TAC[];
6358   REPEAT STRIP_TAC;
6359   REPEAT_N 7 (POP_ASSUM MP_TAC);
6360   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
6361   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
6362   ASM_REWRITE_TAC[];
6363   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6364   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6365   REWRITE_TAC[ALL2;interpsign;];
6366   REPEAT STRIP_TAC;
6367   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6368   REPEAT_N 4 (POP_ASSUM MP_TAC);
6369   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
6370   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6371   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6372   REWRITE_TAC[ALL2;interpsign;];
6373   REPEAT STRIP_TAC;
6374   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6375   ASM_REWRITE_TAC[];
6376   CLAIM `q x = &0`;
6377   ASM_MESON_TAC[];
6378   DISCH_THEN (REWRITE_ALL o list);
6379   POP_ASSUM (fun x -> ALL_TAC);
6380   REWRITE_TAC[REAL_MUL_RZERO;REAL_ADD_LID;];
6381   FIRST_ASSUM MATCH_MP_TAC;
6382   REWRITE_TAC[];
6383 ]);;
6384 (* }}} *)
6385
6386 let INFERPSIGN_POS_EVEN_LEM = prove_by_refinement(
6387   `!a n p ps q qs r rs s x pts1 pts2  s1 s2 s3 rest sgns.
6388   interpmat (APPEND pts1 (CONS x pts2))
6389     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
6390     (APPEND sgns
6391       (CONS (APPEND (CONS Unknown s1)
6392         (APPEND (CONS Zero s2) (CONS Pos s3))) rest)) ==>
6393   (LENGTH ps = LENGTH s1) ==>
6394   (LENGTH qs = LENGTH s2) ==>
6395   ODD (LENGTH sgns) ==>
6396   (LENGTH sgns = 2 * LENGTH pts1 + 1) ==>
6397   (!x. a pow n * p x = s x * q x + r x) ==>
6398   (a <> &0) ==>
6399   EVEN n ==>
6400   interpmat (APPEND pts1 (CONS x pts2))
6401     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
6402     (APPEND sgns
6403       (CONS (APPEND (CONS Pos s1)
6404         (APPEND (CONS Zero s2) (CONS Pos s3))) rest))`,
6405 (* {{{ Proof *)
6406 [
6407   REPEAT STRIP_TAC;
6408   CLAIM `a pow n > &0`;
6409   ASM_MESON_TAC[EVEN_ODD_POW];
6410   STRIP_TAC;
6411   REPEAT (POP_ASSUM MP_TAC);
6412   REWRITE_TAC[interpmat];
6413   REPEAT STRIP_TAC;
6414   FIRST_ASSUM MATCH_ACCEPT_TAC;
6415   CASES_ON `pts1 = []`;
6416   POP_ASSUM (REWRITE_ALL o list);
6417   REWRITE_ALL[APPEND;partition_line;];
6418   COND_CASES_TAC;
6419   CLAIM `?k. sgns = [k]`;
6420   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
6421   REWRITE_ALL[LENGTH];
6422   REPEAT_N 5 (POP_ASSUM (fun x -> ALL_TAC));
6423   POP_ASSUM MP_TAC THEN ARITH_TAC;
6424   STRIP_TAC;
6425   POP_ASSUM (REWRITE_ALL o list);
6426   POP_ASSUM (REWRITE_ALL o list);
6427   REWRITE_ALL[APPEND;partition_line;ALL2;];
6428   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
6429   ASM_REWRITE_TAC[];
6430   REWRITE_ALL[interpsigns;interpsign;ALL2;];
6431   ASM_REWRITE_TAC[];
6432   REPEAT STRIP_TAC;
6433   REPEAT_N 8 (POP_ASSUM MP_TAC);
6434   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6435   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6436   REWRITE_TAC[ALL2;interpsign;];
6437   REPEAT STRIP_TAC;
6438   POP_ASSUM (REWRITE_ALL o list);
6439   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6440   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6441   REWRITE_TAC[ALL2;interpsign;];
6442   REPEAT STRIP_TAC;
6443   CLAIM `q x = &0`;
6444   ASM_MESON_TAC[];
6445   CLAIM `r x > &0`;
6446   ASM_MESON_TAC[];
6447   REPEAT_N 6 (POP_ASSUM MP_TAC);
6448   POP_ASSUM (MP_TAC o ISPEC `x:real`);
6449   REPEAT STRIP_TAC;
6450   POP_ASSUM (REWRITE_ALL o list);
6451   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
6452   REPEAT_N 7 (POP_ASSUM MP_TAC);
6453   POP_ASSUM (REWRITE_ALL o list o GSYM);
6454   REWRITE_TAC[real_gt;REAL_MUL_GT];
6455   REPEAT STRIP_TAC;
6456   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`];
6457   ASM_REWRITE_TAC[];
6458   (* save *)
6459   POP_ASSUM (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
6460   CLAIM `?k. sgns = [k]`;
6461   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
6462   REWRITE_ALL[LENGTH];
6463   REPEAT_N 5 (POP_ASSUM (fun x -> ALL_TAC));
6464   POP_ASSUM MP_TAC THEN ARITH_TAC;
6465   STRIP_TAC;
6466   POP_ASSUM (REWRITE_ALL o list);
6467   REWRITE_ALL[APPEND;partition_line;ALL2;];
6468   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
6469   ASM_REWRITE_TAC[];
6470   REWRITE_ALL[interpsigns;interpsign;ALL2;];
6471   ASM_REWRITE_TAC[];
6472   REPEAT STRIP_TAC;
6473   REPEAT_N 9 (POP_ASSUM MP_TAC);
6474   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6475   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6476   REWRITE_TAC[ALL2;interpsign;];
6477   REPEAT STRIP_TAC;
6478   ASM_REWRITE_TAC[];
6479   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6480   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6481   REWRITE_TAC[ALL2;interpsign;];
6482   REPEAT STRIP_TAC;
6483   ASM_REWRITE_TAC[];
6484   CLAIM `q x = &0`;
6485   ASM_MESON_TAC[];
6486   CLAIM `r x > &0`;
6487   ASM_MESON_TAC[];
6488   REPEAT_N 8 (POP_ASSUM MP_TAC);
6489   POP_ASSUM (MP_TAC o ISPEC `x:real`);
6490   REPEAT STRIP_TAC;
6491   POP_ASSUM (REWRITE_ALL o list);
6492   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
6493   REPEAT_N 9 (POP_ASSUM MP_TAC);
6494   POP_ASSUM (REWRITE_ALL o list o GSYM);
6495   REWRITE_TAC[real_gt;REAL_MUL_GT];
6496   REPEAT STRIP_TAC;
6497   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`];
6498   ASM_REWRITE_TAC[];
6499   (* save *)
6500   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
6501   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
6502   REPEAT STRIP_TAC;
6503   CLAIM `(APPEND (BUTLAST (partition_line pts1))
6504      (CONS (\x'. LAST pts1 < x' /\ x' < x)
6505      (TL (partition_line (CONS x pts2))))) =
6506      (APPEND
6507       (APPEND (BUTLAST (partition_line pts1))
6508       [\x'. LAST pts1 < x' /\ x' < x])
6509      (TL (partition_line (CONS x pts2))))`;
6510   ASM_MESON_TAC[APPEND_CONS];
6511   DISCH_THEN (REWRITE_ALL o list);
6512   REPEAT (POP_ASSUM MP_TAC);
6513   REWRITE_ALL[partition_line];
6514   COND_CASES_TAC;
6515   POP_ASSUM (REWRITE_ALL o list);
6516   REPEAT STRIP_TAC;
6517   REWRITE_ALL[TL;];
6518   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
6519       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
6520   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
6521   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
6522   ARITH_TAC;
6523   STRIP_TAC;
6524   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6525   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6526   REPEAT STRIP_TAC;
6527   MATCH_MP_TAC ALL2_APPEND;
6528   ASM_REWRITE_TAC[];
6529   (* save *)
6530   REPEAT_N 9 (POP_ASSUM MP_TAC);
6531   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
6532   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
6533   ASM_REWRITE_TAC[];
6534   REPEAT STRIP_TAC;
6535   RESTRIP_TAC;
6536   POP_ASSUM (REWRITE_ALL o list);
6537   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6538   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6539   REWRITE_TAC[ALL2;interpsign;];
6540   REPEAT STRIP_TAC;
6541   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6542   REPEAT_N 4 (POP_ASSUM MP_TAC);
6543   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
6544   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6545   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6546   REWRITE_TAC[ALL2;interpsign;];
6547   REPEAT STRIP_TAC;
6548   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6549   ASM_REWRITE_TAC[];
6550   CLAIM `q x = &0`;
6551   ASM_MESON_TAC[];
6552   CLAIM `r x > &0`;
6553   ASM_MESON_TAC[];
6554   REPEAT_N 15 (POP_ASSUM MP_TAC);
6555   POP_ASSUM (MP_TAC o ISPEC `x:real`);
6556   REPEAT STRIP_TAC;
6557   POP_ASSUM (REWRITE_ALL o list);
6558   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
6559   REPEAT_N 16 (POP_ASSUM MP_TAC);
6560   POP_ASSUM (REWRITE_ALL o list o GSYM);
6561   REWRITE_TAC[real_gt;REAL_MUL_GT];
6562   REPEAT STRIP_TAC;
6563   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`];
6564   ASM_REWRITE_TAC[];
6565   REPEAT STRIP_TAC;
6566   (* save *)
6567   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
6568       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
6569   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
6570   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
6571   ARITH_TAC;
6572   STRIP_TAC;
6573   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6574   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6575   REPEAT STRIP_TAC;
6576   MATCH_MP_TAC ALL2_APPEND;
6577   ASM_REWRITE_TAC[];
6578   (* save *)
6579   REWRITE_ALL[TL;ALL2;interpsign;interpsigns;APPEND];
6580   ASM_REWRITE_TAC[];
6581   REPEAT STRIP_TAC;
6582   REPEAT_N 10 (POP_ASSUM MP_TAC);
6583   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
6584   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
6585   ASM_REWRITE_TAC[];
6586   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6587   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6588   REWRITE_TAC[ALL2;interpsign;];
6589   REPEAT STRIP_TAC;
6590   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6591   REPEAT_N 4 (POP_ASSUM MP_TAC);
6592   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
6593   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6594   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6595   REWRITE_TAC[ALL2;interpsign;];
6596   REPEAT STRIP_TAC;
6597   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6598   ASM_REWRITE_TAC[];
6599   CLAIM `q x = &0`;
6600   ASM_MESON_TAC[];
6601   CLAIM `r x > &0`;
6602   ASM_MESON_TAC[];
6603   REPEAT_N 16 (POP_ASSUM MP_TAC);
6604   POP_ASSUM (MP_TAC o ISPEC `x:real`);
6605   REPEAT STRIP_TAC;
6606   POP_ASSUM (REWRITE_ALL o list);
6607   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
6608   REPEAT_N 17 (POP_ASSUM MP_TAC);
6609   POP_ASSUM (REWRITE_ALL o list o GSYM);
6610   REWRITE_TAC[real_gt;REAL_MUL_GT];
6611   REPEAT STRIP_TAC;
6612   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`];
6613 ]);;
6614 (* }}} *)
6615
6616 let SPLIT_LIST_THM = prove_by_refinement(
6617   `!n (l:A list). n < LENGTH l ==>
6618     ?l1 l2. (l = APPEND l1 l2) /\ (LENGTH l1 = n)`,
6619 (* {{{ Proof *)
6620 [
6621   INDUCT_TAC;
6622   REPEAT STRIP_TAC;
6623   EXISTS_TAC `[]:A list`;
6624   EXISTS_TAC `l`;
6625   REWRITE_TAC[APPEND;LENGTH];
6626   REPEAT STRIP_TAC;
6627   CLAIM `n < LENGTH l`;
6628   POP_ASSUM MP_TAC THEN ARITH_TAC;
6629   DISCH_THEN (fun x -> FIRST_ASSUM (fun y -> MP_TAC (MATCH_MP y x)));
6630   STRIP_TAC;
6631   EXISTS_TAC `APPEND l1 [HD l2]`;
6632   EXISTS_TAC `TL (l2:A list)`;
6633   CLAIM `~((l2:A list) = [])`;
6634   REWRITE_TAC[GSYM LENGTH_0];
6635   STRIP_TAC;
6636   POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC;
6637   POP_ASSUM (MP_TAC o AP_TERM `LENGTH:A list -> num`);
6638   REWRITE_TAC[LENGTH_APPEND];
6639   REPEAT STRIP_TAC;
6640   POP_ASSUM (REWRITE_ALL o list);
6641   POP_ASSUM (REWRITE_ALL o list);
6642   POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
6643   REWRITE_TAC[NOT_NIL;];
6644   STRIP_TAC;
6645   POP_ASSUM (REWRITE_ALL o list);
6646   ASM_REWRITE_TAC[TL;HD;LENGTH_APPEND;LENGTH;];
6647   STRIP_TAC;
6648   REWRITE_TAC[APPEND_APPEND;APPEND;];
6649   ARITH_TAC;
6650 ]);;
6651 (* }}} *)
6652
6653 let rec EXISTS_TACL =
6654   (fun l ->
6655      match l with
6656        [] -> ALL_TAC
6657      | h::t -> TYPE_TAC EXISTS_TAC h THEN EXISTS_TACL t);;
6658
6659
6660 let DIV_EVEN = prove_by_refinement(
6661  `!x. EVEN x ==> (2 * x DIV 2 = x)`,
6662 (* {{{ Proof *)
6663 [
6664   REPEAT STRIP_TAC;
6665   TYPE_TACL (fun l -> MP_TAC (ISPECL l DIVISION)) [`x`;`2`];
6666   ARITH_SIMP_TAC[];
6667   REWRITE_ASSUMS[EVEN_MOD];
6668   ASM_REWRITE_TAC[];
6669   ARITH_SIMP_TAC[];
6670   STRIP_TAC;
6671   REWRITE_ASSUMS[ARITH_RULE `x + 0 = x`];
6672   ONCE_REWRITE_ASSUMS[ARITH_RULE `x * y = y * x:num`];
6673   ASM_MESON_TAC[];
6674 ]);;
6675 (* }}} *)
6676
6677 let PRE_LEM = prove_by_refinement(
6678   `!n. (ODD n ==> EVEN (PRE n)) /\
6679        (~(n = 0) ==> (EVEN n ==> ODD (PRE n)))`,
6680 (* {{{ Proof *)
6681 [
6682   INDUCT_TAC;
6683   ARITH_TAC;
6684   POP_ASSUM MP_TAC THEN STRIP_TAC;
6685   REPEAT STRIP_TAC;
6686   REWRITE_TAC[PRE];
6687   ASM_MESON_TAC[ODD;NOT_ODD];
6688   ASM_MESON_TAC[ODD;PRE;NOT_ODD];
6689 ]);;
6690 (* }}} *)
6691
6692 let EVEN_PRE = GEN_ALL (CONJUNCT1 (SPEC_ALL PRE_LEM));;
6693 let ODD_PRE = GEN_ALL (CONJUNCT2 (SPEC_ALL PRE_LEM));;
6694
6695 let INFERPSIGN_POS_EVEN = prove_by_refinement(
6696   `!a n p ps q qs pts r rs s s1 s2 s3 rest sgns.
6697   interpmat pts
6698     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
6699     (APPEND sgns
6700       (CONS (APPEND (CONS Unknown s1)
6701         (APPEND (CONS Zero s2) (CONS Pos s3))) rest)) ==>
6702   (LENGTH ps = LENGTH s1) ==>
6703   (LENGTH qs = LENGTH s2) ==>
6704   ODD (LENGTH sgns) ==>
6705   (!x. a pow n * p x = s x * q x + r x) ==>
6706   (a <> &0) ==>
6707   EVEN n ==>
6708   interpmat pts
6709     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
6710     (APPEND sgns
6711       (CONS (APPEND (CONS Pos s1)
6712         (APPEND (CONS Zero s2) (CONS Pos s3))) rest))`,
6713 (* {{{ Proof *)
6714
6715 [
6716   REPEAT STRIP_TAC;
6717   CLAIM `LENGTH (APPEND sgns (CONS
6718     (APPEND (CONS Unknown s1)
6719       (APPEND (CONS Zero s2) (CONS Pos s3))) rest)) =
6720         LENGTH (partition_line pts)`;
6721   REWRITE_ALL[interpmat];
6722   ASM_MESON_TAC[ALL2_LENGTH];
6723   REWRITE_TAC[LENGTH_APPEND;PARTITION_LINE_LENGTH;LENGTH;];
6724   STRIP_TAC;
6725   TYPE_TACL (fun l -> MP_TAC (ISPECL l SPLIT_LIST_THM)) [`(LENGTH sgns - 1) DIV 2`;`pts`];
6726   STRIP_TAC;
6727   LABEL_ALL_TAC;
6728   PROVE_ASSUM_ANTECEDENT_TAC 0;
6729   POP_ASSUM (fun x -> ALL_TAC);
6730   POP_ASSUM MP_TAC;
6731   POP_ASSUM MP_TAC;
6732   POP_ASSUM (fun x -> ALL_TAC);
6733   POP_ASSUM (fun x -> ALL_TAC);
6734   POP_ASSUM MP_TAC;
6735   ARITH_TAC;
6736   POP_ASSUM MP_TAC THEN STRIP_TAC;
6737   ASM_REWRITE_TAC[];
6738   CLAIM `~(l2 = [])`;
6739   DISCH_THEN (REWRITE_ALL o list);
6740   POP_ASSUM MP_TAC;
6741   REWRITE_ALL[APPEND_NIL];
6742   POP_ASSUM (REWRITE_ALL o list);
6743   POP_ASSUM (fun x -> ALL_TAC);
6744   DISCH_THEN (REWRITE_ALL o list);
6745   POP_ASSUM MP_TAC;
6746   POP_ASSUM MP_TAC;
6747   POP_ASSUM (fun x -> ALL_TAC);
6748   POP_ASSUM (fun x -> ALL_TAC);
6749   POP_ASSUM MP_TAC THEN ARITH_TAC;
6750   REWRITE_TAC[NOT_NIL];
6751   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
6752   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] INFERPSIGN_POS_EVEN_LEM);
6753   ASM_REWRITE_TAC[];
6754   EXISTS_TACL [`a`;`n`;`s`];
6755   (* save *)
6756   ASM_REWRITE_TAC[];
6757   STRIP_TAC;
6758   ASM_MESON_TAC[];
6759   LABEL_ALL_TAC;
6760   CLAIM `EVEN (LENGTH sgns - 1)`;
6761   ASM_MESON_TAC[EVEN_PRE;ARITH_RULE `x - 1 = PRE x`];
6762   STRIP_TAC;
6763   ASM_SIMP_TAC[DIV_EVEN];
6764   USE_THEN "Z-5" MP_TAC THEN ARITH_TAC;
6765 ]);;
6766
6767 (* }}} *)
6768
6769 let INFERPSIGN_NEG_EVEN_LEM = prove_by_refinement(
6770   `!a n p ps q qs r rs s x pts1 pts2  s1 s2 s3 rest sgns.
6771   interpmat (APPEND pts1 (CONS x pts2))
6772     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
6773     (APPEND sgns
6774       (CONS (APPEND (CONS Unknown s1)
6775         (APPEND (CONS Zero s2) (CONS Neg s3))) rest)) ==>
6776   (LENGTH ps = LENGTH s1) ==>
6777   (LENGTH qs = LENGTH s2) ==>
6778   ODD (LENGTH sgns) ==>
6779   (LENGTH sgns = 2 * LENGTH pts1 + 1) ==>
6780   (!x. a pow n * p x = s x * q x + r x) ==>
6781   (a <> &0) ==>
6782   EVEN n ==>
6783   interpmat (APPEND pts1 (CONS x pts2))
6784     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
6785     (APPEND sgns
6786       (CONS (APPEND (CONS Neg s1)
6787         (APPEND (CONS Zero s2) (CONS Neg s3))) rest))`,
6788 (* {{{ Proof *)
6789 [
6790   REPEAT STRIP_TAC;
6791   CLAIM `a pow n > &0`;
6792   ASM_MESON_TAC[EVEN_ODD_POW];
6793   STRIP_TAC;
6794   REPEAT (POP_ASSUM MP_TAC);
6795   REWRITE_TAC[interpmat];
6796   REPEAT STRIP_TAC;
6797   FIRST_ASSUM MATCH_ACCEPT_TAC;
6798   CASES_ON `pts1 = []`;
6799   POP_ASSUM (REWRITE_ALL o list);
6800   REWRITE_ALL[APPEND;partition_line;];
6801   COND_CASES_TAC;
6802   CLAIM `?k. sgns = [k]`;
6803   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
6804   REWRITE_ALL[LENGTH];
6805   REPEAT_N 5 (POP_ASSUM (fun x -> ALL_TAC));
6806   POP_ASSUM MP_TAC THEN ARITH_TAC;
6807   STRIP_TAC;
6808   POP_ASSUM (REWRITE_ALL o list);
6809   POP_ASSUM (REWRITE_ALL o list);
6810   REWRITE_ALL[APPEND;partition_line;ALL2;];
6811   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
6812   ASM_REWRITE_TAC[];
6813   REWRITE_ALL[interpsigns;interpsign;ALL2;];
6814   ASM_REWRITE_TAC[];
6815   REPEAT STRIP_TAC;
6816   REPEAT_N 8 (POP_ASSUM MP_TAC);
6817   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6818   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6819   REWRITE_TAC[ALL2;interpsign;];
6820   REPEAT STRIP_TAC;
6821   POP_ASSUM (REWRITE_ALL o list);
6822   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6823   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6824   REWRITE_TAC[ALL2;interpsign;];
6825   REPEAT STRIP_TAC;
6826   CLAIM `q x = &0`;
6827   ASM_MESON_TAC[];
6828   CLAIM `r x < &0`;
6829   ASM_MESON_TAC[];
6830   REPEAT_N 6 (POP_ASSUM MP_TAC);
6831   POP_ASSUM (MP_TAC o ISPEC `x:real`);
6832   REPEAT STRIP_TAC;
6833   POP_ASSUM (REWRITE_ALL o list);
6834   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
6835   REPEAT_N 7 (POP_ASSUM MP_TAC);
6836   POP_ASSUM (REWRITE_ALL o list o GSYM);
6837   REWRITE_TAC[real_gt;REAL_MUL_GT];
6838   REPEAT STRIP_TAC;
6839   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT];
6840   ASM_REWRITE_TAC[];
6841   (* save *)
6842   POP_ASSUM (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
6843   CLAIM `?k. sgns = [k]`;
6844   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
6845   REWRITE_ALL[LENGTH];
6846   REPEAT_N 5 (POP_ASSUM (fun x -> ALL_TAC));
6847   POP_ASSUM MP_TAC THEN ARITH_TAC;
6848   STRIP_TAC;
6849   POP_ASSUM (REWRITE_ALL o list);
6850   REWRITE_ALL[APPEND;partition_line;ALL2;];
6851   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
6852   ASM_REWRITE_TAC[];
6853   REWRITE_ALL[interpsigns;interpsign;ALL2;];
6854   ASM_REWRITE_TAC[];
6855   REPEAT STRIP_TAC;
6856   REPEAT_N 9 (POP_ASSUM MP_TAC);
6857   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6858   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6859   REWRITE_TAC[ALL2;interpsign;];
6860   REPEAT STRIP_TAC;
6861   ASM_REWRITE_TAC[];
6862   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6863   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6864   REWRITE_TAC[ALL2;interpsign;];
6865   REPEAT STRIP_TAC;
6866   ASM_REWRITE_TAC[];
6867   CLAIM `q x = &0`;
6868   ASM_MESON_TAC[];
6869   CLAIM `r x < &0`;
6870   ASM_MESON_TAC[];
6871   REPEAT_N 8 (POP_ASSUM MP_TAC);
6872   POP_ASSUM (MP_TAC o ISPEC `x:real`);
6873   REPEAT STRIP_TAC;
6874   POP_ASSUM (REWRITE_ALL o list);
6875   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
6876   REPEAT_N 9 (POP_ASSUM MP_TAC);
6877   POP_ASSUM (REWRITE_ALL o list o GSYM);
6878   REWRITE_TAC[real_gt;REAL_MUL_GT];
6879   REPEAT STRIP_TAC;
6880   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT];
6881   ASM_REWRITE_TAC[];
6882   (* save *)
6883   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
6884   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
6885   REPEAT STRIP_TAC;
6886   CLAIM `(APPEND (BUTLAST (partition_line pts1))
6887      (CONS (\x'. LAST pts1 < x' /\ x' < x)
6888      (TL (partition_line (CONS x pts2))))) =
6889      (APPEND
6890       (APPEND (BUTLAST (partition_line pts1))
6891       [\x'. LAST pts1 < x' /\ x' < x])
6892      (TL (partition_line (CONS x pts2))))`;
6893   ASM_MESON_TAC[APPEND_CONS];
6894   DISCH_THEN (REWRITE_ALL o list);
6895   REPEAT (POP_ASSUM MP_TAC);
6896   REWRITE_ALL[partition_line];
6897   COND_CASES_TAC;
6898   POP_ASSUM (REWRITE_ALL o list);
6899   REPEAT STRIP_TAC;
6900   REWRITE_ALL[TL;];
6901   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
6902       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
6903   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
6904   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
6905   ARITH_TAC;
6906   STRIP_TAC;
6907   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6908   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6909   REPEAT STRIP_TAC;
6910   MATCH_MP_TAC ALL2_APPEND;
6911   ASM_REWRITE_TAC[];
6912   (* save *)
6913   REPEAT_N 9 (POP_ASSUM MP_TAC);
6914   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
6915   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
6916   ASM_REWRITE_TAC[];
6917   REPEAT STRIP_TAC;
6918   RESTRIP_TAC;
6919   POP_ASSUM (REWRITE_ALL o list);
6920   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6921   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6922   REWRITE_TAC[ALL2;interpsign;];
6923   REPEAT STRIP_TAC;
6924   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6925   REPEAT_N 4 (POP_ASSUM MP_TAC);
6926   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
6927   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6928   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6929   REWRITE_TAC[ALL2;interpsign;];
6930   REPEAT STRIP_TAC;
6931   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6932   ASM_REWRITE_TAC[];
6933   CLAIM `q x = &0`;
6934   ASM_MESON_TAC[];
6935   CLAIM `r x < &0`;
6936   ASM_MESON_TAC[];
6937   REPEAT_N 15 (POP_ASSUM MP_TAC);
6938   POP_ASSUM (MP_TAC o ISPEC `x:real`);
6939   REPEAT STRIP_TAC;
6940   POP_ASSUM (REWRITE_ALL o list);
6941   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
6942   REPEAT_N 16 (POP_ASSUM MP_TAC);
6943   POP_ASSUM (REWRITE_ALL o list o GSYM);
6944   REWRITE_TAC[real_gt;REAL_MUL_GT];
6945   REPEAT STRIP_TAC;
6946   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT];
6947   ASM_REWRITE_TAC[];
6948   REPEAT STRIP_TAC;
6949   (* save *)
6950   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
6951       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
6952   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
6953   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
6954   ARITH_TAC;
6955   STRIP_TAC;
6956   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6957   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6958   REPEAT STRIP_TAC;
6959   MATCH_MP_TAC ALL2_APPEND;
6960   ASM_REWRITE_TAC[];
6961   (* save *)
6962   REWRITE_ALL[TL;ALL2;interpsign;interpsigns;APPEND];
6963   ASM_REWRITE_TAC[];
6964   REPEAT STRIP_TAC;
6965   REPEAT_N 10 (POP_ASSUM MP_TAC);
6966   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
6967   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
6968   ASM_REWRITE_TAC[];
6969   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6970   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6971   REWRITE_TAC[ALL2;interpsign;];
6972   REPEAT STRIP_TAC;
6973   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6974   REPEAT_N 4 (POP_ASSUM MP_TAC);
6975   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
6976   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
6977   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
6978   REWRITE_TAC[ALL2;interpsign;];
6979   REPEAT STRIP_TAC;
6980   REWRITE_ALL[interpsigns;ALL2;interpsign;];
6981   ASM_REWRITE_TAC[];
6982   CLAIM `q x = &0`;
6983   ASM_MESON_TAC[];
6984   CLAIM `r x < &0`;
6985   ASM_MESON_TAC[];
6986   REPEAT_N 16 (POP_ASSUM MP_TAC);
6987   POP_ASSUM (MP_TAC o ISPEC `x:real`);
6988   REPEAT STRIP_TAC;
6989   POP_ASSUM (REWRITE_ALL o list);
6990   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
6991   REPEAT_N 17 (POP_ASSUM MP_TAC);
6992   POP_ASSUM (REWRITE_ALL o list o GSYM);
6993   REWRITE_TAC[real_gt;REAL_MUL_GT];
6994   REPEAT STRIP_TAC;
6995   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT];
6996 ]);;
6997 (* }}} *)
6998
6999
7000 let INFERPSIGN_NEG_EVEN = prove_by_refinement(
7001   `!a n p ps q qs pts r rs s s1 s2 s3 rest sgns.
7002   interpmat pts
7003     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7004     (APPEND sgns
7005       (CONS (APPEND (CONS Unknown s1)
7006         (APPEND (CONS Zero s2) (CONS Neg s3))) rest)) ==>
7007   (LENGTH ps = LENGTH s1) ==>
7008   (LENGTH qs = LENGTH s2) ==>
7009   ODD (LENGTH sgns) ==>
7010   (!x. a pow n * p x = s x * q x + r x) ==>
7011   (a <> &0) ==>
7012   EVEN n ==>
7013   interpmat pts
7014     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7015     (APPEND sgns
7016       (CONS (APPEND (CONS Neg s1)
7017         (APPEND (CONS Zero s2) (CONS Neg s3))) rest))`,
7018 (* {{{ Proof *)
7019
7020 [
7021   REPEAT STRIP_TAC;
7022   CLAIM `LENGTH (APPEND sgns (CONS
7023     (APPEND (CONS Unknown s1)
7024       (APPEND (CONS Zero s2) (CONS Neg s3))) rest)) =
7025         LENGTH (partition_line pts)`;
7026   REWRITE_ALL[interpmat];
7027   ASM_MESON_TAC[ALL2_LENGTH];
7028   REWRITE_TAC[LENGTH_APPEND;PARTITION_LINE_LENGTH;LENGTH;];
7029   STRIP_TAC;
7030   TYPE_TACL (fun l -> MP_TAC (ISPECL l SPLIT_LIST_THM)) [`(LENGTH sgns - 1) DIV 2`;`pts`];
7031   STRIP_TAC;
7032   LABEL_ALL_TAC;
7033   PROVE_ASSUM_ANTECEDENT_TAC 0;
7034   POP_ASSUM (fun x -> ALL_TAC);
7035   POP_ASSUM MP_TAC;
7036   POP_ASSUM MP_TAC;
7037   POP_ASSUM (fun x -> ALL_TAC);
7038   POP_ASSUM (fun x -> ALL_TAC);
7039   POP_ASSUM MP_TAC;
7040   ARITH_TAC;
7041   POP_ASSUM MP_TAC THEN STRIP_TAC;
7042   ASM_REWRITE_TAC[];
7043   CLAIM `~(l2 = [])`;
7044   DISCH_THEN (REWRITE_ALL o list);
7045   POP_ASSUM MP_TAC;
7046   REWRITE_ALL[APPEND_NIL];
7047   POP_ASSUM (REWRITE_ALL o list);
7048   POP_ASSUM (fun x -> ALL_TAC);
7049   DISCH_THEN (REWRITE_ALL o list);
7050   POP_ASSUM MP_TAC;
7051   POP_ASSUM MP_TAC;
7052   POP_ASSUM (fun x -> ALL_TAC);
7053   POP_ASSUM (fun x -> ALL_TAC);
7054   POP_ASSUM MP_TAC THEN ARITH_TAC;
7055   REWRITE_TAC[NOT_NIL];
7056   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
7057   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] INFERPSIGN_NEG_EVEN_LEM);
7058   ASM_REWRITE_TAC[];
7059   EXISTS_TACL [`a`;`n`;`s`];
7060   (* save *)
7061   ASM_REWRITE_TAC[];
7062   STRIP_TAC;
7063   ASM_MESON_TAC[];
7064   LABEL_ALL_TAC;
7065   CLAIM `EVEN (LENGTH sgns - 1)`;
7066   ASM_MESON_TAC[EVEN_PRE;ARITH_RULE `x - 1 = PRE x`];
7067   STRIP_TAC;
7068   ASM_SIMP_TAC[DIV_EVEN];
7069   USE_THEN "Z-5" MP_TAC THEN ARITH_TAC;
7070 ]);;
7071
7072 (* }}} *)
7073
7074 let INFERPSIGN_ZERO_EVEN_LEM = prove_by_refinement(
7075   `!a n p ps q qs r rs s x pts1 pts2  s1 s2 s3 rest sgns.
7076   interpmat (APPEND pts1 (CONS x pts2))
7077     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7078     (APPEND sgns
7079       (CONS (APPEND (CONS Unknown s1)
7080         (APPEND (CONS Zero s2) (CONS Zero s3))) rest)) ==>
7081   (LENGTH ps = LENGTH s1) ==>
7082   (LENGTH qs = LENGTH s2) ==>
7083   ODD (LENGTH sgns) ==>
7084   (LENGTH sgns = 2 * LENGTH pts1 + 1) ==>
7085   (!x. a pow n * p x = s x * q x + r x) ==>
7086   (a <> &0) ==>
7087   EVEN n ==>
7088   interpmat (APPEND pts1 (CONS x pts2))
7089     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7090     (APPEND sgns
7091       (CONS (APPEND (CONS Zero s1)
7092         (APPEND (CONS Zero s2) (CONS Zero s3))) rest))`,
7093 (* {{{ Proof *)
7094 [
7095   REPEAT STRIP_TAC;
7096   CLAIM `a pow n > &0`;
7097   ASM_MESON_TAC[EVEN_ODD_POW];
7098   STRIP_TAC;
7099   REPEAT (POP_ASSUM MP_TAC);
7100   REWRITE_TAC[interpmat];
7101   REPEAT STRIP_TAC;
7102   FIRST_ASSUM MATCH_ACCEPT_TAC;
7103   CASES_ON `pts1 = []`;
7104   POP_ASSUM (REWRITE_ALL o list);
7105   REWRITE_ALL[APPEND;partition_line;];
7106   COND_CASES_TAC;
7107   CLAIM `?k. sgns = [k]`;
7108   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
7109   REWRITE_ALL[LENGTH];
7110   REPEAT_N 5 (POP_ASSUM (fun x -> ALL_TAC));
7111   POP_ASSUM MP_TAC THEN ARITH_TAC;
7112   STRIP_TAC;
7113   POP_ASSUM (REWRITE_ALL o list);
7114   POP_ASSUM (REWRITE_ALL o list);
7115   REWRITE_ALL[APPEND;partition_line;ALL2;];
7116   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
7117   ASM_REWRITE_TAC[];
7118   REWRITE_ALL[interpsigns;interpsign;ALL2;];
7119   ASM_REWRITE_TAC[];
7120   REPEAT STRIP_TAC;
7121   REPEAT_N 8 (POP_ASSUM MP_TAC);
7122   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7123   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7124   REWRITE_TAC[ALL2;interpsign;];
7125   REPEAT STRIP_TAC;
7126   POP_ASSUM (REWRITE_ALL o list);
7127   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7128   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7129   REWRITE_TAC[ALL2;interpsign;];
7130   REPEAT STRIP_TAC;
7131   CLAIM `q x = &0`;
7132   ASM_MESON_TAC[];
7133   CLAIM `r x = &0`;
7134   ASM_MESON_TAC[];
7135   REPEAT_N 6 (POP_ASSUM MP_TAC);
7136   POP_ASSUM (MP_TAC o ISPEC `x:real`);
7137   REPEAT STRIP_TAC;
7138   POP_ASSUM (REWRITE_ALL o list);
7139   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
7140   REPEAT_N 7 (POP_ASSUM MP_TAC);
7141   POP_ASSUM (REWRITE_ALL o list o GSYM);
7142   REWRITE_TAC[real_gt;REAL_MUL_GT];
7143   REPEAT STRIP_TAC;
7144   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`];
7145   ASM_REWRITE_TAC[];
7146   (* save *)
7147   POP_ASSUM (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
7148   CLAIM `?k. sgns = [k]`;
7149   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
7150   REWRITE_ALL[LENGTH];
7151   REPEAT_N 5 (POP_ASSUM (fun x -> ALL_TAC));
7152   POP_ASSUM MP_TAC THEN ARITH_TAC;
7153   STRIP_TAC;
7154   POP_ASSUM (REWRITE_ALL o list);
7155   REWRITE_ALL[APPEND;partition_line;ALL2;];
7156   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
7157   ASM_REWRITE_TAC[];
7158   REWRITE_ALL[interpsigns;interpsign;ALL2;];
7159   ASM_REWRITE_TAC[];
7160   REPEAT STRIP_TAC;
7161   REPEAT_N 9 (POP_ASSUM MP_TAC);
7162   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7163   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7164   REWRITE_TAC[ALL2;interpsign;];
7165   REPEAT STRIP_TAC;
7166   ASM_REWRITE_TAC[];
7167   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7168   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7169   REWRITE_TAC[ALL2;interpsign;];
7170   REPEAT STRIP_TAC;
7171   ASM_REWRITE_TAC[];
7172   CLAIM `q x = &0`;
7173   ASM_MESON_TAC[];
7174   CLAIM `r x = &0`;
7175   ASM_MESON_TAC[];
7176   REPEAT_N 8 (POP_ASSUM MP_TAC);
7177   POP_ASSUM (MP_TAC o ISPEC `x:real`);
7178   REPEAT STRIP_TAC;
7179   POP_ASSUM (REWRITE_ALL o list);
7180   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
7181   REPEAT_N 9 (POP_ASSUM MP_TAC);
7182   POP_ASSUM (REWRITE_ALL o list o GSYM);
7183   REWRITE_TAC[real_gt;REAL_MUL_GT];
7184   REPEAT STRIP_TAC;
7185   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`];
7186   ASM_REWRITE_TAC[];
7187   (* save *)
7188   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
7189   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
7190   REPEAT STRIP_TAC;
7191   CLAIM `(APPEND (BUTLAST (partition_line pts1))
7192      (CONS (\x'. LAST pts1 < x' /\ x' < x)
7193      (TL (partition_line (CONS x pts2))))) =
7194      (APPEND
7195       (APPEND (BUTLAST (partition_line pts1))
7196       [\x'. LAST pts1 < x' /\ x' < x])
7197      (TL (partition_line (CONS x pts2))))`;
7198   ASM_MESON_TAC[APPEND_CONS];
7199   DISCH_THEN (REWRITE_ALL o list);
7200   REPEAT (POP_ASSUM MP_TAC);
7201   REWRITE_ALL[partition_line];
7202   COND_CASES_TAC;
7203   POP_ASSUM (REWRITE_ALL o list);
7204   REPEAT STRIP_TAC;
7205   REWRITE_ALL[TL;];
7206   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
7207       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
7208   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
7209   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
7210   ARITH_TAC;
7211   STRIP_TAC;
7212   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7213   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7214   REPEAT STRIP_TAC;
7215   MATCH_MP_TAC ALL2_APPEND;
7216   ASM_REWRITE_TAC[];
7217   (* save *)
7218   REPEAT_N 9 (POP_ASSUM MP_TAC);
7219   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
7220   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
7221   ASM_REWRITE_TAC[];
7222   REPEAT STRIP_TAC;
7223   RESTRIP_TAC;
7224   POP_ASSUM (REWRITE_ALL o list);
7225   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7226   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7227   REWRITE_TAC[ALL2;interpsign;];
7228   REPEAT STRIP_TAC;
7229   REWRITE_ALL[interpsigns;ALL2;interpsign;];
7230   REPEAT_N 4 (POP_ASSUM MP_TAC);
7231   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
7232   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7233   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7234   REWRITE_TAC[ALL2;interpsign;];
7235   REPEAT STRIP_TAC;
7236   REWRITE_ALL[interpsigns;ALL2;interpsign;];
7237   ASM_REWRITE_TAC[];
7238   CLAIM `q x = &0`;
7239   ASM_MESON_TAC[];
7240   CLAIM `r x = &0`;
7241   ASM_MESON_TAC[];
7242   REPEAT_N 15 (POP_ASSUM MP_TAC);
7243   POP_ASSUM (MP_TAC o ISPEC `x:real`);
7244   REPEAT STRIP_TAC;
7245   POP_ASSUM (REWRITE_ALL o list);
7246   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
7247   REPEAT_N 16 (POP_ASSUM MP_TAC);
7248   POP_ASSUM (REWRITE_ALL o list o GSYM);
7249   REWRITE_TAC[real_gt;REAL_MUL_GT];
7250   REPEAT STRIP_TAC;
7251   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`];
7252   ASM_REWRITE_TAC[];
7253   REPEAT STRIP_TAC;
7254   (* save *)
7255   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
7256       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
7257   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
7258   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
7259   ARITH_TAC;
7260   STRIP_TAC;
7261   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7262   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7263   REPEAT STRIP_TAC;
7264   MATCH_MP_TAC ALL2_APPEND;
7265   ASM_REWRITE_TAC[];
7266   (* save *)
7267   REWRITE_ALL[TL;ALL2;interpsign;interpsigns;APPEND];
7268   ASM_REWRITE_TAC[];
7269   REPEAT STRIP_TAC;
7270   REPEAT_N 10 (POP_ASSUM MP_TAC);
7271   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
7272   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
7273   ASM_REWRITE_TAC[];
7274   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7275   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7276   REWRITE_TAC[ALL2;interpsign;];
7277   REPEAT STRIP_TAC;
7278   REWRITE_ALL[interpsigns;ALL2;interpsign;];
7279   REPEAT_N 4 (POP_ASSUM MP_TAC);
7280   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
7281   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7282   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7283   REWRITE_TAC[ALL2;interpsign;];
7284   REPEAT STRIP_TAC;
7285   REWRITE_ALL[interpsigns;ALL2;interpsign;];
7286   ASM_REWRITE_TAC[];
7287   CLAIM `q x = &0`;
7288   ASM_MESON_TAC[];
7289   CLAIM `r x = &0`;
7290   ASM_MESON_TAC[];
7291   REPEAT_N 16 (POP_ASSUM MP_TAC);
7292   POP_ASSUM (MP_TAC o ISPEC `x:real`);
7293   REPEAT STRIP_TAC;
7294   POP_ASSUM (REWRITE_ALL o list);
7295   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
7296   REPEAT_N 17 (POP_ASSUM MP_TAC);
7297   POP_ASSUM (REWRITE_ALL o list o GSYM);
7298   REWRITE_TAC[real_gt;REAL_MUL_GT];
7299   REPEAT STRIP_TAC;
7300   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`];
7301 ]);;
7302 (* }}} *)
7303
7304 let INFERPSIGN_ZERO_EVEN = prove_by_refinement(
7305   `!a n p ps q qs pts r rs s s1 s2 s3 rest sgns.
7306   interpmat pts
7307     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7308     (APPEND sgns
7309       (CONS (APPEND (CONS Unknown s1)
7310         (APPEND (CONS Zero s2) (CONS Zero s3))) rest)) ==>
7311   (LENGTH ps = LENGTH s1) ==>
7312   (LENGTH qs = LENGTH s2) ==>
7313   ODD (LENGTH sgns) ==>
7314   (!x. a pow n * p x = s x * q x + r x) ==>
7315   (a <> &0) ==>
7316   EVEN n ==>
7317   interpmat pts
7318     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7319     (APPEND sgns
7320       (CONS (APPEND (CONS Zero s1)
7321         (APPEND (CONS Zero s2) (CONS Zero s3))) rest))`,
7322 (* {{{ Proof *)
7323
7324 [
7325   REPEAT STRIP_TAC;
7326   CLAIM `LENGTH (APPEND sgns (CONS
7327     (APPEND (CONS Unknown s1)
7328       (APPEND (CONS Zero s2) (CONS Zero s3))) rest)) =
7329         LENGTH (partition_line pts)`;
7330   REWRITE_ALL[interpmat];
7331   ASM_MESON_TAC[ALL2_LENGTH];
7332   REWRITE_TAC[LENGTH_APPEND;PARTITION_LINE_LENGTH;LENGTH;];
7333   STRIP_TAC;
7334   TYPE_TACL (fun l -> MP_TAC (ISPECL l SPLIT_LIST_THM)) [`(LENGTH sgns - 1) DIV 2`;`pts`];
7335   STRIP_TAC;
7336   LABEL_ALL_TAC;
7337   PROVE_ASSUM_ANTECEDENT_TAC 0;
7338   POP_ASSUM (fun x -> ALL_TAC);
7339   POP_ASSUM MP_TAC;
7340   POP_ASSUM MP_TAC;
7341   POP_ASSUM (fun x -> ALL_TAC);
7342   POP_ASSUM (fun x -> ALL_TAC);
7343   POP_ASSUM MP_TAC;
7344   ARITH_TAC;
7345   POP_ASSUM MP_TAC THEN STRIP_TAC;
7346   ASM_REWRITE_TAC[];
7347   CLAIM `~(l2 = [])`;
7348   DISCH_THEN (REWRITE_ALL o list);
7349   POP_ASSUM MP_TAC;
7350   REWRITE_ALL[APPEND_NIL];
7351   POP_ASSUM (REWRITE_ALL o list);
7352   POP_ASSUM (fun x -> ALL_TAC);
7353   DISCH_THEN (REWRITE_ALL o list);
7354   POP_ASSUM MP_TAC;
7355   POP_ASSUM MP_TAC;
7356   POP_ASSUM (fun x -> ALL_TAC);
7357   POP_ASSUM (fun x -> ALL_TAC);
7358   POP_ASSUM MP_TAC THEN ARITH_TAC;
7359   REWRITE_TAC[NOT_NIL];
7360   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
7361   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] INFERPSIGN_ZERO_EVEN_LEM);
7362   ASM_REWRITE_TAC[];
7363   EXISTS_TACL [`a`;`n`;`s`];
7364   (* save *)
7365   ASM_REWRITE_TAC[];
7366   STRIP_TAC;
7367   ASM_MESON_TAC[];
7368   LABEL_ALL_TAC;
7369   CLAIM `EVEN (LENGTH sgns - 1)`;
7370   ASM_MESON_TAC[EVEN_PRE;ARITH_RULE `x - 1 = PRE x`];
7371   STRIP_TAC;
7372   ASM_SIMP_TAC[DIV_EVEN];
7373   USE_THEN "Z-5" MP_TAC THEN ARITH_TAC;
7374 ]);;
7375
7376 (* }}} *)
7377
7378
7379 let INFERPSIGN_POS_ODD_POS_LEM = prove_by_refinement(
7380   `!a n p ps q qs r rs s x pts1 pts2  s1 s2 s3 rest sgns.
7381   interpmat (APPEND pts1 (CONS x pts2))
7382     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7383     (APPEND sgns
7384       (CONS (APPEND (CONS Unknown s1)
7385         (APPEND (CONS Zero s2) (CONS Pos s3))) rest)) ==>
7386   (LENGTH ps = LENGTH s1) ==>
7387   (LENGTH qs = LENGTH s2) ==>
7388   ODD (LENGTH sgns) ==>
7389   (LENGTH sgns = 2 * LENGTH pts1 + 1) ==>
7390   (!x. a pow n * p x = s x * q x + r x) ==>
7391   (a > &0) ==>
7392   interpmat (APPEND pts1 (CONS x pts2))
7393     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7394     (APPEND sgns
7395       (CONS (APPEND (CONS Pos s1)
7396         (APPEND (CONS Zero s2) (CONS Pos s3))) rest))`,
7397 (* {{{ Proof *)
7398 [
7399   REPEAT STRIP_TAC;
7400   CLAIM `a pow n > &0`;
7401   ASM_MESON_TAC[REAL_POW_LT;real_gt;];
7402   STRIP_TAC;
7403   REPEAT (POP_ASSUM MP_TAC);
7404   REWRITE_TAC[interpmat];
7405   REPEAT STRIP_TAC;
7406   FIRST_ASSUM MATCH_ACCEPT_TAC;
7407   CASES_ON `pts1 = []`;
7408   POP_ASSUM (REWRITE_ALL o list);
7409   REWRITE_ALL[APPEND;partition_line;];
7410   COND_CASES_TAC;
7411   CLAIM `?k. sgns = [k]`;
7412   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
7413   REWRITE_ALL[LENGTH];
7414   REPEAT_N 4 (POP_ASSUM (fun x -> ALL_TAC));
7415   POP_ASSUM MP_TAC THEN ARITH_TAC;
7416   STRIP_TAC;
7417   POP_ASSUM (REWRITE_ALL o list);
7418   POP_ASSUM (REWRITE_ALL o list);
7419   REWRITE_ALL[APPEND;partition_line;ALL2;];
7420   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
7421   ASM_REWRITE_TAC[];
7422   REWRITE_ALL[interpsigns;interpsign;ALL2;];
7423   ASM_REWRITE_TAC[];
7424   REPEAT STRIP_TAC;
7425   REPEAT_N 7 (POP_ASSUM MP_TAC);
7426   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7427   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7428   REWRITE_TAC[ALL2;interpsign;];
7429   REPEAT STRIP_TAC;
7430   POP_ASSUM (REWRITE_ALL o list);
7431   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7432   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7433   REWRITE_TAC[ALL2;interpsign;];
7434   REPEAT STRIP_TAC;
7435   CLAIM `q x = &0`;
7436   ASM_MESON_TAC[];
7437   CLAIM `r x > &0`;
7438   ASM_MESON_TAC[];
7439   REPEAT_N 5 (POP_ASSUM MP_TAC);
7440   POP_ASSUM (MP_TAC o ISPEC `x:real`);
7441   REPEAT STRIP_TAC;
7442   POP_ASSUM (REWRITE_ALL o list);
7443   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
7444   REPEAT_N 6 (POP_ASSUM MP_TAC);
7445   POP_ASSUM (REWRITE_ALL o list o GSYM);
7446   REWRITE_TAC[real_gt;REAL_MUL_GT];
7447   REPEAT STRIP_TAC;
7448   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`];
7449   ASM_REWRITE_TAC[];
7450   (* save *)
7451   POP_ASSUM (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
7452   CLAIM `?k. sgns = [k]`;
7453   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
7454   REWRITE_ALL[LENGTH];
7455   REPEAT_N 4 (POP_ASSUM (fun x -> ALL_TAC));
7456   POP_ASSUM MP_TAC THEN ARITH_TAC;
7457   STRIP_TAC;
7458   POP_ASSUM (REWRITE_ALL o list);
7459   REWRITE_ALL[APPEND;partition_line;ALL2;];
7460   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
7461   ASM_REWRITE_TAC[];
7462   REWRITE_ALL[interpsigns;interpsign;ALL2;];
7463   ASM_REWRITE_TAC[];
7464   REPEAT STRIP_TAC;
7465   REPEAT_N 8 (POP_ASSUM MP_TAC);
7466   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7467   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7468   REWRITE_TAC[ALL2;interpsign;];
7469   REPEAT STRIP_TAC;
7470   ASM_REWRITE_TAC[];
7471   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7472   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7473   REWRITE_TAC[ALL2;interpsign;];
7474   REPEAT STRIP_TAC;
7475   ASM_REWRITE_TAC[];
7476   CLAIM `q x = &0`;
7477   ASM_MESON_TAC[];
7478   CLAIM `r x > &0`;
7479   ASM_MESON_TAC[];
7480   REPEAT_N 7 (POP_ASSUM MP_TAC);
7481   POP_ASSUM (MP_TAC o ISPEC `x:real`);
7482   REPEAT STRIP_TAC;
7483   POP_ASSUM (REWRITE_ALL o list);
7484   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
7485   REPEAT_N 8 (POP_ASSUM MP_TAC);
7486   POP_ASSUM (REWRITE_ALL o list o GSYM);
7487   REWRITE_TAC[real_gt;REAL_MUL_GT];
7488   REPEAT STRIP_TAC;
7489   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`];
7490   ASM_REWRITE_TAC[];
7491   (* save *)
7492   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
7493   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
7494   REPEAT STRIP_TAC;
7495   CLAIM `(APPEND (BUTLAST (partition_line pts1))
7496      (CONS (\x'. LAST pts1 < x' /\ x' < x)
7497      (TL (partition_line (CONS x pts2))))) =
7498      (APPEND
7499       (APPEND (BUTLAST (partition_line pts1))
7500       [\x'. LAST pts1 < x' /\ x' < x])
7501      (TL (partition_line (CONS x pts2))))`;
7502   ASM_MESON_TAC[APPEND_CONS];
7503   DISCH_THEN (REWRITE_ALL o list);
7504   REPEAT (POP_ASSUM MP_TAC);
7505   REWRITE_ALL[partition_line];
7506   COND_CASES_TAC;
7507   POP_ASSUM (REWRITE_ALL o list);
7508   REPEAT STRIP_TAC;
7509   REWRITE_ALL[TL;];
7510   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
7511       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
7512   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
7513   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
7514   ARITH_TAC;
7515   STRIP_TAC;
7516   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7517   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7518   REPEAT STRIP_TAC;
7519   MATCH_MP_TAC ALL2_APPEND;
7520   ASM_REWRITE_TAC[];
7521   (* save *)
7522   REPEAT_N 8 (POP_ASSUM MP_TAC);
7523   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
7524   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
7525   ASM_REWRITE_TAC[];
7526   REPEAT STRIP_TAC;
7527   RESTRIP_TAC;
7528   POP_ASSUM (REWRITE_ALL o list);
7529   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7530   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7531   REWRITE_TAC[ALL2;interpsign;];
7532   REPEAT STRIP_TAC;
7533   REWRITE_ALL[interpsigns;ALL2;interpsign;];
7534   REPEAT_N 4 (POP_ASSUM MP_TAC);
7535   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
7536   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7537   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7538   REWRITE_TAC[ALL2;interpsign;];
7539   REPEAT STRIP_TAC;
7540   REWRITE_ALL[interpsigns;ALL2;interpsign;];
7541   ASM_REWRITE_TAC[];
7542   CLAIM `q x = &0`;
7543   ASM_MESON_TAC[];
7544   CLAIM `r x > &0`;
7545   ASM_MESON_TAC[];
7546   REPEAT_N 14 (POP_ASSUM MP_TAC);
7547   POP_ASSUM (MP_TAC o ISPEC `x:real`);
7548   REPEAT STRIP_TAC;
7549   POP_ASSUM (REWRITE_ALL o list);
7550   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
7551   REPEAT_N 16 (POP_ASSUM MP_TAC);
7552   POP_ASSUM (REWRITE_ALL o list o GSYM);
7553   REWRITE_TAC[real_gt;REAL_MUL_GT];
7554   REPEAT STRIP_TAC;
7555   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`;REAL_MUL_GT];
7556   ASM_REWRITE_TAC[];
7557   REPEAT STRIP_TAC;
7558   (* save *)
7559   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
7560       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
7561   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
7562   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
7563   ARITH_TAC;
7564   STRIP_TAC;
7565   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7566   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7567   REPEAT STRIP_TAC;
7568   MATCH_MP_TAC ALL2_APPEND;
7569   ASM_REWRITE_TAC[];
7570   (* save *)
7571   REWRITE_ALL[TL;ALL2;interpsign;interpsigns;APPEND];
7572   ASM_REWRITE_TAC[];
7573   REPEAT STRIP_TAC;
7574   REPEAT_N 9 (POP_ASSUM MP_TAC);
7575   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
7576   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
7577   ASM_REWRITE_TAC[];
7578   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7579   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7580   REWRITE_TAC[ALL2;interpsign;];
7581   REPEAT STRIP_TAC;
7582   REWRITE_ALL[interpsigns;ALL2;interpsign;];
7583   REPEAT_N 4 (POP_ASSUM MP_TAC);
7584   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
7585   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7586   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7587   REWRITE_TAC[ALL2;interpsign;];
7588   REPEAT STRIP_TAC;
7589   REWRITE_ALL[interpsigns;ALL2;interpsign;];
7590   ASM_REWRITE_TAC[];
7591   CLAIM `q x = &0`;
7592   ASM_MESON_TAC[];
7593   CLAIM `r x > &0`;
7594   ASM_MESON_TAC[];
7595   REPEAT_N 15 (POP_ASSUM MP_TAC);
7596   POP_ASSUM (MP_TAC o ISPEC `x:real`);
7597   REPEAT STRIP_TAC;
7598   POP_ASSUM (REWRITE_ALL o list);
7599   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
7600   REPEAT_N 16 (POP_ASSUM MP_TAC);
7601   POP_ASSUM (REWRITE_ALL o list o GSYM);
7602   REWRITE_TAC[real_gt;REAL_MUL_GT];
7603   REPEAT STRIP_TAC;
7604   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`];
7605 ]);;
7606
7607 (* }}} *)
7608
7609 let INFERPSIGN_POS_ODD_POS = prove_by_refinement(
7610   `!a n p ps q qs pts r rs s s1 s2 s3 rest sgns.
7611   interpmat pts
7612     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7613     (APPEND sgns
7614       (CONS (APPEND (CONS Unknown s1)
7615         (APPEND (CONS Zero s2) (CONS Pos s3))) rest)) ==>
7616   (LENGTH ps = LENGTH s1) ==>
7617   (LENGTH qs = LENGTH s2) ==>
7618   ODD (LENGTH sgns) ==>
7619   (!x. a pow n * p x = s x * q x + r x) ==>
7620   (a > &0) ==>
7621   interpmat pts
7622     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7623     (APPEND sgns
7624       (CONS (APPEND (CONS Pos s1)
7625         (APPEND (CONS Zero s2) (CONS Pos s3))) rest))`,
7626 (* {{{ Proof *)
7627
7628 [
7629   REPEAT STRIP_TAC;
7630   CLAIM `LENGTH (APPEND sgns (CONS
7631     (APPEND (CONS Unknown s1)
7632       (APPEND (CONS Zero s2) (CONS Pos s3))) rest)) =
7633         LENGTH (partition_line pts)`;
7634   REWRITE_ALL[interpmat];
7635   ASM_MESON_TAC[ALL2_LENGTH];
7636   REWRITE_TAC[LENGTH_APPEND;PARTITION_LINE_LENGTH;LENGTH;];
7637   STRIP_TAC;
7638   TYPE_TACL (fun l -> MP_TAC (ISPECL l SPLIT_LIST_THM)) [`(LENGTH sgns - 1) DIV 2`;`pts`];
7639   STRIP_TAC;
7640   LABEL_ALL_TAC;
7641   PROVE_ASSUM_ANTECEDENT_TAC 0;
7642   POP_ASSUM (fun x -> ALL_TAC);
7643   POP_ASSUM MP_TAC;
7644   POP_ASSUM (fun x -> ALL_TAC);
7645   POP_ASSUM (fun x -> ALL_TAC);
7646   POP_ASSUM MP_TAC;
7647   ARITH_TAC;
7648   POP_ASSUM MP_TAC THEN STRIP_TAC;
7649   ASM_REWRITE_TAC[];
7650   CLAIM `~(l2 = [])`;
7651   DISCH_THEN (REWRITE_ALL o list);
7652   POP_ASSUM MP_TAC;
7653   REWRITE_ALL[APPEND_NIL];
7654   POP_ASSUM (REWRITE_ALL o list);
7655   POP_ASSUM (fun x -> ALL_TAC);
7656   DISCH_THEN (REWRITE_ALL o list);
7657   POP_ASSUM MP_TAC;
7658   POP_ASSUM (fun x -> ALL_TAC);
7659   POP_ASSUM (fun x -> ALL_TAC);
7660   POP_ASSUM MP_TAC THEN ARITH_TAC;
7661   REWRITE_TAC[NOT_NIL];
7662   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
7663   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] INFERPSIGN_POS_ODD_POS_LEM);
7664   ASM_REWRITE_TAC[];
7665   EXISTS_TACL [`a`;`n`;`s`];
7666   (* save *)
7667   ASM_REWRITE_TAC[];
7668   STRIP_TAC;
7669   ASM_MESON_TAC[];
7670   LABEL_ALL_TAC;
7671   CLAIM `EVEN (LENGTH sgns - 1)`;
7672   ASM_MESON_TAC[EVEN_PRE;ARITH_RULE `x - 1 = PRE x`];
7673   STRIP_TAC;
7674   ASM_SIMP_TAC[DIV_EVEN];
7675   USE_THEN "Z-4" MP_TAC THEN ARITH_TAC;
7676 ]);;
7677
7678 (* }}} *)
7679
7680 let INFERPSIGN_NEG_ODD_POS_LEM = prove_by_refinement(
7681   `!a n p ps q qs r rs s x pts1 pts2  s1 s2 s3 rest sgns.
7682   interpmat (APPEND pts1 (CONS x pts2))
7683     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7684     (APPEND sgns
7685       (CONS (APPEND (CONS Unknown s1)
7686         (APPEND (CONS Zero s2) (CONS Neg s3))) rest)) ==>
7687   (LENGTH ps = LENGTH s1) ==>
7688   (LENGTH qs = LENGTH s2) ==>
7689   ODD (LENGTH sgns) ==>
7690   (LENGTH sgns = 2 * LENGTH pts1 + 1) ==>
7691   (!x. a pow n * p x = s x * q x + r x) ==>
7692   (a > &0) ==>
7693   interpmat (APPEND pts1 (CONS x pts2))
7694     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7695     (APPEND sgns
7696       (CONS (APPEND (CONS Neg s1)
7697         (APPEND (CONS Zero s2) (CONS Neg s3))) rest))`,
7698 (* {{{ Proof *)
7699 [
7700   REPEAT STRIP_TAC;
7701   CLAIM `a pow n > &0`;
7702   ASM_MESON_TAC[REAL_POW_LT;real_gt;];
7703   STRIP_TAC;
7704   REPEAT (POP_ASSUM MP_TAC);
7705   REWRITE_TAC[interpmat];
7706   REPEAT STRIP_TAC;
7707   FIRST_ASSUM MATCH_ACCEPT_TAC;
7708   CASES_ON `pts1 = []`;
7709   POP_ASSUM (REWRITE_ALL o list);
7710   REWRITE_ALL[APPEND;partition_line;];
7711   COND_CASES_TAC;
7712   CLAIM `?k. sgns = [k]`;
7713   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
7714   REWRITE_ALL[LENGTH];
7715   REPEAT_N 4 (POP_ASSUM (fun x -> ALL_TAC));
7716   POP_ASSUM MP_TAC THEN ARITH_TAC;
7717   STRIP_TAC;
7718   POP_ASSUM (REWRITE_ALL o list);
7719   POP_ASSUM (REWRITE_ALL o list);
7720   REWRITE_ALL[APPEND;partition_line;ALL2;];
7721   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
7722   ASM_REWRITE_TAC[];
7723   REWRITE_ALL[interpsigns;interpsign;ALL2;];
7724   ASM_REWRITE_TAC[];
7725   REPEAT STRIP_TAC;
7726   REPEAT_N 7 (POP_ASSUM MP_TAC);
7727   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7728   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7729   REWRITE_TAC[ALL2;interpsign;];
7730   REPEAT STRIP_TAC;
7731   POP_ASSUM (REWRITE_ALL o list);
7732   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7733   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7734   REWRITE_TAC[ALL2;interpsign;];
7735   REPEAT STRIP_TAC;
7736   CLAIM `q x = &0`;
7737   ASM_MESON_TAC[];
7738   CLAIM `r x < &0`;
7739   ASM_MESON_TAC[real_gt];
7740   REPEAT_N 5 (POP_ASSUM MP_TAC);
7741   POP_ASSUM (MP_TAC o ISPEC `x:real`);
7742   REPEAT STRIP_TAC;
7743   POP_ASSUM (REWRITE_ALL o list);
7744   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
7745   REPEAT_N 6 (POP_ASSUM MP_TAC);
7746   POP_ASSUM (REWRITE_ALL o list o GSYM);
7747   REWRITE_TAC[real_gt;REAL_MUL_GT];
7748   REPEAT STRIP_TAC;
7749   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`];
7750   ASM_REWRITE_TAC[];
7751   (* save *)
7752   POP_ASSUM (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
7753   CLAIM `?k. sgns = [k]`;
7754   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
7755   REWRITE_ALL[LENGTH];
7756   REPEAT_N 4 (POP_ASSUM (fun x -> ALL_TAC));
7757   POP_ASSUM MP_TAC THEN ARITH_TAC;
7758   STRIP_TAC;
7759   POP_ASSUM (REWRITE_ALL o list);
7760   REWRITE_ALL[APPEND;partition_line;ALL2;];
7761   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
7762   ASM_REWRITE_TAC[];
7763   REWRITE_ALL[interpsigns;interpsign;ALL2;];
7764   ASM_REWRITE_TAC[];
7765   REPEAT STRIP_TAC;
7766   REPEAT_N 8 (POP_ASSUM MP_TAC);
7767   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7768   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7769   REWRITE_TAC[ALL2;interpsign;];
7770   REPEAT STRIP_TAC;
7771   ASM_REWRITE_TAC[];
7772   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7773   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7774   REWRITE_TAC[ALL2;interpsign;];
7775   REPEAT STRIP_TAC;
7776   ASM_REWRITE_TAC[];
7777   CLAIM `q x = &0`;
7778   ASM_MESON_TAC[];
7779   CLAIM `r x < &0`;
7780   ASM_MESON_TAC[];
7781   REPEAT_N 7 (POP_ASSUM MP_TAC);
7782   POP_ASSUM (MP_TAC o ISPEC `x:real`);
7783   REPEAT STRIP_TAC;
7784   POP_ASSUM (REWRITE_ALL o list);
7785   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
7786   REPEAT_N 8 (POP_ASSUM MP_TAC);
7787   POP_ASSUM (REWRITE_ALL o list o GSYM);
7788   REWRITE_TAC[real_gt;REAL_MUL_GT];
7789   REPEAT STRIP_TAC;
7790   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`];
7791   ASM_REWRITE_TAC[];
7792   (* save *)
7793   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
7794   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
7795   REPEAT STRIP_TAC;
7796   CLAIM `(APPEND (BUTLAST (partition_line pts1))
7797      (CONS (\x'. LAST pts1 < x' /\ x' < x)
7798      (TL (partition_line (CONS x pts2))))) =
7799      (APPEND
7800       (APPEND (BUTLAST (partition_line pts1))
7801       [\x'. LAST pts1 < x' /\ x' < x])
7802      (TL (partition_line (CONS x pts2))))`;
7803   ASM_MESON_TAC[APPEND_CONS];
7804   DISCH_THEN (REWRITE_ALL o list);
7805   REPEAT (POP_ASSUM MP_TAC);
7806   REWRITE_ALL[partition_line];
7807   COND_CASES_TAC;
7808   POP_ASSUM (REWRITE_ALL o list);
7809   REPEAT STRIP_TAC;
7810   REWRITE_ALL[TL;];
7811   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
7812       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
7813   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
7814   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
7815   ARITH_TAC;
7816   STRIP_TAC;
7817   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7818   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7819   REPEAT STRIP_TAC;
7820   MATCH_MP_TAC ALL2_APPEND;
7821   ASM_REWRITE_TAC[];
7822   (* save *)
7823   REPEAT_N 8 (POP_ASSUM MP_TAC);
7824   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
7825   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
7826   ASM_REWRITE_TAC[];
7827   REPEAT STRIP_TAC;
7828   RESTRIP_TAC;
7829   POP_ASSUM (REWRITE_ALL o list);
7830   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7831   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7832   REWRITE_TAC[ALL2;interpsign;];
7833   REPEAT STRIP_TAC;
7834   REWRITE_ALL[interpsigns;ALL2;interpsign;];
7835   REPEAT_N 4 (POP_ASSUM MP_TAC);
7836   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
7837   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7838   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7839   REWRITE_TAC[ALL2;interpsign;];
7840   REPEAT STRIP_TAC;
7841   REWRITE_ALL[interpsigns;ALL2;interpsign;];
7842   ASM_REWRITE_TAC[];
7843   CLAIM `q x = &0`;
7844   ASM_MESON_TAC[];
7845   CLAIM `r x < &0`;
7846   ASM_MESON_TAC[];
7847   REPEAT_N 14 (POP_ASSUM MP_TAC);
7848   POP_ASSUM (MP_TAC o ISPEC `x:real`);
7849   REPEAT STRIP_TAC;
7850   POP_ASSUM (REWRITE_ALL o list);
7851   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
7852   REPEAT_N 16 (POP_ASSUM MP_TAC);
7853   POP_ASSUM (REWRITE_ALL o list o GSYM);
7854   REWRITE_TAC[real_gt;REAL_MUL_GT];
7855   REPEAT STRIP_TAC;
7856   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`;REAL_MUL_GT];
7857   ASM_REWRITE_TAC[];
7858   REPEAT STRIP_TAC;
7859   (* save *)
7860   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
7861       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
7862   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
7863   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
7864   ARITH_TAC;
7865   STRIP_TAC;
7866   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7867   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7868   REPEAT STRIP_TAC;
7869   MATCH_MP_TAC ALL2_APPEND;
7870   ASM_REWRITE_TAC[];
7871   (* save *)
7872   REWRITE_ALL[TL;ALL2;interpsign;interpsigns;APPEND];
7873   ASM_REWRITE_TAC[];
7874   REPEAT STRIP_TAC;
7875   REPEAT_N 9 (POP_ASSUM MP_TAC);
7876   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
7877   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
7878   ASM_REWRITE_TAC[];
7879   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7880   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7881   REWRITE_TAC[ALL2;interpsign;];
7882   REPEAT STRIP_TAC;
7883   REWRITE_ALL[interpsigns;ALL2;interpsign;];
7884   REPEAT_N 4 (POP_ASSUM MP_TAC);
7885   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
7886   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
7887   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
7888   REWRITE_TAC[ALL2;interpsign;];
7889   REPEAT STRIP_TAC;
7890   REWRITE_ALL[interpsigns;ALL2;interpsign;];
7891   ASM_REWRITE_TAC[];
7892   CLAIM `q x = &0`;
7893   ASM_MESON_TAC[];
7894   CLAIM `r x < &0`;
7895   ASM_MESON_TAC[];
7896   REPEAT_N 15 (POP_ASSUM MP_TAC);
7897   POP_ASSUM (MP_TAC o ISPEC `x:real`);
7898   REPEAT STRIP_TAC;
7899   POP_ASSUM (REWRITE_ALL o list);
7900   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
7901   REPEAT_N 16 (POP_ASSUM MP_TAC);
7902   POP_ASSUM (REWRITE_ALL o list o GSYM);
7903   REWRITE_TAC[real_gt;REAL_MUL_GT];
7904   REPEAT STRIP_TAC;
7905   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`];
7906 ]);;
7907
7908 (* }}} *)
7909
7910 let INFERPSIGN_NEG_ODD_POS = prove_by_refinement(
7911   `!a n p ps q qs pts r rs s s1 s2 s3 rest sgns.
7912   interpmat pts
7913     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7914     (APPEND sgns
7915       (CONS (APPEND (CONS Unknown s1)
7916         (APPEND (CONS Zero s2) (CONS Neg s3))) rest)) ==>
7917   (LENGTH ps = LENGTH s1) ==>
7918   (LENGTH qs = LENGTH s2) ==>
7919   ODD (LENGTH sgns) ==>
7920   (!x. a pow n * p x = s x * q x + r x) ==>
7921   (a > &0) ==>
7922   interpmat pts
7923     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7924     (APPEND sgns
7925       (CONS (APPEND (CONS Neg s1)
7926         (APPEND (CONS Zero s2) (CONS Neg s3))) rest))`,
7927 (* {{{ Proof *)
7928
7929 [
7930   REPEAT STRIP_TAC;
7931   CLAIM `LENGTH (APPEND sgns (CONS
7932     (APPEND (CONS Unknown s1)
7933       (APPEND (CONS Zero s2) (CONS Neg s3))) rest)) =
7934         LENGTH (partition_line pts)`;
7935   REWRITE_ALL[interpmat];
7936   ASM_MESON_TAC[ALL2_LENGTH];
7937   REWRITE_TAC[LENGTH_APPEND;PARTITION_LINE_LENGTH;LENGTH;];
7938   STRIP_TAC;
7939   TYPE_TACL (fun l -> MP_TAC (ISPECL l SPLIT_LIST_THM)) [`(LENGTH sgns - 1) DIV 2`;`pts`];
7940   STRIP_TAC;
7941   LABEL_ALL_TAC;
7942   PROVE_ASSUM_ANTECEDENT_TAC 0;
7943   POP_ASSUM (fun x -> ALL_TAC);
7944   POP_ASSUM MP_TAC;
7945   POP_ASSUM (fun x -> ALL_TAC);
7946   POP_ASSUM (fun x -> ALL_TAC);
7947   POP_ASSUM MP_TAC;
7948   ARITH_TAC;
7949   POP_ASSUM MP_TAC THEN STRIP_TAC;
7950   ASM_REWRITE_TAC[];
7951   CLAIM `~(l2 = [])`;
7952   DISCH_THEN (REWRITE_ALL o list);
7953   POP_ASSUM MP_TAC;
7954   REWRITE_ALL[APPEND_NIL];
7955   POP_ASSUM (REWRITE_ALL o list);
7956   POP_ASSUM (fun x -> ALL_TAC);
7957   DISCH_THEN (REWRITE_ALL o list);
7958   POP_ASSUM MP_TAC;
7959   POP_ASSUM (fun x -> ALL_TAC);
7960   POP_ASSUM (fun x -> ALL_TAC);
7961   POP_ASSUM MP_TAC THEN ARITH_TAC;
7962   REWRITE_TAC[NOT_NIL];
7963   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
7964   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] INFERPSIGN_NEG_ODD_POS_LEM);
7965   ASM_REWRITE_TAC[];
7966   EXISTS_TACL [`a`;`n`;`s`];
7967   (* save *)
7968   ASM_REWRITE_TAC[];
7969   STRIP_TAC;
7970   ASM_MESON_TAC[];
7971   LABEL_ALL_TAC;
7972   CLAIM `EVEN (LENGTH sgns - 1)`;
7973   ASM_MESON_TAC[EVEN_PRE;ARITH_RULE `x - 1 = PRE x`];
7974   STRIP_TAC;
7975   ASM_SIMP_TAC[DIV_EVEN];
7976   USE_THEN "Z-4" MP_TAC THEN ARITH_TAC;
7977 ]);;
7978
7979 (* }}} *)
7980
7981 let INFERPSIGN_ZERO_ODD_POS_LEM = prove_by_refinement(
7982   `!a n p ps q qs r rs s x pts1 pts2  s1 s2 s3 rest sgns.
7983   interpmat (APPEND pts1 (CONS x pts2))
7984     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7985     (APPEND sgns
7986       (CONS (APPEND (CONS Unknown s1)
7987         (APPEND (CONS Zero s2) (CONS Zero s3))) rest)) ==>
7988   (LENGTH ps = LENGTH s1) ==>
7989   (LENGTH qs = LENGTH s2) ==>
7990   ODD (LENGTH sgns) ==>
7991   (LENGTH sgns = 2 * LENGTH pts1 + 1) ==>
7992   (!x. a pow n * p x = s x * q x + r x) ==>
7993   (a > &0) ==>
7994   interpmat (APPEND pts1 (CONS x pts2))
7995     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
7996     (APPEND sgns
7997       (CONS (APPEND (CONS Zero s1)
7998         (APPEND (CONS Zero s2) (CONS Zero s3))) rest))`,
7999 (* {{{ Proof *)
8000 [
8001   REPEAT STRIP_TAC;
8002   CLAIM `a pow n > &0`;
8003   ASM_MESON_TAC[REAL_POW_LT;real_gt;];
8004   STRIP_TAC;
8005   REPEAT (POP_ASSUM MP_TAC);
8006   REWRITE_TAC[interpmat];
8007   REPEAT STRIP_TAC;
8008   FIRST_ASSUM MATCH_ACCEPT_TAC;
8009   CASES_ON `pts1 = []`;
8010   POP_ASSUM (REWRITE_ALL o list);
8011   REWRITE_ALL[APPEND;partition_line;];
8012   COND_CASES_TAC;
8013   CLAIM `?k. sgns = [k]`;
8014   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
8015   REWRITE_ALL[LENGTH];
8016   REPEAT_N 4 (POP_ASSUM (fun x -> ALL_TAC));
8017   POP_ASSUM MP_TAC THEN ARITH_TAC;
8018   STRIP_TAC;
8019   POP_ASSUM (REWRITE_ALL o list);
8020   POP_ASSUM (REWRITE_ALL o list);
8021   REWRITE_ALL[APPEND;partition_line;ALL2;];
8022   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
8023   ASM_REWRITE_TAC[];
8024   REWRITE_ALL[interpsigns;interpsign;ALL2;];
8025   ASM_REWRITE_TAC[];
8026   REPEAT STRIP_TAC;
8027   REPEAT_N 7 (POP_ASSUM MP_TAC);
8028   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
8029   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
8030   REWRITE_TAC[ALL2;interpsign;];
8031   REPEAT STRIP_TAC;
8032   POP_ASSUM (REWRITE_ALL o list);
8033   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
8034   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
8035   REWRITE_TAC[ALL2;interpsign;];
8036   REPEAT STRIP_TAC;
8037   CLAIM `q x = &0`;
8038   ASM_MESON_TAC[];
8039   CLAIM `r x = &0`;
8040   ASM_MESON_TAC[real_gt];
8041   REPEAT_N 5 (POP_ASSUM MP_TAC);
8042   POP_ASSUM (MP_TAC o ISPEC `x:real`);
8043   REPEAT STRIP_TAC;
8044   POP_ASSUM (REWRITE_ALL o list);
8045   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
8046   REPEAT_N 6 (POP_ASSUM MP_TAC);
8047   POP_ASSUM (REWRITE_ALL o list o GSYM);
8048   REWRITE_TAC[real_gt;REAL_MUL_GT];
8049   REPEAT STRIP_TAC;
8050   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`];
8051   ASM_REWRITE_TAC[];
8052   (* save *)
8053   POP_ASSUM (fun x -> REWRITE_ASSUMS[x] THEN ASSUME_TAC x);
8054   CLAIM `?k. sgns = [k]`;
8055   MATCH_EQ_MP_TAC (GSYM LENGTH_1);
8056   REWRITE_ALL[LENGTH];
8057   REPEAT_N 4 (POP_ASSUM (fun x -> ALL_TAC));
8058   POP_ASSUM MP_TAC THEN ARITH_TAC;
8059   STRIP_TAC;
8060   POP_ASSUM (REWRITE_ALL o list);
8061   REWRITE_ALL[APPEND;partition_line;ALL2;];
8062   REPEAT (POP_ASSUM MP_TAC) THEN REPEAT STRIP_TAC;
8063   ASM_REWRITE_TAC[];
8064   REWRITE_ALL[interpsigns;interpsign;ALL2;];
8065   ASM_REWRITE_TAC[];
8066   REPEAT STRIP_TAC;
8067   REPEAT_N 8 (POP_ASSUM MP_TAC);
8068   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
8069   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
8070   REWRITE_TAC[ALL2;interpsign;];
8071   REPEAT STRIP_TAC;
8072   ASM_REWRITE_TAC[];
8073   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
8074   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
8075   REWRITE_TAC[ALL2;interpsign;];
8076   REPEAT STRIP_TAC;
8077   ASM_REWRITE_TAC[];
8078   CLAIM `q x = &0`;
8079   ASM_MESON_TAC[];
8080   CLAIM `r x = &0`;
8081   ASM_MESON_TAC[];
8082   REPEAT_N 7 (POP_ASSUM MP_TAC);
8083   POP_ASSUM (MP_TAC o ISPEC `x:real`);
8084   REPEAT STRIP_TAC;
8085   POP_ASSUM (REWRITE_ALL o list);
8086   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
8087   REPEAT_N 8 (POP_ASSUM MP_TAC);
8088   POP_ASSUM (REWRITE_ALL o list o GSYM);
8089   REWRITE_TAC[real_gt;REAL_MUL_GT];
8090   REPEAT STRIP_TAC;
8091   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`];
8092   ASM_REWRITE_TAC[];
8093   (* save *)
8094   POP_ASSUM (fun x -> REPEAT (POP_ASSUM MP_TAC) THEN ASSUME_TAC x);
8095   ASM_SIMP_TAC[PARTITION_LINE_APPEND];
8096   REPEAT STRIP_TAC;
8097   CLAIM `(APPEND (BUTLAST (partition_line pts1))
8098      (CONS (\x'. LAST pts1 < x' /\ x' < x)
8099      (TL (partition_line (CONS x pts2))))) =
8100      (APPEND
8101       (APPEND (BUTLAST (partition_line pts1))
8102       [\x'. LAST pts1 < x' /\ x' < x])
8103      (TL (partition_line (CONS x pts2))))`;
8104   ASM_MESON_TAC[APPEND_CONS];
8105   DISCH_THEN (REWRITE_ALL o list);
8106   REPEAT (POP_ASSUM MP_TAC);
8107   REWRITE_ALL[partition_line];
8108   COND_CASES_TAC;
8109   POP_ASSUM (REWRITE_ALL o list);
8110   REPEAT STRIP_TAC;
8111   REWRITE_ALL[TL;];
8112   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
8113       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
8114   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
8115   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
8116   ARITH_TAC;
8117   STRIP_TAC;
8118   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
8119   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
8120   REPEAT STRIP_TAC;
8121   MATCH_MP_TAC ALL2_APPEND;
8122   ASM_REWRITE_TAC[];
8123   (* save *)
8124   REPEAT_N 8 (POP_ASSUM MP_TAC);
8125   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
8126   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
8127   ASM_REWRITE_TAC[];
8128   REPEAT STRIP_TAC;
8129   RESTRIP_TAC;
8130   POP_ASSUM (REWRITE_ALL o list);
8131   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
8132   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
8133   REWRITE_TAC[ALL2;interpsign;];
8134   REPEAT STRIP_TAC;
8135   REWRITE_ALL[interpsigns;ALL2;interpsign;];
8136   REPEAT_N 4 (POP_ASSUM MP_TAC);
8137   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
8138   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
8139   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
8140   REWRITE_TAC[ALL2;interpsign;];
8141   REPEAT STRIP_TAC;
8142   REWRITE_ALL[interpsigns;ALL2;interpsign;];
8143   ASM_REWRITE_TAC[];
8144   CLAIM `q x = &0`;
8145   ASM_MESON_TAC[];
8146   CLAIM `r x = &0`;
8147   ASM_MESON_TAC[];
8148   REPEAT_N 14 (POP_ASSUM MP_TAC);
8149   POP_ASSUM (MP_TAC o ISPEC `x:real`);
8150   REPEAT STRIP_TAC;
8151   POP_ASSUM (REWRITE_ALL o list);
8152   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
8153   REPEAT_N 16 (POP_ASSUM MP_TAC);
8154   POP_ASSUM (REWRITE_ALL o list o GSYM);
8155   REWRITE_TAC[real_gt;REAL_MUL_GT];
8156   REPEAT STRIP_TAC;
8157   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`;REAL_MUL_GT;REAL_LT_IMP_NZ];
8158   ASM_REWRITE_TAC[];
8159   REPEAT STRIP_TAC;
8160   (* save *)
8161   CLAIM `LENGTH (APPEND (BUTLAST (partition_line pts1))
8162       [\x'. LAST pts1 < x' /\ x' < x]) = LENGTH sgns`;
8163   FIRST_ASSUM (MP_TAC o MATCH_MP  ALL2_LENGTH);
8164   ASM_SIMP_TAC[LENGTH_APPEND;PARTITION_LINE_NOT_NIL;BUTLAST_LENGTH;PARTITION_LINE_LENGTH;LENGTH;];
8165   ARITH_TAC;
8166   STRIP_TAC;
8167   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
8168   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
8169   REPEAT STRIP_TAC;
8170   MATCH_MP_TAC ALL2_APPEND;
8171   ASM_REWRITE_TAC[];
8172   (* save *)
8173   REWRITE_ALL[TL;ALL2;interpsign;interpsigns;APPEND];
8174   ASM_REWRITE_TAC[];
8175   REPEAT STRIP_TAC;
8176   REPEAT_N 9 (POP_ASSUM MP_TAC);
8177   POP_ASSUM (fun x -> POP_ASSUM (fun y -> REPEAT STRIP_TAC THEN ASSUME_TAC x THEN ASSUME_TAC y));
8178   REWRITE_ALL[ALL2;interpsigns;APPEND;interpsign;];
8179   ASM_REWRITE_TAC[];
8180   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
8181   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
8182   REWRITE_TAC[ALL2;interpsign;];
8183   REPEAT STRIP_TAC;
8184   REWRITE_ALL[interpsigns;ALL2;interpsign;];
8185   REPEAT_N 4 (POP_ASSUM MP_TAC);
8186   POP_ASSUM (fun x -> REPEAT STRIP_TAC THEN ASSUME_TAC x);
8187   FIRST_ASSUM (MP_TAC o MATCH_MP ALL2_APPEND_LENGTH);
8188   FIRST_ASSUM (fun x -> DISCH_THEN (fun y -> MP_TAC (MATCH_MP y x)));
8189   REWRITE_TAC[ALL2;interpsign;];
8190   REPEAT STRIP_TAC;
8191   REWRITE_ALL[interpsigns;ALL2;interpsign;];
8192   ASM_REWRITE_TAC[];
8193   CLAIM `q x = &0`;
8194   ASM_MESON_TAC[];
8195   CLAIM `r x = &0`;
8196   ASM_MESON_TAC[];
8197   REPEAT_N 15 (POP_ASSUM MP_TAC);
8198   POP_ASSUM (MP_TAC o ISPEC `x:real`);
8199   REPEAT STRIP_TAC;
8200   POP_ASSUM (REWRITE_ALL o list);
8201   REWRITE_ALL[REAL_MUL_RZERO;REAL_ADD_LID;];
8202   REPEAT_N 16 (POP_ASSUM MP_TAC);
8203   POP_ASSUM (REWRITE_ALL o list o GSYM);
8204   REWRITE_TAC[real_gt;REAL_MUL_GT];
8205   REPEAT STRIP_TAC;
8206   ASM_MESON_TAC[REAL_ARITH `~(x < y /\ y < x)`;REAL_MUL_LT;REAL_ENTIRE;ARITH_RULE `x < y ==> ~(x = y)`;REAL_MUL_GT;REAL_LT_IMP_NZ];
8207 ]);;
8208
8209 (* }}} *)
8210
8211 let INFERPSIGN_ZERO_ODD_POS = prove_by_refinement(
8212   `!a n p ps q qs pts r rs s s1 s2 s3 rest sgns.
8213   interpmat pts
8214     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
8215     (APPEND sgns
8216       (CONS (APPEND (CONS Unknown s1)
8217         (APPEND (CONS Zero s2) (CONS Zero s3))) rest)) ==>
8218   (LENGTH ps = LENGTH s1) ==>
8219   (LENGTH qs = LENGTH s2) ==>
8220   ODD (LENGTH sgns) ==>
8221   (!x. a pow n * p x = s x * q x + r x) ==>
8222   (a > &0) ==>
8223   interpmat pts
8224     (APPEND (CONS p ps) (APPEND (CONS q qs) (CONS r rs)))
8225     (APPEND sgns
8226       (CONS (APPEND (CONS Zero s1)
8227         (APPEND (CONS Zero s2) (CONS Zero s3))) rest))`,
8228 (* {{{ Proof *)
8229 [
8230   REPEAT STRIP_TAC;
8231   CLAIM `LENGTH (APPEND sgns (CONS
8232     (APPEND (CONS Unknown s1)
8233       (APPEND (CONS Zero s2) (CONS Zero s3))) rest)) =
8234         LENGTH (partition_line pts)`;
8235   REWRITE_ALL[interpmat];
8236   ASM_MESON_TAC[ALL2_LENGTH];
8237   REWRITE_TAC[LENGTH_APPEND;PARTITION_LINE_LENGTH;LENGTH;];
8238   STRIP_TAC;
8239   TYPE_TACL (fun l -> MP_TAC (ISPECL l SPLIT_LIST_THM)) [`(LENGTH sgns - 1) DIV 2`;`pts`];
8240   STRIP_TAC;
8241   LABEL_ALL_TAC;
8242   PROVE_ASSUM_ANTECEDENT_TAC 0;
8243   POP_ASSUM (fun x -> ALL_TAC);
8244   POP_ASSUM MP_TAC;
8245   POP_ASSUM (fun x -> ALL_TAC);
8246   POP_ASSUM (fun x -> ALL_TAC);
8247   POP_ASSUM MP_TAC;
8248   ARITH_TAC;
8249   POP_ASSUM MP_TAC THEN STRIP_TAC;
8250   ASM_REWRITE_TAC[];
8251   CLAIM `~(l2 = [])`;
8252   DISCH_THEN (REWRITE_ALL o list);
8253   POP_ASSUM MP_TAC;
8254   REWRITE_ALL[APPEND_NIL];
8255   POP_ASSUM (REWRITE_ALL o list);
8256   POP_ASSUM (fun x -> ALL_TAC);
8257   DISCH_THEN (REWRITE_ALL o list);
8258   POP_ASSUM MP_TAC;
8259   POP_ASSUM (fun x -> ALL_TAC);
8260   POP_ASSUM (fun x -> ALL_TAC);
8261   POP_ASSUM MP_TAC THEN ARITH_TAC;
8262   REWRITE_TAC[NOT_NIL];
8263   STRIP_TAC THEN POP_ASSUM (REWRITE_ALL o list);
8264   MATCH_MP_TAC (REWRITE_RULE[IMP_AND_THM] INFERPSIGN_ZERO_ODD_POS_LEM);
8265   ASM_REWRITE_TAC[];
8266   EXISTS_TACL [`a`;`n`;`s`];
8267   (* save *)
8268   ASM_REWRITE_TAC[];
8269   STRIP_TAC;
8270   ASM_MESON_TAC[];
8271   LABEL_ALL_TAC;
8272   CLAIM `EVEN (LENGTH sgns - 1)`;
8273   ASM_MESON_TAC[EVEN_PRE;ARITH_RULE `x - 1 = PRE x`];
8274   STRIP_TAC;
8275   ASM_SIMP_TAC[DIV_EVEN];
8276   USE_THEN "Z-4" MP_TAC THEN ARITH_TAC;
8277 ]);;
8278
8279 (* }}} *)