(* Explicit computations for hypermap_of_list *)
#load "str.cma";;
needs "../formal_lp/hypermap/ssreflect/list_hypermap_iso-compiled.hl";;
needs "../formal_lp/hypermap/computations/list_conversions2.hl";;
needs "../formal_lp/hypermap/computations/more_theory-compiled.hl";;
module List_hypermap_computations = struct
open Str;;
open List;;
open Misc_vars;;
open Arith_misc;;
open Arith_nat;;
open More_list_hypermap;;
open List_hypermap;;
open List_conversions;;
open List_hypermap_iso;;
let MY_RULE = UNDISCH_ALL o PURE_REWRITE_RULE[GSYM IMP_IMP] o SPEC_ALL;;
let MY_RULE_NUM = UNDISCH_ALL o NUMERALS_TO_NUM o PURE_REWRITE_RULE[GSYM IMP_IMP] o SPEC_ALL;;
let TO_NUM = REWRITE_RULE[Arith_hash.NUM_THM] o DEPTH_CONV NUMERAL_TO_NUM_CONV;;
let to_num = rand o concl o TO_NUM;;
(* Constants and variables *)
let hd_var_num = `hd:num` and
h_var_num = `h:num` and
h1_var_num = `h1:num` and
h2_var_num = `h2:num` and
t_var = `t:(num)list` and
x_var_pair = `x:num#num` and
d_var_pair = `d:num#num` and
h1_var_pair = `h1:num#num` and
h2_var_pair = `h2:num#num` and
acc_var = `acc:(num#num)list` and
f_var_fun = `f:num#num->num#num` and
l_cap_var = `L:((num)list)list` and
ll_var = `ll:((num)list)list` and
list_var = `list:(num#num)list` and
t_var_numnum_list = `t:(num#num)list` and
t_var_num_list = `t:(num)list` and
t_var_list_list = `t:((num)list)list` and
h_var_list = `h:(num)list` and
r_var_list = `r:(num)list` and
s1_var_list = `s1:(num)list` and
s2_var_list = `s2:(num)list`;;
let num_list_type = `:(num)list`;;
let num_list_list_type = `:((num)list)list`;;
let mem_const = `MEM:(num#num)->(num#num)list->bool` and
flatten_const = `flatten:((num#num)list)list -> (num#num)list`;;
let hypermap_of_list_const = `hypermap_of_list:((num)list)list->(num#num)hypermap` and
list_of_darts_const = `list_of_darts:((num)list)list->(num#num)list` and
list_of_edges_const = `list_of_edges:((num)list)list->((num#num)#(num#num))list` and
list_of_faces_const = `list_of_faces:((num)list)list->((num#num)list)list` and
list_of_nodes_const = `list_of_nodes:((num)list)list->((num#num)list)list` and
list_of_elements_const = `list_of_elements:((num)list)list->(num)list` and
good_list_const = `good_list:((num)list)list->bool` and
good_list_nodes_const = `good_list_nodes:((num)list)list->bool`;;
let num_pair_hash tm =
let ltm, rtm = dest_pair tm in
Arith_cache.num_tm_hash ltm ^ "," ^ Arith_cache.num_tm_hash rtm;;
let build_term_rewrite tm lhs =
let rec build_rewrite tm =
if tm = lhs then
(fun th -> th), true
else
match tm with
| Comb (l_tm, r_tm) ->
let l_f, l_flag = build_rewrite l_tm and
r_f, r_flag = build_rewrite r_tm in
if l_flag then
if r_flag then
(fun th -> MK_COMB (l_f th, r_f th)), true
else
(fun th -> AP_THM (l_f th) r_tm), true
else
if r_flag then
(fun th -> AP_TERM l_tm (r_f th)), true
else
I, false
| Abs (var_tm, b_tm) ->
let b_f, b_flag = build_rewrite b_tm in
if b_flag then
(fun th -> ABS var_tm (b_f th)), true
else
I, false
| _ -> I, false in
let f, flag = build_rewrite tm in
if flag then f else (fun th -> REFL tm);;
(* eq_th = |- lhs = rhs; rewrites exact occurrences of lhs in tm and returns |- tm = tm[lhs/rhs] *)
let term_rewrite tm eq_th =
let lhs, _ = dest_eq (concl eq_th) in
build_term_rewrite tm lhs eq_th;;
(*
let tm = `(x + 2) * 2 = 0 /\ (\y. (x + 2) * y) 3 = 2` and
th = ARITH_RULE `x + 2 = 1 * 2 + x`;;
let f = build_term_rewrite tm `x + 2`;;
term_rewrite tm th;;
f th;;
PURE_REWRITE_CONV[th] tm;;
(* 0.304 *)
test 10000 (term_rewrite tm) th;;
(* 0.216 *)
test 10000 f th;;
(* 2.808 *)
test 10000 (PURE_REWRITE_CONV[th]) tm;;
*)
(* example of java style string from hypermap generator. *)
let pentstring = "13_150834109178 18 3 0 1 2 3 3 2 7 3 3 0 2 4 5 4 0 3 4 6 1 0 4 3 7 2 8 3 8 2 1 4 8 1 6 9 3 9 6 10 3 10 6 4 3 10 4 5 4 5 3 7 11 3 10 5 11 3 11 7 12 3 12 7 8 3 12 8 9 3 9 10 11 3 11 12 9 ";;
let test_string = "149438122187 18 6 0 1 2 3 4 5 4 0 5 6 7 3 6 5 4 3 6 4 8 3 8 4 3 3 8 3 9 3 9 3 2 3 9 2 10 3 10 2 11 3 11 2 1 3 11 1 0 3 11 0 7 3 10 11 7 3 10 7 12 3 12 7 6 3 12 6 8 3 12 8 9 3 9 10 12 ";;
(* conversion to list. e.g. convert_to_list pentstring *)
let convert_to_list =
let split_sp= Str.split (regexp " +") in
let strip_ = global_replace (regexp "_") "" in
let rec movelist n (x,a) =
if n = 0 then (x,a) else
match x with
| [] -> failwith "convert_to_list"
| y::ys -> movelist (n-1) (ys, y::a) in
let getone (x,a) = match x with
| [] -> ([],a)
| y::ys -> let (u,v) = movelist y (ys,[]) in (u,v::a) in
let rec getall (x,a) =
if (x=[]) then (x,a) else getall (getone (x,a)) in
fun s ->
let h::ss = (split_sp (strip_ s)) in
let _::ns = map int_of_string ss in
let (_,a) = getall (ns,[]) in
(h,rev (map rev a));;
let create_hol_list ll =
let s1 = map (map mk_small_numeral) ll in
let s2 = map (fun l -> mk_list (l, num_type)) s1 in
mk_list (s2, num_list_type);;
let create_hol_list_str =
create_hol_list o snd o convert_to_list;;
let test_list0 = create_hol_list_str test_string;;
let test_list = to_num test_list0;;
let print_num tm =
try
let n = raw_dest_hash tm in
let str = "'" ^ Num.string_of_num n in
Format.print_string str
with _ -> failwith "print_num";;
install_user_printer ("num", print_num);;
(********************************************)
let eval_mem_num_pair = eval_mem_univ pair_eq_conv_num;;
let mem_num_pair_conv = mem_conv_univ pair_eq_conv_num;;
(*************************************)
(* list_sum conversions *)
let list_sum_conv f_conv tm =
let ltm, f_tm = dest_comb tm in
let list_tm = rand ltm in
let list_ty = type_of list_tm in
let f_ty = type_of f_tm in
let ty = (hd o snd o dest_type) list_ty in
let f_var = mk_var("f", f_ty) and
h_var = mk_var("h", ty) and
t_var = mk_var("t", list_ty) in
let inst_t = INST[f_tm, f_var] o INST_TYPE[ty, aty] in
let list_sum_h = inst_t LIST_SUM_A_H and
list_sum_cons = inst_t LIST_SUM_A_CONS in
let rec list_sum_conv_raw = fun h_tm t_tm ->
if (is_comb t_tm) then
let h_tm', t_tm' = dest_comb t_tm in
let th0 = INST[h_tm, h_var; t_tm, t_var] list_sum_cons in
let ltm, rtm = dest_comb(rand(concl th0)) in
let plus_op, fh_tm = dest_comb ltm in
let f_th = f_conv fh_tm in
let th1 = list_sum_conv_raw (rand h_tm') t_tm' in
let th2 = MK_COMB(AP_TERM plus_op f_th, th1) in
TRANS th0 th2
else
let th0 = INST[h_tm, h_var] list_sum_h in
let f_th = f_conv (rand(concl th0)) in
TRANS th0 f_th in
if (is_comb list_tm) then
let h_tm, t_tm = dest_comb list_tm in
list_sum_conv_raw (rand h_tm) t_tm
else
inst_t LIST_SUM_A_EMPTY;;
(*********************************)
(* e_list conversions *)
let eval_e_list_num =
let th0 = prove(`
e_list (x:num,y:num) = y,x`,
REWRITE_TAC[
e_list]) in
fun d_tm ->
let ltm, y_tm = dest_comb d_tm in
let x_tm = rand ltm in
INST[x_tm, x_var_num; y_tm, y_var_num]
th0;;
let e_list_conv_num tm =
let ltm, d_tm = dest_comb tm in
if ((fst o dest_const) ltm <> "e_list") then
failwith "e_list_conv_num: e_list expected"
else
eval_e_list_num d_tm;;
(*********************************)
(* list_pairs_conv *)
let RULE tm = prove(tm, REWRITE_TAC[list_pairs2]);;
let list_pairs2_0 = RULE `list_pairs2 [] (hd:num) = []` and
list_pairs2_1 = RULE `list_pairs2 [h1] (hd:num) = [h1,hd]` and
list_pairs2_2 = RULE `list_pairs2 (h1 :: h2 :: t) (hd:num) = (h1,h2) :: list_pairs2 (h2 :: t) hd`;;
let RULE tm = prove(tm, REWRITE_TAC[list_pairs_eq_list_pairs2; list_pairs2_0; HD]);;
let list_pairs_empty = RULE `list_pairs ([]:(num)list) = []` and
list_pairs_cons = RULE `list_pairs ((h:num) :: t) = list_pairs2 (h :: t) h`;;
let list_pairs2_conv tm =
let ltm, hd_tm = dest_comb tm in
let rec list_pairs2_rec list =
if (is_comb list) then
let h_tm', t1_tm = dest_comb list in
let h1_tm = rand h_tm' in
if (is_comb t1_tm) then
let h_tm', t2_tm = dest_comb t1_tm in
let h2_tm = rand h_tm' in
let th0 = INST[h1_tm, h1_var_num; h2_tm, h2_var_num; t2_tm, t_var; hd_tm, hd_var_num] list_pairs2_2 in
let ltm = rator (rand (concl th0)) in
let th1 = list_pairs2_rec t1_tm in
TRANS th0 (AP_TERM ltm th1)
else
INST[h1_tm, h1_var_num; hd_tm, hd_var_num] list_pairs2_1
else
INST[hd_tm, hd_var_num] list_pairs2_0 in
list_pairs2_rec (rand ltm);;
let eval_list_pairs list_tm =
if (is_comb list_tm) then
let h_tm', t_tm = dest_comb list_tm in
let h_tm = rand h_tm' in
let th0 = INST[h_tm, h_var_num; t_tm, t_var] list_pairs_cons in
let th1 = list_pairs2_conv (rand (concl th0)) in
TRANS th0 th1
else
list_pairs_empty;;
let list_pairs_conv = eval_list_pairs o rand;;
(***********************************************)
(* list_of_faces_conv *)
let LIST_OF_FACES_REWRITE_CONV = REWRITE_CONV[list_of_faces; MAP; list_pairs_eq_list_pairs2; list_pairs2; HD];;
(* applies the given operation to the rhs of eq_th and returns op (lhs) = op (rhs) *)
let apply_op eq_th op =
let op_rhs = op (rand (concl eq_th)) in
let op_tm = (rator o lhand o concl) op_rhs in
TRANS (AP_TERM op_tm eq_th) op_rhs;;
let eval_list_of_faces =
let eval_list_of_faces3, eval_list_of_faces4, eval_list_of_faces5, eval_list_of_faces6 =
let eq3_th = (MY_RULE_NUM o prove)
(`list_of_faces3 (L:((num)list)list) = FILTER (\f. LENGTH f = 3) (list_of_faces L)`,
REWRITE_TAC[list_of_faces3; filter_FILTER]) in
let eq4_th = (MY_RULE_NUM o prove)
(`list_of_faces4 (L:((num)list)list) = FILTER (\f. LENGTH f = 4) (list_of_faces L)`,
REWRITE_TAC[list_of_faces4; filter_FILTER]) in
let eq5_th = (MY_RULE_NUM o prove)
(`list_of_faces5 (L:((num)list)list) = FILTER (\f. LENGTH f = 5) (list_of_faces L)`,
REWRITE_TAC[list_of_faces5; filter_FILTER]) in
let eq6_th = (MY_RULE_NUM o prove)
(`list_of_faces6 (L:((num)list)list) = FILTER (\f. LENGTH f = 6) (list_of_faces L)`,
REWRITE_TAC[list_of_faces6; filter_FILTER]) in
let op3_tm = (rator o rand o concl) eq3_th in
let op4_tm = (rator o rand o concl) eq4_th in
let op5_tm = (rator o rand o concl) eq5_th in
let op6_tm = (rator o rand o concl) eq6_th in
let eval eq_th op_tm list_tm faces_th =
let th0 = INST[list_tm, l_cap_var] eq_th in
let th1 = AP_TERM op_tm faces_th in
let th2 = filter_conv_univ (BETA_CONV THENC LAND_CONV length_conv THENC raw_eq_hash_conv) (rand (concl th1)) in
TRANS th0 (TRANS th1 th2) in
(eval eq3_th op3_tm),
(eval eq4_th op4_tm),
(eval eq5_th op5_tm),
(eval eq6_th op6_tm);;
let eval_faces_of_list0 =
let th0 = ISPEC l_cap_var faces_of_list in
let op_tm = `MAP set_of_list : ((num#num)list)list->(num#num->bool)list` in
fun list_tm faces_th ->
let th1 = INST[list_tm, l_cap_var] th0 in
let th2 = AP_TERM op_tm faces_th in
let th3 = map_conv_univ set_of_list_conv ((rand o concl) th2) in
TRANS th1 (TRANS th2 th3);;
(*
let y = mk_comb (list_of_darts_const, test_list);;
test 100 LIST_OF_FACES_REWRITE_CONV y;; (* 0.224 *)
test 100 eval_list_of_faces test_list;; (* 0.104 *)
*)
(*********************************)
(* list_of_darts *)
let eval_list_of_darts0, eval_list_of_darts3, eval_list_of_darts4,
eval_list_of_darts5, eval_list_of_darts6 =
let eval_list_of_darts tm =
eval_list_of_darts0 tm (eval_list_of_faces tm);;
(*
test 100 eval_list_of_darts test_list;; (* 0.204 *)
*)
(************************************)
(* list_of_elements *)
let eval_list_of_elements =
(*
test 100 eval_list_of_elements test_list;; (* 1.432 *)
*)
(******************************)
(* GOOD_LIST_CONV *)
let GOOD_LIST_COND3_EMPTY = prove(`
ALL (\d:num#num.
MEM (
SND d,
FST d) list) [] <=> T`,
REWRITE_TAC[
ALL]) and
GOOD_LIST_COND3_CONS_T = (UNDISCH_ALL o prove)(`(
MEM (y,x) list <=> T) ==>
(
ALL (\d:num#num.
MEM (
SND d,
FST d) list) (CONS (x,y) t) <=>
ALL (\d:num#num.
MEM (
SND d,
FST d) list) t)`, SIMP_TAC[
ALL]) and
GOOD_LIST_COND3_CONS_F = (UNDISCH_ALL o prove)(`(
MEM (y,x) list <=> F) ==>
(
ALL (\d:num#num.
MEM (
SND d,
FST d) list) (CONS (x,y) t) <=> F)`,
SIMP_TAC[
ALL]);;
let rec good_list_cond3_conv tm =
let ltm, list_tm = dest_comb tm in
let f_tm = rand ltm in
let list2_tm = (rand o snd o dest_abs) f_tm in
if (is_comb list_tm) then
let h_tm, t_tm = dest_comb list_tm in
let x_tm, y_tm = dest_pair (rand h_tm) in
let inst = INST[list2_tm, list_var; x_tm, x_var_num; y_tm, y_var_num; t_tm, t_var_numnum_list] in
let mem_th = mem_num_pair_conv (mk_binop mem_const (mk_pair (y_tm, x_tm)) list2_tm) in
if (rand(concl mem_th) = t_const) then
let th0 = MY_PROVE_HYP mem_th (inst GOOD_LIST_COND3_CONS_T) in
let th1 = good_list_cond3_conv (rand (concl th0)) in
TRANS th0 th1
else
MY_PROVE_HYP mem_th (inst GOOD_LIST_COND3_CONS_F)
else
INST[list2_tm, list_var] GOOD_LIST_COND3_EMPTY;;
let good_list_cond2_conv =
let th_T = prove(`(\l. ~(l = [])) ((h:num) :: t) <=> T`,
REWRITE_TAC[
NOT_CONS_NIL]) and
th_F = prove(`(\l. ~(l = [])) ([]:(num)list) <=> F`, REWRITE_TAC[]) in
let test_f tm =
let list_tm = rand tm in
if is_comb list_tm then
let h_tm', t_tm = dest_comb list_tm in
INST[rand h_tm', h_var_num; t_tm, t_var_num_list]
th_T
else
th_F in
fun tm ->
all_conv_univ test_f tm;;
let eval_good_list0 =
let good_th = (MY_RULE o prove)(`list_of_darts L = (list:(num#num)list)
/\ (uniq list <=> T)
/\ (ALL (\l. ~(l = [])) L <=> T)
/\ (ALL (\d. MEM (SND d,FST d) list) list <=> T)
==> good_list L`,
SIMP_TAC[good_list; ALL_MEM; Seq2.ALL_all]) in
let cond2_tm = `ALL (\l:(num)list. ~(l = []))` in
let cond3_tm = `ALL (\d:num#num. MEM (SND d, FST d) list) list` in
fun tm darts_th ->
let darts_tm = (rand o concl) darts_th in
let th0 = INST[tm, l_cap_var; darts_tm, list_var] good_th in
let uniq_th = (eval_uniq_univ pair_eq_conv_num) darts_tm in
let cond2_th = good_list_cond2_conv (mk_comb (cond2_tm, tm)) in
let cond3_th = good_list_cond3_conv (subst[darts_tm, list_var] cond3_tm) in
(MY_PROVE_HYP darts_th o MY_PROVE_HYP uniq_th o MY_PROVE_HYP cond2_th o MY_PROVE_HYP cond3_th) th0;;
(*
let darts = eval_list_of_darts test_list;;
test 10 (eval_good_list0 test_list) darts;; (* 1.376 *)
*)
(*********************************)
(* split_list_hyp *)
let one_eq = TO_NUM `1` and
two_tm = to_num `2` and
three_tm = to_num `3` and
three_lt_tm = to_num `(<) 3`;;
let split_list_hyp_cons_F = (MY_RULE o prove)(`list_pairs h = list /\ (MEM d list <=> F)
==> split_list_hyp (h :: t) d = h :: split_list_hyp t (d:num#num)`, SIMP_TAC[split_list_hyp]);;
let split_list_hyp_cons_T = (UNDISCH_ALL o PURE_ONCE_REWRITE_RULE[GSYM one_eq] o DISCH_ALL o MY_RULE_NUM o prove)
(`list_pairs h = list /\ (MEM (d:num#num) list <=> T) /\ (3 < LENGTH h <=> T)
/\ indexl d list = i /\ rotr 1 (rot i h) = r /\ take 3 r = s1 /\ dropl 2 r = s2 /\ HD r = h1
==> split_list_hyp (h :: t) d = s1 :: (h1 :: s2) :: t`,
SIMP_TAC[split_list_hyp; split_list_face] THEN
STRIP_TAC THEN REPLICATE_TAC 3 (POP_ASSUM (fun th -> ALL_TAC)) THEN
POP_ASSUM (fun th -> REWRITE_TAC[GSYM th]) THEN
REWRITE_TAC[Seq.size_rotr; Seq.size_rot; Seq.size] THEN
ASM_REWRITE_TAC[ARITH_RULE `a <= 3 <=> ~(3 < a)`] THEN
REWRITE_TAC[Seq.cat]);;
let rec eval_split_list_hyp tm d_tm =
if not (is_comb tm) then
INST[d_tm, d_var_pair] split_list_hyp_empty
else
let h_tm', t_tm = dest_comb tm in
let h_tm = rand h_tm' in
let pairs_th = eval_list_pairs h_tm in
let list_tm = (rand o concl) pairs_th in
let mem_th = eval_mem_num_pair d_tm list_tm in
if (rand (concl mem_th) = f_const) then
let th0 = (MY_PROVE_HYP pairs_th o MY_PROVE_HYP mem_th o
INST[d_tm, d_var_pair; t_tm, t_var_list_list; h_tm, h_var_list; list_tm, list_var])
split_list_hyp_cons_F in
let ltm = (rator o rand o concl) th0 in
let th1 = eval_split_list_hyp t_tm d_tm in
TRANS th0 (AP_TERM ltm th1)
else
let size_th = eval_length h_tm in
let size_lt0 = AP_TERM three_lt_tm size_th in
let size_lt1 = raw_lt_hash_conv ((rand o concl) size_lt0) in
if (rand (concl size_lt1) = f_const) then
failwith "eval_split_list_hyp: size (face) <= 3"
else
let size_lt_th = TRANS size_lt0 size_lt1 in
let i_th = eval_index_univ pair_eq_conv_num d_tm list_tm in
let i_tm = (rand o concl) i_th in
let r_th = apply_op (eval_rot i_tm h_tm) eval_rotr1 in
let r_tm = (rand o concl) r_th in
let hd_th = eval_hd r_tm in
let h1_tm = (rand o concl) hd_th in
let take_th = eval_take three_tm r_tm in
let s1_tm = (rand o concl) take_th in
let drop_th = eval_drop two_tm r_tm in
let s2_tm = (rand o concl) drop_th in
(MY_PROVE_HYP i_th o MY_PROVE_HYP hd_th o MY_PROVE_HYP pairs_th o
MY_PROVE_HYP take_th o MY_PROVE_HYP r_th o MY_PROVE_HYP drop_th o
MY_PROVE_HYP mem_th o MY_PROVE_HYP size_lt_th o
INST[h_tm, h_var_list; list_tm, list_var; h1_tm, h1_var_num;
d_tm, d_var_pair; r_tm, r_var_list; i_tm, i_var_num; t_tm, t_var_list_list;
s1_tm, s1_var_list; s2_tm, s2_var_list])
split_list_hyp_cons_T;;
(*
let tm = test_list;;
let d_tm = to_num `7,0`;;
(* 0.152 *)
test 100 (eval_split_list_hyp tm) d_tm;;
*)
(*********************************)
(* list_of_nodes *)
let filter_nodes_cons_eq = (MY_RULE o prove)(`(n = x <=> T) ==> filter (\d:num#num. FST d = x) (CONS (n,m) t) =
CONS (n,m) (filter (\d. FST d = x) t)`, SIMP_TAC[Seq.filter]);;
let filter_nodes_cons_neq = (MY_RULE o prove)(`(n = x <=> F) ==> filter (\d:num#num. FST d = x) (CONS (n,m) t) =
filter (\d. FST d = x) t`, SIMP_TAC[Seq.filter]);;
let rec eval_filter_nodes x_tm list_tm =
if (is_comb list_tm) then
let h_tm', t_tm = dest_comb list_tm in
let h_tm = rand h_tm' in
let n_tm, m_tm = dest_pair h_tm in
let inst = INST[n_tm, n_var_num; m_tm, m_var_num; t_tm, t_var_numnum_list; x_tm, x_var_num] in
let eq_th = raw_eq_hash_conv (mk_eq (n_tm, x_tm)) in
if (rand (concl eq_th) = t_const) then
let th0 = MY_PROVE_HYP eq_th (inst filter_nodes_cons_eq) in
let ltm = (rator o rand o concl) th0 in
let th1 = eval_filter_nodes x_tm t_tm in
TRANS th0 (AP_TERM ltm th1)
else
let th0 = MY_PROVE_HYP eq_th (inst filter_nodes_cons_neq) in
let th1 = eval_filter_nodes x_tm t_tm in
TRANS th0 th1
else
INST[x_tm, x_var_num] filter_nodes_empty;;
let filter_nodes_conv filter_tm =
let ltm, list_tm = dest_comb filter_tm in
let x_tm = (rand o snd o dest_abs o rand) ltm in
eval_filter_nodes x_tm list_tm;;
(*
let x_tm = to_num `11`;;
let list_tm = (rand o concl o eval_list_of_darts) test_list;;
(* 10: 0.396 *)
test 100 (eval_filter_nodes x_tm) list_tm;;
*)
let eval_list_of_nodes0 =
let th0 = (MY_RULE o prove)(`list_of_darts L = list /\ list_of_elements L = (s1:(num)list)
==> list_of_nodes L = MAP (\x. filter (\d. FST d = x) list) s1`, SIMP_TAC[list_of_nodes]) in
fun tm darts_th elements_th ->
let list_tm = (rand o concl) darts_th in
let s1_tm = (rand o concl) elements_th in
let th1 = (MY_PROVE_HYP darts_th o MY_PROVE_HYP elements_th o
INST[list_tm, list_var; s1_tm, s1_var_list; tm, l_cap_var]) th0 in
let rtm = rand (concl th1) in
let map_th = map_conv_univ (BETA_CONV THENC filter_nodes_conv) rtm in
TRANS th1 map_th;;
let eval_nodes_of_list0 =
let th0 = ISPEC l_cap_var nodes_of_list in
let op_tm = `MAP set_of_list : ((num#num)list)list->(num#num->bool)list` in
fun list_tm nodes_th ->
let th1 = INST[list_tm, l_cap_var] th0 in
let th2 = AP_TERM op_tm nodes_th in
let th3 = map_conv_univ set_of_list_conv ((rand o concl) th2) in
TRANS th1 (TRANS th2 th3);;
let eval_list_of_nodes tm =
eval_list_of_nodes0 tm (eval_list_of_darts tm) (eval_list_of_elements tm);;
(*
let darts_th = eval_list_of_darts test_list;;
let elements_th = eval_list_of_elements test_list;;
(* 10: 0.528 *)
test 10 (eval_list_of_nodes0 test_list darts_th) elements_th;;
*)
let build_table_of_nodes hyp_list nodes_th =
let table_of_nodes = Hashtbl.create 100 in
let th0 = (UNDISCH_ALL o ISPEC hyp_list) nodes_hypermap_of_list_all in
let all_tm = rator (concl th0) in
let th1 = EQ_MP (AP_TERM all_tm nodes_th) th0 in
let th1_list = get_all th1 in
let build1 th =
let th = MY_BETA_RULE th in
let list_tm = dest_list(rand(concl th)) in
let ths = get_all th in
let r = CONV_RULE (BETA_CONV THENC RAND_CONV set_of_list_conv) in
map (fun tm, th -> Hashtbl.add table_of_nodes (num_pair_hash tm) (r th)) (zip list_tm ths) in
let _ = map build1 th1_list in
table_of_nodes;;
(*
let nodes_th = eval_list_of_nodes test_list;;
(* 10: 0.156 *)
test 10 (build_table_of_nodes test_list) nodes_th;;
*)
(***************************)
(* table of faces *)
let build_table_of_faces hyp_list good_list_th faces_th =
let table_of_faces = Hashtbl.create 100 and
table_of_find_face = Hashtbl.create 100 in
let th0 = (MY_PROVE_HYP good_list_th o UNDISCH_ALL o ISPEC hyp_list) faces_hypermap_of_list_all in
let all_tm = rator (concl th0) in
let th1 = EQ_MP (AP_TERM all_tm faces_th) th0 in
let th1_list = get_all th1 in
let build1 th =
let th = MY_BETA_RULE th in
let list_tm = dest_list(rand(concl th)) in
let ths = get_all th in
map (fun tm, th ->
let th1, th2 = (CONJ_PAIR o CONV_RULE BETA_CONV) th in
let th1_2 = CONV_RULE (RAND_CONV set_of_list_conv) th1 in
let hash = num_pair_hash tm in
Hashtbl.add table_of_faces hash th1_2;
Hashtbl.add table_of_find_face hash th2) (zip list_tm ths) in
let _ = map build1 th1_list in
table_of_faces, table_of_find_face;;
(*
let faces_th = eval_list_of_faces test_list;;
let darts_th = eval_list_of_darts0 test_list faces_th;;
let good_list_th = eval_good_list0 test_list darts_th;;
let table1, table2 = build_table_of_faces test_list good_th faces_th;;
Hashtbl.find table1 "D7,D2D1";;
Hashtbl.find table2 "D7,D2D1";;
(* 10: 0.241 *)
test 10 (build_table_of_faces test_list good_th) faces_th;;
*)
(*****************************)
(* f_list_ext tables *)
let list_to_pair list = hd list, hd(tl list);;
let F_LIST_EXT_SINGLE, INV_F_LIST_EXT_SINGLE = (list_to_pair o CONJUNCTS o MY_RULE o prove)
(`f_list_ext_table L [h1] (x:num#num)
==> f_list_ext L h1 = x /\
inverse (f_list_ext L) x = h1`, SIMP_TAC[f_list_ext_table]);;
let F_LIST_EXT_CONS, INV_F_LIST_EXT_CONS = (list_to_pair o CONJUNCTS o MY_RULE o prove)
(`f_list_ext_table L (h1 :: h2 :: t) (x:num#num)
==> f_list_ext L h1 = h2 /\
inverse (f_list_ext L) h2 = h1`, SIMP_TAC[f_list_ext_table]);;
let F_LIST_EXT_TABLE_CONS = (MY_RULE o prove)
(`f_list_ext_table L (h1 :: t) (x:num#num) ==> f_list_ext_table L t x`,
DISJ_CASES_TAC (ISPEC `t:(num#num)list` list_CASES) THENL
[
ASM_REWRITE_TAC[f_list_ext_table];
POP_ASSUM STRIP_ASSUME_TAC THEN
ASM_SIMP_TAC[f_list_ext_table]
]);;
let f_list_ext_table_all th =
let ltm, x_tm = dest_comb(concl th) in
let ltm, list_tm = dest_comb ltm in
let l_tm = rand ltm in
let inst_t = INST[x_tm, x_var_pair] in
let f_single, inv_f_single = inst_t F_LIST_EXT_SINGLE, inst_t INV_F_LIST_EXT_SINGLE in
let f_cons, inv_f_cons = inst_t F_LIST_EXT_CONS, inst_t INV_F_LIST_EXT_CONS in
let f_table = inst_t F_LIST_EXT_TABLE_CONS in
let rec f_list_raw f_table_th h1_tm t1_tm =
if (is_comb t1_tm) then
let h2_tm', t2_tm = dest_comb t1_tm in
let h2_tm = rand h2_tm' in
let inst_t = MY_PROVE_HYP f_table_th o
INST[l_tm, l_cap_var; h1_tm, h1_var_pair; h2_tm, h2_var_pair; t2_tm, t_var_numnum_list] in
let f_th, inv_f_th = inst_t f_cons, inst_t inv_f_cons in
let th0 = (MY_PROVE_HYP f_table_th o INST[l_tm, l_cap_var; h1_tm, h1_var_pair; t1_tm, t_var_numnum_list]) f_table in
let f_list, inv_f_list = f_list_raw th0 h2_tm t2_tm in
(h1_tm, f_th) :: f_list, (h2_tm, inv_f_th) :: inv_f_list
else
let inst_t = MY_PROVE_HYP f_table_th o INST[l_tm, l_cap_var; h1_tm, h1_var_pair] in
let f_th, inv_f_th = inst_t f_single, inst_t inv_f_single in
[h1_tm, f_th], [x_tm, inv_f_th] in
if (is_comb list_tm) then
let h1_tm, t1_tm = dest_comb list_tm in
f_list_raw th (rand h1_tm) t1_tm
else
[], [];;
let build_f_list_ext_table =
let th0' = (UNDISCH_ALL o ISPEC l_cap_var) f_list_ext_table_list_of_faces in
fun hol_list good_list_th faces_th ->
let f_table, inv_f_table = Hashtbl.create 100, Hashtbl.create 100 in
let th0 = (MY_PROVE_HYP good_list_th o INST[hol_list, l_cap_var]) th0' in
let all_tm = rator (concl th0) in
let th1 = EQ_MP (AP_TERM all_tm faces_th) th0 in
let th1_list = get_all th1 in
let step th =
let th = MY_BETA_RULE th in
let ltm, rtm = dest_comb(concl th) in
let first_th = hd_conv rtm in
let f_table_th = EQ_MP (AP_TERM ltm first_th) th in
let f_list, inv_f_list = f_list_ext_table_all f_table_th in
let _ = map (fun tm, th -> Hashtbl.add f_table (num_pair_hash tm) th) f_list in
let _ = map (fun tm, th -> Hashtbl.add inv_f_table (num_pair_hash tm) th) inv_f_list in
() in
let _ = map step th1_list in
f_table, inv_f_table;;
(*
let faces_th = eval_list_of_faces test_list;;
let darts_th = eval_list_of_darts0 test_list faces_th;;
let good_th = eval_good_list0 test_list darts_th;;
let ft, ift = build_f_list_ext_table test_list good_th faces_th;;
Hashtbl.find ft "D7,D2D1";;
Hashtbl.find ift "D7,D2D1";;
(* 10: 0.056 *)
test 10 (build_f_list_ext_table test_list good_th) faces_th;;
*)
(**************************************)
(* compute_all *)
let compute_all hyp_list good_th_opt =
let thm_table = Hashtbl.create 10 in
let fun_table = Hashtbl.create 10 in
let faces_th = eval_list_of_faces hyp_list in
let darts_th = eval_list_of_darts0 hyp_list faces_th in
let good_th =
match good_th_opt with
| Some th -> th
| None -> eval_good_list0 hyp_list darts_th in
let add = fun str thm -> Hashtbl.add thm_table str thm in
let add_fun = fun str table -> Hashtbl.add fun_table str table in
let _ =
add "good_list" good_th;
add "list_of_darts" darts_th;
add "list_of_faces" faces_th in
let rec hyp_set name =
try Hashtbl.find thm_table name
with Not_found ->
(match name with
| "list_of_darts3" ->
let faces3_th = eval_list_of_faces3 hyp_list faces_th in
let darts3_th = eval_list_of_darts3 hyp_list faces3_th in
let _ = add "list_of_darts3" darts3_th in
darts3_th
| "list_of_darts4" ->
let faces4_th = eval_list_of_faces4 hyp_list faces_th in
let darts4_th = eval_list_of_darts4 hyp_list faces4_th in
let _ = add "list_of_darts4" darts4_th in
darts4_th
| "list_of_darts5" ->
let faces5_th = eval_list_of_faces5 hyp_list faces_th in
let darts5_th = eval_list_of_darts5 hyp_list faces5_th in
let _ = add "list_of_darts5" darts5_th in
darts5_th
| "list_of_darts6" ->
let faces6_th = eval_list_of_faces6 hyp_list faces_th in
let darts6_th = eval_list_of_darts6 hyp_list faces6_th in
let _ = add "list_of_darts6" darts6_th in
darts6_th
| "list_of_elements" ->
let elements_th = eval_list_of_elements hyp_list in
let _ = add "list_of_elements" elements_th in
elements_th
| "list_of_nodes" ->
let nodes_th = eval_list_of_nodes0 hyp_list darts_th (hyp_set "list_of_elements") in
let _ = add "list_of_nodes" nodes_th in
nodes_th
| "nodes_of_list" ->
let set_nodes_th = eval_nodes_of_list0 hyp_list (hyp_set "list_of_nodes") in
let _ = add "nodes_of_list" set_nodes_th in
set_nodes_th
| "faces_of_list" ->
let set_faces_th = eval_faces_of_list0 hyp_list (hyp_set "list_of_faces") in
let _ = add "faces_of_list" set_faces_th in
set_faces_th
| _ -> failwith ("Bad hypermap set: " ^ name)) in
let hyp_fun name dart_tm =
let table =
try Hashtbl.find fun_table name
with Not_found ->
(match name with
| "face" ->
let table_of_faces, table_of_find_face = build_table_of_faces hyp_list good_th faces_th in
let _ = add_fun "face" table_of_faces in
let _ = add_fun "find_face" table_of_find_face in
table_of_faces
| "find_face" ->
let table_of_faces, table_of_find_face = build_table_of_faces hyp_list good_th faces_th in
let _ = add_fun "face" table_of_faces in
let _ = add_fun "find_face" table_of_find_face in
table_of_find_face
| "node" ->
let table_of_nodes = build_table_of_nodes hyp_list (hyp_set "list_of_nodes") in
let _ = add_fun "node" table_of_nodes in
table_of_nodes
| "f_list_ext" | "inverse" ->
let f_table, inv_f_table = build_f_list_ext_table hyp_list good_th faces_th in
let _ = add_fun "f_list_ext" f_table in
let _ = add_fun "inverse" inv_f_table in
if name = "inverse" then inv_f_table else f_table
| _ -> failwith ("Bad hypermap function: " ^ name)) in
try Hashtbl.find table (num_pair_hash dart_tm)
with Not_found -> failwith ("Bad dart index: " ^ num_pair_hash dart_tm) in
hyp_set, hyp_fun;;
let add_eq eq1_th eq2_th =
let th0 = MK_COMB (AP_TERM add_op_num eq1_th, eq2_th) in
let r_th = raw_add_conv_hash (rand (concl th0)) in
TRANS th0 r_th;;
let mul_eq eq1_th eq2_th =
let th0 = MK_COMB (AP_TERM mul_op_num eq1_th, eq2_th) in
let r_th = raw_mul_conv_hash (rand (concl th0)) in
TRANS th0 r_th;;
let eq_eq eq1_th eq2_th =
let th0 = MK_COMB (AP_TERM eq_op_num eq1_th, eq2_th) in
let r_th = raw_eq_hash_conv (rand (concl th0)) in
TRANS th0 r_th;;
let eval_good_list_nodes_condition0 =
let two = to_num `2` and
four = to_num `4` in
fun elements_th darts_th faces_th ->
let length_darts = apply_op darts_th eval_length and
length_faces = apply_op faces_th eval_length and
length_elements = apply_op elements_th eval_length in
(* 2 * (sizel (list_of_elements L) + sizel (list_of_faces L)) = sizel (list_of_darts L) + 4 *)
let (+), ( * ), (!), (==) = add_eq, mul_eq, REFL, eq_eq in
(!two * (length_elements + length_faces)) == (length_darts + !four);;
let eval_good_list_nodes_condition hyp_set =
eval_good_list_nodes_condition0 (hyp_set "list_of_elements") (hyp_set "list_of_darts") (hyp_set "list_of_faces");;
end;;
(*
open List_hypermap_computations;;
let t1, t2 = compute_all test_list None;;
(* 10: 2.635 *)
test 10 (compute_all test_list) None;;
num_pair_hash (to_num `1,0`);;
t2 "node" (to_num `0,1`);;
*)