2 let aacons_tm = `CONS:A -> A list -> A list` ;;
4 let h::rest = dest_list tm in
7 let thm2 = REFL (mk_list(rest,ty)) in
8 let cs = inst [ty,aty] aacons_tm in
9 MK_COMB ((AP_TERM cs thm),thm2);;
13 let h::t = dest_list tm in
14 let lty = type_of h in
15 let cs = inst [lty,aty] aacons_tm in
16 MK_COMB ((AP_TERM cs (REFL h)), (LIST_CONV conv (mk_list(t,lty))))
17 (* with _ -> failwith "TL_CONV" *)
19 let rec EL_CONV conv i tm =
20 if i = 0 then HD_CONV conv tm
22 let h::t = dest_list tm in
23 let lty = type_of h in
24 let cs = inst [lty,aty] aacons_tm in
25 MK_COMB ((AP_TERM cs (REFL h)), (EL_CONV conv (i - 1) (mk_list(t,lty))))
30 let conv = (REWRITE_CONV[ARITH_RULE `x + x = &2 * x`])
31 let tm = `[&5 + &5; &6 + &6; &7 + &7]`
34 HD_CONV(TL_CONV conv) tm
42 let NOT_CONS = prove_by_refinement(
43 `!l. (~ ?(h:A) t. (l = CONS h t)) ==> (l = [])`,
47 MESON_TAC[list_CASES];
52 let REMOVE = new_recursive_definition list_RECURSION
53 `(REMOVE x [] = []) /\
54 (REMOVE x (CONS (h:A) t) =
55 let rest = REMOVE x t in
56 if x = h then rest else CONS h rest)`;;
58 let CHOP_LIST = new_recursive_definition num_RECURSION
59 `(CHOP_LIST 0 l = [],l) /\
60 (CHOP_LIST (SUC n) l =
61 let a,b = CHOP_LIST n (TL l) in
68 let REM_FALSE = prove_by_refinement(
69 `!x l. ~(MEM x (REMOVE x l))`,
74 ASM_MESON_TAC[MEM;REM_NIL];
77 ASM_REWRITE_TAC[REMOVE;LET_DEF;LET_END_DEF];
79 ASM_REWRITE_TAC[REMOVE;LET_DEF;LET_END_DEF];
84 let MEM_REMOVE = prove_by_refinement(
85 `!x y z l. MEM x (REMOVE y l) ==> MEM x (REMOVE y (CONS z l))`,
90 ASM_REWRITE_TAC[REMOVE;LET_DEF;LET_END_DEF];
91 ASM_REWRITE_TAC[REMOVE;LET_DEF;LET_END_DEF];
96 let REM_NEQ = prove_by_refinement(
97 `!x x1 l. MEM x l /\ ~(x = x1) ==> MEM x (REMOVE x1 l)`,
100 STRIP_TAC THEN STRIP_TAC;
104 POP_ASSUM SUBST1_TAC;
106 ASM_REWRITE_TAC[REMOVE;LET_DEF;LET_END_DEF;COND_CLAUSES;MEM];
111 CLAIM `MEM x (REMOVE x1 t)`;
114 MATCH_MP_TAC MEM_REMOVE;
115 FIRST_ASSUM MATCH_ACCEPT_TAC;
120 let LAST_SING = prove_by_refinement(
130 let LAST_CONS = prove_by_refinement(
131 `!h t. ~(t = []) ==> (LAST (CONS h t) = LAST t)`,
139 let LAST_CONS_CONS = prove_by_refinement(
140 `!h1 h2 t. ~(t = []) ==> (LAST (CONS h1 (CONS h2 t)) = LAST (CONS h1 t))`,
143 REWRITE_TAC[LAST;NOT_CONS_NIL];
144 MESON_TAC[LAST;NOT_CONS_NIL;COND_CLAUSES];
148 let HD_APPEND = prove_by_refinement(
149 `!h t l. HD (APPEND (CONS h t) l) = h`,
152 ASM_MESON_TAC[HD;APPEND];
156 let LENGTH_0 = prove_by_refinement(
157 `!l. (LENGTH l = 0) <=> (l = [])`,
162 ASM_MESON_TAC[LENGTH;NOT_CONS_NIL;ARITH_RULE `~(0 = SUC n)`];
166 let LENGTH_1 = prove_by_refinement(
167 `!l. (LENGTH l = 1) <=> ?x. l = [x]`,
172 MESON_TAC[LENGTH;ARITH_RULE `~(1 = 0)`];
173 MESON_TAC[NOT_CONS_NIL];
175 REWRITE_TAC[LENGTH;ARITH_RULE `~(0 = 1)`];
178 CLAIM `LENGTH t = 0`;
179 POP_ASSUM MP_TAC THEN ARITH_TAC;
182 ASM_MESON_TAC[LENGTH_0];
187 ASM_MESON_TAC[LENGTH;ONE];
191 let LIST_TRI = prove_by_refinement(
192 `!p. (p = []) \/ (?x. p = [x:A]) \/ (?x y t. p = CONS x (CONS y t))`,
196 DISJ_CASES_TAC (ISPEC `p:A list` list_CASES);
198 POP_ASSUM MP_TAC THEN STRIP_TAC;
199 DISJ_CASES_TAC (ISPEC `t:A list` list_CASES);
205 let LENGTH_PAIR = prove_by_refinement(
206 `!p. (LENGTH p = 2) <=> ?h t. p = [h:A; t]`,
209 STRIP_TAC THEN EQ_TAC;
211 MP_TAC (ISPEC `p:A list` list_CASES);
213 ASM_MESON_TAC[LENGTH_0;ARITH_RULE `~(2 = 0)`];
214 MP_TAC (ISPEC `t:A list` list_CASES);
216 ASM_MESON_TAC[LENGTH_1;ARITH_RULE `~(1 = 2)`];
217 MP_TAC (ISPEC `t':A list` list_CASES);
222 CLAIM `p = CONS h (CONS h' (CONS h'' t''))`;
225 CLAIM `2 < LENGTH p`;
226 POP_ASSUM SUBST1_TAC;
229 ASM_MESON_TAC[LT_REFL];
231 ASM_REWRITE_TAC[LENGTH];
236 let LENGTH_SING = prove_by_refinement(
237 `!p. (LENGTH p = 1) <=> ?h. p = [h:A]`,
240 STRIP_TAC THEN EQ_TAC;
242 MP_TAC (ISPEC `p:A list` list_CASES);
244 ASM_MESON_TAC[LENGTH_0;ARITH_RULE `~(1 = 0)`];
245 MP_TAC (ISPEC `t:A list` list_CASES);
249 CLAIM `p = CONS h (CONS h' t')`;
252 CLAIM `1 < LENGTH p`;
253 POP_ASSUM SUBST1_TAC;
259 ASM_REWRITE_TAC[LENGTH;];
264 let TL_NIL = prove_by_refinement(
265 `!l. ~(l = []) ==> ((TL l = []) <=> ?x. l = [x])`,
268 REPEAT STRIP_TAC THEN EQ_TAC;
269 CLAIM `?h t. l = CONS h t`;
270 ASM_MESON_TAC[list_CASES];
273 ASM_MESON_TAC !LIST_REWRITES;
274 ASM_MESON_TAC !LIST_REWRITES;
278 let LAST_TL = prove_by_refinement(
279 `!l. ~(l = []) /\ ~(TL l = []) ==> (LAST (TL l) = LAST l)`,
284 REWRITE_TAC[TL;LAST];
285 ASM_MESON_TAC[NOT_CONS_NIL];
289 let LENGTH_TL = prove_by_refinement(
290 `!l. ~(l = []) /\ ~(TL l = []) ==> (LENGTH (TL l) = PRE(LENGTH l))`,
301 let LENGTH_NZ = prove_by_refinement(
302 `!p. 0 < LENGTH p <=> ~(p = [])`,
307 ASM_MESON_TAC[LENGTH;NOT_CONS_NIL;LT_REFL];
308 REWRITE_TAC[LENGTH;NOT_CONS_NIL;LT_REFL;NOT_NIL];
309 STRIP_TAC THEN ASM_REWRITE_TAC[];