44 datatype sum_tree |
44 datatype sum_tree |
45 = Leaf of typ |
45 = Leaf of typ |
46 | Branch of (typ * (typ * sum_tree) * (typ * sum_tree)) |
46 | Branch of (typ * (typ * sum_tree) * (typ * sum_tree)) |
47 |
47 |
48 type sum_path = bool list (* true: left, false: right *) |
48 type sum_path = bool list (* true: left, false: right *) |
49 |
49 |
50 fun sum_type_of (Leaf T) = T |
50 fun sum_type_of (Leaf T) = T |
51 | sum_type_of (Branch (ST,(LT,_),(RT,_))) = ST |
51 | sum_type_of (Branch (ST,(LT,_),(RT,_))) = ST |
52 |
52 |
53 |
53 |
54 fun mk_tree Ts = |
54 fun mk_tree Ts = |
55 let |
55 let |
56 fun mk_tree' 1 [T] = (T, Leaf T, [[]]) |
56 fun mk_tree' 1 [T] = (T, Leaf T, [[]]) |
57 | mk_tree' n Ts = |
57 | mk_tree' n Ts = |
58 let |
58 let |
59 val n2 = n div 2 |
59 val n2 = n div 2 |
60 val (lTs, rTs) = chop n2 Ts |
60 val (lTs, rTs) = chop n2 Ts |
61 val (TL, ltree, lpaths) = mk_tree' n2 lTs |
61 val (TL, ltree, lpaths) = mk_tree' n2 lTs |
62 val (TR, rtree, rpaths) = mk_tree' (n - n2) rTs |
62 val (TR, rtree, rpaths) = mk_tree' (n - n2) rTs |
63 val T = mk_sumT TL TR |
63 val T = mk_sumT TL TR |
64 val pths = map (cons true) lpaths @ map (cons false) rpaths |
64 val pths = map (cons true) lpaths @ map (cons false) rpaths |
65 in |
65 in |
66 (T, Branch (T, (TL, ltree), (TR, rtree)), pths) |
66 (T, Branch (T, (TL, ltree), (TR, rtree)), pths) |
67 end |
67 end |
68 in |
68 in |
69 mk_tree' (length Ts) Ts |
69 mk_tree' (length Ts) Ts |
70 end |
70 end |
71 |
71 |
72 |
72 |
73 fun mk_tree_distinct Ts = |
73 fun mk_tree_distinct Ts = |
74 let |
74 let |
75 fun insert_once T Ts = |
75 fun insert_once T Ts = |
76 let |
76 let |
77 val i = find_index_eq T Ts |
77 val i = find_index_eq T Ts |
78 in |
78 in |
79 if i = ~1 then (length Ts, Ts @ [T]) else (i, Ts) |
79 if i = ~1 then (length Ts, Ts @ [T]) else (i, Ts) |
80 end |
80 end |
81 |
81 |
82 val (idxs, dist_Ts) = fold_map insert_once Ts [] |
82 val (idxs, dist_Ts) = fold_map insert_once Ts [] |
83 |
83 |
84 val (ST, tree, pths) = mk_tree dist_Ts |
84 val (ST, tree, pths) = mk_tree dist_Ts |
85 in |
85 in |
86 (ST, tree, map (nth pths) idxs) |
86 (ST, tree, map (nth pths) idxs) |
87 end |
87 end |
88 |
88 |
102 | mk_proj _ _ _ = sys_error "mk_proj" |
102 | mk_proj _ _ _ = sys_error "mk_proj" |
103 |
103 |
104 |
104 |
105 fun mk_sumcases tree T ts = |
105 fun mk_sumcases tree T ts = |
106 let |
106 let |
107 fun mk_sumcases' (Leaf _) (t::ts) = (t,ts) |
107 fun mk_sumcases' (Leaf _) (t::ts) = (t,ts) |
108 | mk_sumcases' (Branch (ST, (LT, ltr), (RT, rtr))) ts = |
108 | mk_sumcases' (Branch (ST, (LT, ltr), (RT, rtr))) ts = |
109 let |
109 let |
110 val (lcase, ts') = mk_sumcases' ltr ts |
110 val (lcase, ts') = mk_sumcases' ltr ts |
111 val (rcase, ts'') = mk_sumcases' rtr ts' |
111 val (rcase, ts'') = mk_sumcases' rtr ts' |
112 in |
112 in |
113 (mk_sumcase LT RT T lcase rcase, ts'') |
113 (mk_sumcase LT RT T lcase rcase, ts'') |
114 end |
114 end |
115 | mk_sumcases' _ [] = sys_error "mk_sumcases" |
115 | mk_sumcases' _ [] = sys_error "mk_sumcases" |
116 in |
116 in |
117 fst (mk_sumcases' tree ts) |
117 fst (mk_sumcases' tree ts) |
118 end |
118 end |
119 |
119 |
120 end |
120 end |
121 |
121 |
122 |
122 |
123 |
123 |
124 |
124 |