1 needs "../formal_lp/arith/nat.hl";;
10 let MY_PROVE_HYP hyp th = EQ_MP (DEDUCT_ANTISYM_RULE hyp th) hyp;;
11 let MY_RULE = UNDISCH_ALL o PURE_REWRITE_RULE[GSYM IMP_IMP] o SPEC_ALL;;
12 let MY_RULE_NUM = UNDISCH_ALL o NUMERALS_TO_NUM o PURE_REWRITE_RULE[GSYM IMP_IMP] o SPEC_ALL;;
17 (******************************)
21 let HD_A_CONS = prove(`HD (CONS (h:A) t) = h`, REWRITE_TAC[HD]);;
23 (* Takes a term `[a;...]` and returns the theorem |- HD [a;...] = a *)
25 let ltm, t_tm = dest_comb list_tm in
26 let h_tm = rand ltm in
27 let list_ty = type_of t_tm and
29 let h_var = mk_var("h", ty) and
30 t_var = mk_var("t", list_ty) in
31 (INST[h_tm, h_var; t_tm, t_var] o INST_TYPE[ty, aty]) HD_A_CONS;;
33 (* Takes a term `HD [a;...]` and returns the theorem |- HD [a;...] = a *)
35 if (fst o dest_const o rator) hd_tm <> "HD" then failwith "hd_conv"
36 else eval_hd (rand hd_tm);;
40 let tm = `HD [1;2;3;4]`;;
43 test 1000 (REWRITE_CONV[HD]) tm;;
45 test 1000 hd_conv tm;;
46 let tm = `[1;2;3;4]`;;
48 test 1000 eval_hd tm;;
52 (*********************************)
55 let EL_0' = (MY_RULE_NUM o prove)(`EL 0 (CONS (h:A) t) = h`, REWRITE_TAC[EL; HD]);;
56 let EL_n' = (MY_RULE_NUM o prove)(`0 < n /\ PRE n = m ==> EL n (CONS (h:A) t) = EL m t`,
57 STRIP_TAC THEN SUBGOAL_THEN `n = SUC m` ASSUME_TAC THENL
58 [ REPEAT (POP_ASSUM MP_TAC) THEN ARITH_TAC; ALL_TAC ] THEN ASM_REWRITE_TAC[EL; TL]);;
61 let zero_const = `_0` and
64 let m_var_num = `m:num` and
68 (* Takes a raw numeral term and a list term and returns the theorem |- EL n [...] = x *)
69 let eval_el n_tm list_tm =
70 let list_ty = type_of list_tm in
71 let ty = (hd o snd o dest_type) list_ty in
72 let inst_t = INST_TYPE[ty, aty] in
73 let el_0, el_n = inst_t EL_0', inst_t EL_n' in
74 let h_var, t_var = mk_var("h", ty), mk_var("t", list_ty) in
76 let rec el_conv_raw = fun n_tm list_tm ->
77 let h_tm, t_tm = dest_cons list_tm in
78 let inst0 = INST[h_tm, h_var; t_tm, t_var] in
79 if n_tm = zero_const then
82 let n_gt0 = (EQT_ELIM o raw_gt0_hash_conv) n_tm in
83 let pre_n = raw_pre_hash_conv (mk_comb (pre_const, n_tm)) in
84 let m_tm = (rand o concl) pre_n in
85 let th0 = (MY_PROVE_HYP pre_n o MY_PROVE_HYP n_gt0 o
86 INST[n_tm, n_var_num; m_tm, m_var_num] o inst0) el_n in
87 let th1 = el_conv_raw m_tm t_tm in
89 el_conv_raw n_tm list_tm;;
93 (* Takes a term `EL n [...]` and returns the theorem |- EL n [...] = x *)
94 (* Note: n must be a raw numeral term Dx (Dy ... _0) *)
96 let ltm, list_tm = dest_comb el_tm in
97 let el, n_tm = dest_comb ltm in
98 if (fst o dest_const) el <> "EL" then failwith "el_conv"
99 else eval_el n_tm list_tm;;
104 list_tm = `[1; 2; 3; 4; 5]`;;
106 eval_el n0_tm list_tm;;
108 test 10000 (eval_el n0_tm) list_tm;;
110 eval_el n_tm list_tm;;
112 test 10000 (eval_el n_tm) list_tm;;
114 let tm = mk_icomb (mk_comb (`EL`, n_tm), list_tm);;
120 (*******************************)
122 (* FST, SND conversions *)
124 let FST' = ISPECL[`x:A`; `y:B`] FST;;
125 let SND' = ISPECL[`x:A`; `y:B`] SND;;
129 let x_tm, y_tm = dest_pair (rand tm) in
130 let x_ty, y_ty = type_of x_tm, type_of y_tm in
131 let x_var, y_var = mk_var("x", x_ty), mk_var("y", y_ty) in
132 (INST[x_tm, x_var; y_tm, y_var] o INST_TYPE[x_ty, aty; y_ty, bty]) FST';;
135 let x_tm, y_tm = dest_pair (rand tm) in
136 let x_ty, y_ty = type_of x_tm, type_of y_tm in
137 let x_var, y_var = mk_var("x", x_ty), mk_var("y", y_ty) in
138 (INST[x_tm, x_var; y_tm, y_var] o INST_TYPE[x_ty, aty; y_ty, bty]) SND';;
142 let tm = `FST (1,2)`;;
146 test 10000 (REWRITE_CONV[]) tm;;
148 test 10000 fst_conv tm;;
152 (******************************)
154 (* LENGTH conversions *)
156 let LENGTH_0' = (MY_RULE_NUM o prove) (`LENGTH ([]:(A)list) = 0`, REWRITE_TAC[LENGTH]) and
157 LENGTH_CONS' = prove(`LENGTH (CONS (h:A) t) = SUC (LENGTH t)`, REWRITE_TAC[LENGTH]);;
159 let suc_const = `SUC`;;
161 (* Takes a term `[...]` and returns the theorem |- LENGTH [...] = n *)
162 let eval_length list_tm =
163 let list_ty = type_of list_tm in
164 let ty = (hd o snd o dest_type) list_ty in
165 let inst_t = INST_TYPE[ty, aty] in
166 let length_empty, length_cons = inst_t LENGTH_0', inst_t LENGTH_CONS' in
167 let h_var, t_var = mk_var("h", ty), mk_var("t", list_ty) in
169 let rec length_conv_raw = fun list_tm ->
170 if (is_comb list_tm) then
171 let ltm, t_tm = dest_comb list_tm in
172 let h_tm = rand ltm in
173 let th0 = INST[h_tm, h_var; t_tm, t_var] length_cons in
174 let th1' = length_conv_raw t_tm in
175 let th1 = AP_TERM suc_const th1' in
176 let th2 = raw_suc_conv_hash (rand(concl th1)) in
177 TRANS (TRANS th0 th1) th2
180 length_conv_raw list_tm;;
183 (* Takes a term `LENGTH [...]` and returns the theorem |- LENGTH [...] = n *)
184 let length_conv length_tm =
185 if (fst o dest_const o rator) length_tm <> "LENGTH" then failwith "length_conv"
186 else eval_length (rand length_tm);;
190 let tm = `LENGTH [&1;&4;&4;&6;&7 * &8]`;;
192 test 1000 (REWRITE_CONV[LENGTH; ARITH_SUC]) tm;; (* 0.792 *)
193 test 1000 length_conv tm;; (* 0.076 *)
200 let ZIP_0' = prove(`ZIP ([]:(A)list) ([]:(B)list) = []`, REWRITE_TAC[ZIP]) and
201 ZIP_CONS' = prove(`ZIP (CONS (h1:A) t1) (CONS (h2:B) t2) = CONS (h1, h2) (ZIP t1 t2)`,
204 let eval_zip list1_tm list2_tm =
205 let list1_ty = type_of list1_tm and
206 list2_ty = type_of list2_tm in
207 let ty1 = (hd o snd o dest_type) list1_ty and
208 ty2 = (hd o snd o dest_type) list2_ty in
209 let inst_t = INST_TYPE[ty1, aty; ty2, bty] in
210 let zip0, zip_cons = inst_t ZIP_0', inst_t ZIP_CONS' in
211 let h1_var, t1_var = mk_var("h1", ty1), mk_var("t1", list1_ty) and
212 h2_var, t2_var = mk_var("h2", ty2), mk_var("t2", list2_ty) in
214 let rec zip_conv_rec = fun list1_tm list2_tm ->
215 if (is_comb list1_tm) then
216 let ltm1, t1_tm = dest_comb list1_tm and
217 ltm2, t2_tm = dest_comb list2_tm in
218 let h1_tm, h2_tm = rand ltm1, rand ltm2 in
219 let th0 = INST[h1_tm, h1_var; t1_tm, t1_var; h2_tm, h2_var; t2_tm, t2_var] zip_cons in
220 let cons_tm = (rator o rand o concl) th0 in
221 let th1' = zip_conv_rec t1_tm t2_tm in
222 let th1 = AP_TERM cons_tm th1' in
226 zip_conv_rec list1_tm list2_tm;;
233 let ALL_0' = prove(`ALL P ([]:(A)list) <=> T`, REWRITE_TAC[ALL]) and
234 ALL_CONS_T' = (MY_RULE o prove)(`(P h <=> T) /\ (ALL P t <=> T) ==> (ALL P (CONS (h:A) t) <=> T)`,
235 REWRITE_TAC[ALL]) and
236 ALL_CONS_F2' = (MY_RULE o prove)(`(ALL P t <=> F) ==> (ALL P (CONS (h:A) t) <=> F)`,
238 ALL_CONS_F1' = (MY_RULE o prove)(`(P h <=> F) ==> (ALL P (CONS (h:A) t) <=> F)`,
242 (* Note: p_conv should return theorems of the form |- P a b <=> T *)
243 let all_conv_univ p_conv tm =
244 let ltm, list_tm = dest_comb tm in
245 let p_tm = rand ltm in
247 let list_ty = type_of list_tm and
248 p_ty = type_of p_tm in
249 let ty = (hd o snd o dest_type) list_ty in
250 let inst_t = INST_TYPE[ty, aty] in
252 let all_0, all_t, all_f1, all_f2 = inst_t ALL_0', inst_t ALL_CONS_T',
253 inst_t ALL_CONS_F1', inst_t ALL_CONS_F2' in
254 let h_var, t_var = mk_var("h", ty), mk_var("t", list_ty) and
255 p_var = mk_var("P", p_ty) in
257 let rec all_conv_rec = fun list_tm ->
258 if is_comb list_tm then
259 let ltm, t_tm = dest_comb list_tm in
260 let h_tm = rand ltm in
261 let p_th = p_conv (mk_comb (p_tm, h_tm)) in
262 let inst = INST[h_tm, h_var; t_tm, t_var; p_tm, p_var] in
263 if (rand o concl) p_th = t_const then
264 let all_th = all_conv_rec t_tm in
265 if (rand o concl) all_th = t_const then
266 (MY_PROVE_HYP all_th o MY_PROVE_HYP p_th o inst) all_t
268 (MY_PROVE_HYP all_th o inst) all_f2
270 (MY_PROVE_HYP p_th o inst) all_f1
272 INST[p_tm, p_var] all_0 in
273 all_conv_rec list_tm;;
277 let tm = `ALL ((<) 0) [1;3;4;2;4]`;;
278 all_conv_univ NUM_LT_CONV tm;;
279 let test_conv = REWRITE_CONV[ALL] THENC ONCE_DEPTH_CONV NUM_LT_CONV;;
282 test 1000 (all_conv_univ NUM_LT_CONV) tm;;
284 test 1000 test_conv test_tm;;
289 (*******************)
290 (* ALL2 conversion *)
291 (*******************)
293 let ALL2_0' = prove(`ALL2 P ([]:(A)list) ([]:(B)list) <=> T`, REWRITE_TAC[ALL2]) and
294 ALL2_CONS_T' = (MY_RULE o prove)(`(P h1 h2 <=> T) /\ (ALL2 P t1 t2 <=> T) ==>
295 (ALL2 P (CONS (h1:A) t1) (CONS (h2:B) t2) <=> T)`,
296 REWRITE_TAC[ALL2]) and
297 ALL2_CONS_F2' = (MY_RULE o prove)(`(ALL2 P t1 t2 <=> F) ==>
298 (ALL2 P (CONS (h1:A) t1) (CONS (h2:B) t2) <=> F)`,
300 ALL2_CONS_F1' = (MY_RULE o prove)(`(P h1 h2 <=> F) ==>
301 (ALL2 P (CONS (h1:A) t1) (CONS (h2:B) t2) <=> F)`,
305 (* Note: p_conv should return theorems of the form |- P a b <=> T *)
306 let all2_conv_univ p_conv tm =
307 let ltm, list2_tm = dest_comb tm in
308 let ltm2, list1_tm = dest_comb ltm in
309 let p_tm = rand ltm2 in
311 let list1_ty = type_of list1_tm and
312 list2_ty = type_of list2_tm and
313 p_ty = type_of p_tm in
314 let ty1 = (hd o snd o dest_type) list1_ty and
315 ty2 = (hd o snd o dest_type) list2_ty in
316 let inst_t = INST_TYPE[ty1, aty; ty2, bty] in
318 let all2_0, all2_t, all2_f1, all2_f2 = inst_t ALL2_0', inst_t ALL2_CONS_T',
319 inst_t ALL2_CONS_F1', inst_t ALL2_CONS_F2' in
320 let h1_var, t1_var = mk_var("h1", ty1), mk_var("t1", list1_ty) and
321 h2_var, t2_var = mk_var("h2", ty2), mk_var("t2", list2_ty) and
322 p_var = mk_var("P", p_ty) in
324 let rec all2_conv_rec = fun list1_tm list2_tm ->
325 if is_comb list1_tm then
326 let ltm1, t1_tm = dest_comb list1_tm and
327 ltm2, t2_tm = dest_comb list2_tm in
328 let h1_tm, h2_tm = rand ltm1, rand ltm2 in
329 let p_th = p_conv (mk_binop p_tm h1_tm h2_tm) in
330 let inst = INST[h1_tm, h1_var; t1_tm, t1_var; h2_tm, h2_var; t2_tm, t2_var; p_tm, p_var] in
331 if (rand o concl) p_th = t_const then
332 let all2_th = all2_conv_rec t1_tm t2_tm in
333 if (rand o concl) all2_th = t_const then
334 (MY_PROVE_HYP all2_th o MY_PROVE_HYP p_th o inst) all2_t
336 (MY_PROVE_HYP all2_th o inst) all2_f2
338 (MY_PROVE_HYP p_th o inst) all2_f1
340 if is_comb list2_tm then failwith ("all2_conv_univ: l1 = []; l2 = "^string_of_term list2_tm) else
341 INST[p_tm, p_var] all2_0 in
342 all2_conv_rec list1_tm list2_tm;;
346 let tm = `ALL2 (<) [1;3;4;2;4] [3;343;454;454;5]`;;
347 all2_conv_univ NUM_LT_CONV tm;;
348 let test_conv = REWRITE_CONV[ALL2] THENC ONCE_DEPTH_CONV NUM_LT_CONV;;
351 test 1000 (all2_conv_univ NUM_LT_CONV) tm;;
353 test 1000 test_conv test_tm;;
358 (******************************)
360 (* MEM conversions *)
362 let MEM_A_EMPTY = prove(`MEM (x:A) [] <=> F`, REWRITE_TAC[MEM]) and
363 MEM_A_HD = MY_RULE (prove(`(x = h <=> T) ==> (MEM (x:A) (CONS h t) <=> T)`,SIMP_TAC[MEM])) and
364 MEM_A_TL = MY_RULE (prove(`(x = h <=> F) ==> (MEM (x:A) (CONS h t) <=> MEM x t)`, SIMP_TAC[MEM]));;
367 let rec eval_mem_univ eq_conv x_tm list_tm =
368 let ty = type_of x_tm in
369 let inst_t = INST_TYPE[ty, aty] in
370 let mem_empty, mem_hd, mem_tl = inst_t MEM_A_EMPTY, inst_t MEM_A_HD, inst_t MEM_A_TL in
371 let x_var, h_var = mk_var("x", ty), mk_var("h", ty) and
372 t_var = mk_var("t", mk_type("list", [ty])) in
374 let rec mem_conv_raw list_tm =
375 if (is_comb list_tm) then
376 let h_tm', t_tm = dest_comb list_tm in
377 let h_tm = rand h_tm' in
378 let eq_th = eq_conv (mk_eq(x_tm, h_tm)) in
379 if (rand(concl eq_th) = t_const) then
380 let th0' = INST[x_tm, x_var; h_tm, h_var; t_tm, t_var] mem_hd in
381 MY_PROVE_HYP eq_th th0'
383 let th0' = INST[x_tm, x_var; h_tm, h_var; t_tm, t_var] mem_tl in
384 let th0 = MY_PROVE_HYP eq_th th0' in
385 let th1 = mem_conv_raw t_tm in
388 INST[x_tm, x_var] mem_empty in
390 mem_conv_raw list_tm;;
393 let mem_conv_univ eq_conv mem_tm =
394 let ltm, list_tm = dest_comb mem_tm in
395 let c_tm, x_tm = dest_comb ltm in
396 if (fst o dest_const) c_tm <> "MEM" then failwith "mem_conv_univ" else
397 eval_mem_univ eq_conv x_tm list_tm;;
401 let tm = `MEM 11 [1;2;3;4;5;6;4;5;6;7;3;4;4;6;8;9;10]`;;
402 mem_conv_univ (PURE_REWRITE_CONV[ARITH_EQ]) tm;;
404 test 100 (mem_conv_univ (REWRITE_CONV[ARITH_EQ])) tm;; (* 0.176 *)
405 test 100 (REWRITE_CONV[MEM; ARITH_EQ]) tm;; (* 0.352 *)
409 (**********************************)
411 (* FILTER conversions *)
413 let FILTER_A_EMPTY = prove(`FILTER (P:A->bool) [] = []`, REWRITE_TAC[FILTER]) and
414 FILTER_A_HD = (MY_RULE o prove)(`(P h <=> T) ==> FILTER (P:A->bool) (CONS h t) = CONS h (FILTER P t)`,
415 SIMP_TAC[FILTER]) and
416 FILTER_A_TL = (MY_RULE o prove)(`(P h <=> F) ==> FILTER (P:A->bool) (CONS h t) = FILTER P t`,
421 let filter_conv_univ p_conv tm =
422 let ltm, list_tm = dest_comb tm in
423 let p_tm = rand ltm in
424 let p_ty = type_of p_tm in
425 let ty = (hd o snd o dest_type) p_ty in
426 let inst_t = INST_TYPE[ty, aty] in
427 let filter_empty, filter_hd, filter_tl =
428 inst_t FILTER_A_EMPTY, inst_t FILTER_A_HD, inst_t FILTER_A_TL in
429 let p_var = mk_var("P", p_ty) in
430 let h_var = mk_var("h", ty) in
431 let t_var = mk_var("t", mk_type("list",[ty])) in
433 let rec filter_conv_raw = fun list_tm ->
434 if (is_comb list_tm) then
435 let ltm, t_tm = dest_comb list_tm in
436 let h_tm = rand ltm in
437 let p_th = p_conv (mk_comb(p_tm, h_tm)) in
438 if (rand(concl p_th) = t_const) then
439 let th0' = INST[p_tm, p_var; h_tm, h_var; t_tm, t_var] filter_hd in
440 let th0 = MY_PROVE_HYP p_th th0' in
441 let ltm = rator(rand(concl th0)) in
442 let th1 = filter_conv_raw t_tm in
443 TRANS th0 (AP_TERM ltm th1)
445 let th0' = INST[p_tm, p_var; h_tm, h_var; t_tm, t_var] filter_tl in
446 let th0 = MY_PROVE_HYP p_th th0' in
447 let th1 = filter_conv_raw t_tm in
450 INST[p_tm, p_var] filter_empty in
452 filter_conv_raw list_tm;;
458 let tm = `FILTER (\n. n = 2 \/ n = 3) [1;2;3;4;2;3;1]`;;
460 REWRITE_CONV[FILTER; ARITH_EQ] tm;;
461 filter_conv_univ (REWRITE_CONV[ARITH_EQ]) tm;;
463 test 100 (REWRITE_CONV[FILTER; ARITH_EQ]) tm;; (* 7.596 *)
464 test 100 (filter_conv_univ (REWRITE_CONV[ARITH_EQ])) tm;; (* 0.236 *)
467 (***************************)
469 (* MAP conversions *)
472 let MAP_AB_EMPTY = prove(`MAP (f:A->B) [] = []`, REWRITE_TAC[MAP]) and
473 MAP_AB_CONS = prove(`MAP (f:A->B) (CONS h t) = CONS (f h) (MAP f t)`, REWRITE_TAC[MAP]);;
476 let map_conv_univ f_conv tm =
477 let ltm, list_tm = dest_comb tm in
478 let ftm = rand ltm in
479 let ftm_ty = type_of ftm in
480 let f_var = mk_var("f", ftm_ty) in
481 let [a_type; b_type] = snd(dest_type ftm_ty) in
482 let h_var = mk_var("h", a_type) in
483 let t_var = mk_var("t", mk_type("list", [a_type])) in
484 let inst_t = INST[ftm, f_var] o INST_TYPE[a_type, aty; b_type, bty] in
485 let map_empty, map_cons =
486 inst_t MAP_AB_EMPTY, inst_t MAP_AB_CONS in
488 let rec map_conv_raw list_tm =
489 if (is_comb list_tm) then
490 let h_tm', t_tm = dest_comb list_tm in
491 let h_tm = rand h_tm' in
492 let th0 = INST[h_tm, h_var; t_tm, t_var] map_cons in
493 let ltm, rtm = dest_comb (rand(concl th0)) in
494 let cons_tm, f_h_tm = dest_comb ltm in
495 let f_h_th = f_conv f_h_tm in
496 let map_t_th = map_conv_raw t_tm in
497 TRANS th0 (MK_COMB (AP_TERM cons_tm f_h_th, map_t_th))
501 map_conv_raw list_tm;;
505 let tm = `MAP (\x. x + 1) [1;2;3;4;5;6;7;8;9;10;11]`;;
507 REWRITE_CONV[MAP] tm;;
508 map_conv_univ BETA_CONV tm;;
509 map_conv_univ (BETA_CONV THENC NUM_ADD_CONV) tm;;
511 test 100 (REWRITE_CONV[MAP]) tm;; (* 0.464 *)
512 test 100 (map_conv_univ BETA_CONV) tm;; (* 0.04 *)
514 test 100 (map_conv_univ (BETA_CONV THENC NUM_ADD_CONV)) tm;; (* 0.096 *)
518 (*****************************************)
523 let ALL_A_HD = UNDISCH_ALL(prove(`ALL (P:A->bool) (CONS h t) ==> P h`, SIMP_TAC[ALL])) and
524 ALL_A_TL = UNDISCH_ALL(prove(`ALL (P:A->bool) (CONS h t) ==> ALL P t`, SIMP_TAC[ALL]));;
527 (* Given a theorem `ALL P list` returns the list of theorems (P x1),...,(P xn) *)
529 let ltm, list_tm = dest_comb (concl th) in
530 let p_tm = rand ltm in
531 let list_ty = type_of list_tm in
532 let p_ty = type_of p_tm in
533 let ty = (hd o snd o dest_type) list_ty in
534 let p_var = mk_var("P", p_ty) in
535 let h_var = mk_var("h", ty) in
536 let t_var = mk_var("t", list_ty) in
538 let inst_t = INST[p_tm, p_var] o INST_TYPE[ty, aty] in
539 let all_hd, all_tl = inst_t ALL_A_HD, inst_t ALL_A_TL in
541 let rec get_all_raw all_th list_tm =
542 if (is_comb list_tm) then
543 let h_tm', t_tm = dest_comb list_tm in
544 let h_tm = rand h_tm' in
545 let inst_t = INST[h_tm, h_var; t_tm, t_var] in
546 let th_tl = MY_PROVE_HYP all_th (inst_t all_tl) in
547 let th_hd = MY_PROVE_HYP all_th (inst_t all_hd) in
548 th_hd :: get_all_raw th_tl t_tm
552 get_all_raw th list_tm;;
556 (* Given a theorem `ALL P list`, returns (P x_i1),..., (P x_in)
557 where i1,...,in are given indices.
558 The list of indices should be sorted *)
559 let select_all th indices =
560 let ltm, list_tm = dest_comb (concl th) in
561 let p_tm = rand ltm in
562 let list_ty = type_of list_tm in
563 let p_ty = type_of p_tm in
564 let ty = (hd o snd o dest_type) list_ty in
565 let p_var = mk_var("P", p_ty) in
566 let h_var = mk_var("h", ty) in
567 let t_var = mk_var("t", list_ty) in
569 let inst_t = INST[p_tm, p_var] o INST_TYPE[ty, aty] in
570 let all_hd, all_tl = inst_t ALL_A_HD, inst_t ALL_A_TL in
572 let rec get_all_raw all_th list_tm indices n =
576 let h_tm', t_tm = dest_comb list_tm in
577 let h_tm = rand h_tm' in
578 let inst_t = INST[h_tm, h_var; t_tm, t_var] in
579 let th_tl = MY_PROVE_HYP all_th (inst_t all_tl) in
582 let th_hd = MY_PROVE_HYP all_th (inst_t all_hd) in
583 th_hd :: get_all_raw th_tl t_tm is (n + 1)
585 get_all_raw th_tl t_tm (i::is) (n + 1) in
587 get_all_raw th list_tm indices 0;;
591 let tm = `ALL (\x. x > 3) [4; 5; 8; 10; 5; 4]`;;
592 let th = (EQT_ELIM o REWRITE_CONV[ALL; ARITH]) tm;;
594 select_all th [2;3;4];;
597 test 100 (CONJUNCTS o REWRITE_RULE[ALL]) th;;
599 test 100 (get_all) th;;
601 test 100 (select_all th) [2;3;4];;
605 (*****************************************)
607 (* set_of_list conversions *)
609 let SET_OF_LIST_A_EMPTY = prove(`set_of_list ([]:(A)list) = {}`, REWRITE_TAC[set_of_list]) and
610 SET_OF_LIST_A_H = prove(`set_of_list [h:A] = {h}`, REWRITE_TAC[set_of_list]) and
611 SET_OF_LIST_A_CONS = prove(`set_of_list (CONS (h:A) t) = h INSERT set_of_list t`, REWRITE_TAC[set_of_list]);;
615 let set_of_list_conv tm =
616 let list_tm = rand tm in
617 let list_ty = type_of list_tm in
618 let ty = (hd o snd o dest_type) list_ty in
619 let h_var = mk_var("h", ty) in
620 let t_var = mk_var("t", list_ty) in
621 let inst_t = INST_TYPE[ty, aty] in
622 let set_of_list_h, set_of_list_cons = inst_t SET_OF_LIST_A_H, inst_t SET_OF_LIST_A_CONS in
624 let rec set_of_list_conv_raw = fun h_tm t_tm ->
625 if (is_comb t_tm) then
626 let h_tm', t_tm' = dest_comb t_tm in
627 let th0 = INST[h_tm, h_var; t_tm, t_var] set_of_list_cons in
628 let ltm, rtm = dest_comb(rand(concl th0)) in
629 TRANS th0 (AP_TERM ltm (set_of_list_conv_raw (rand h_tm') t_tm'))
631 INST[h_tm, h_var] set_of_list_h in
633 if (is_comb list_tm) then
634 let h_tm, t_tm = dest_comb list_tm in
635 set_of_list_conv_raw (rand h_tm) t_tm
637 inst_t SET_OF_LIST_A_EMPTY;;
642 let tm = `set_of_list [&1; &5; &6; &3; &5; &8; &9]`;;
643 set_of_list_conv tm;;
645 test 1000 (REWRITE_CONV[set_of_list]) tm;;
647 test 1000 set_of_list_conv tm;;
653 (*************************************)
655 (* list_sum conversions *)
657 let list_sum = new_definition `list_sum list f = ITLIST (\t1 t2. f t1 + t2) list (&0)`;;
659 let LIST_SUM_A_EMPTY = prove(`list_sum [] (f:A->real) = &0`, REWRITE_TAC[list_sum; ITLIST]) and
660 LIST_SUM_A_H = prove(`list_sum [h:A] f = f h`, REWRITE_TAC[list_sum; ITLIST; REAL_ADD_RID]) and
661 LIST_SUM_A_CONS = prove(`list_sum (CONS (h:A) t) f = f h + list_sum t f`, REWRITE_TAC[list_sum; ITLIST]);;
664 let list_sum_conv f_conv tm =
665 let ltm, f_tm = dest_comb tm in
666 let list_tm = rand ltm in
667 let list_ty = type_of list_tm in
668 let f_ty = type_of f_tm in
669 let ty = (hd o snd o dest_type) list_ty in
670 let f_var = mk_var("f", f_ty) and
671 h_var = mk_var("h", ty) and
672 t_var = mk_var("t", list_ty) in
673 let inst_t = INST[f_tm, f_var] o INST_TYPE[ty, aty] in
674 let list_sum_h = inst_t LIST_SUM_A_H and
675 list_sum_cons = inst_t LIST_SUM_A_CONS in
677 let rec list_sum_conv_raw = fun h_tm t_tm ->
678 if (is_comb t_tm) then
679 let h_tm', t_tm' = dest_comb t_tm in
680 let th0 = INST[h_tm, h_var; t_tm, t_var] list_sum_cons in
681 let ltm, rtm = dest_comb(rand(concl th0)) in
682 let plus_op, fh_tm = dest_comb ltm in
683 let f_th = f_conv fh_tm in
684 let th1 = list_sum_conv_raw (rand h_tm') t_tm' in
685 let th2 = MK_COMB(AP_TERM plus_op f_th, th1) in
688 let th0 = INST[h_tm, h_var] list_sum_h in
689 let f_th = f_conv (rand(concl th0)) in
692 if (is_comb list_tm) then
693 let h_tm, t_tm = dest_comb list_tm in
694 list_sum_conv_raw (rand h_tm) t_tm
696 inst_t LIST_SUM_A_EMPTY;;
702 let tm = `list_sum [&1; &3; &4; pi; #0.1] cos`;;
704 list_sum_conv ALL_CONV tm;;
707 test 1000 (REWRITE_CONV[list_sum; ITLIST; REAL_ADD_RID]) tm;;
709 test 1000 (list_sum_conv ALL_CONV) tm;;
712 let tm = `list_sum [&1; &3; &4; pi; #0.1] (\x. cos x)`;;
714 test 1000 (list_sum_conv BETA_CONV) tm;;