author | wenzelm |
Wed, 29 Mar 2023 12:02:34 +0200 | |
changeset 77740 | 19c539f5d4d3 |
parent 77739 | 2225d3267f58 |
child 77741 | 1951f6470792 |
permissions | -rw-r--r-- |
6118 | 1 |
(* Title: Pure/General/table.ML |
15014 | 2 |
Author: Markus Wenzel and Stefan Berghofer, TU Muenchen |
5015 | 3 |
|
16342 | 4 |
Generic tables. Efficient purely functional implementation using |
5 |
balanced 2-3 trees. |
|
5015 | 6 |
*) |
7 |
||
8 |
signature KEY = |
|
9 |
sig |
|
10 |
type key |
|
70586 | 11 |
val ord: key ord |
5015 | 12 |
end; |
13 |
||
14 |
signature TABLE = |
|
15 |
sig |
|
77731 | 16 |
structure Key: KEY |
5015 | 17 |
type key |
18 |
type 'a table |
|
19 |
exception DUP of key |
|
19031 | 20 |
exception SAME |
15014 | 21 |
exception UNDEF of key |
5015 | 22 |
val empty: 'a table |
74232 | 23 |
val build: ('a table -> 'a table) -> 'a table |
5015 | 24 |
val is_empty: 'a table -> bool |
67537 | 25 |
val is_single: 'a table -> bool |
39020 | 26 |
val map: (key -> 'a -> 'b) -> 'a table -> 'b table |
16446 | 27 |
val fold: (key * 'b -> 'a -> 'a) -> 'b table -> 'a -> 'a |
28334 | 28 |
val fold_rev: (key * 'b -> 'a -> 'a) -> 'b table -> 'a -> 'a |
5015 | 29 |
val dest: 'a table -> (key * 'a) list |
5681 | 30 |
val keys: 'a table -> key list |
52049 | 31 |
val min: 'a table -> (key * 'a) option |
32 |
val max: 'a table -> (key * 'a) option |
|
27508 | 33 |
val exists: (key * 'a -> bool) -> 'a table -> bool |
34 |
val forall: (key * 'a -> bool) -> 'a table -> bool |
|
74227 | 35 |
val get_first: (key * 'a -> 'b option) -> 'a table -> 'b option |
43792
d5803c3d537a
Table.lookup_key and Graph.get_entry allow to retrieve the original key, which is not necessarily identical to the given one;
wenzelm
parents:
39020
diff
changeset
|
36 |
val lookup_key: 'a table -> key -> (key * 'a) option |
31616 | 37 |
val lookup: 'a table -> key -> 'a option |
16887 | 38 |
val defined: 'a table -> key -> bool |
31209 | 39 |
val update: key * 'a -> 'a table -> 'a table |
40 |
val update_new: key * 'a -> 'a table -> 'a table (*exception DUP*) |
|
17179 | 41 |
val default: key * 'a -> 'a table -> 'a table |
56051 | 42 |
val map_entry: key -> ('a -> 'a) (*exception SAME*) -> 'a table -> 'a table |
31209 | 43 |
val map_default: key * 'a -> ('a -> 'a) -> 'a table -> 'a table |
23655
d2d1138e0ddc
replaced exception TableFun/GraphFun.DUPS by TableFun/GraphFun.DUP;
wenzelm
parents:
21065
diff
changeset
|
44 |
val make: (key * 'a) list -> 'a table (*exception DUP*) |
56051 | 45 |
val join: (key -> 'a * 'a -> 'a) (*exception SAME*) -> |
23655
d2d1138e0ddc
replaced exception TableFun/GraphFun.DUPS by TableFun/GraphFun.DUP;
wenzelm
parents:
21065
diff
changeset
|
46 |
'a table * 'a table -> 'a table (*exception DUP*) |
d2d1138e0ddc
replaced exception TableFun/GraphFun.DUPS by TableFun/GraphFun.DUP;
wenzelm
parents:
21065
diff
changeset
|
47 |
val merge: ('a * 'a -> bool) -> 'a table * 'a table -> 'a table (*exception DUP*) |
15665 | 48 |
val delete: key -> 'a table -> 'a table (*exception UNDEF*) |
15761 | 49 |
val delete_safe: key -> 'a table -> 'a table |
16466 | 50 |
val member: ('b * 'a -> bool) -> 'a table -> key * 'b -> bool |
15761 | 51 |
val insert: ('a * 'a -> bool) -> key * 'a -> 'a table -> 'a table (*exception DUP*) |
16139 | 52 |
val remove: ('b * 'a -> bool) -> key * 'b -> 'a table -> 'a table |
18946 | 53 |
val lookup_list: 'a list table -> key -> 'a list |
31209 | 54 |
val cons_list: key * 'a -> 'a list table -> 'a list table |
19506 | 55 |
val insert_list: ('a * 'a -> bool) -> key * 'a -> 'a list table -> 'a list table |
18946 | 56 |
val remove_list: ('b * 'a -> bool) -> key * 'b -> 'a list table -> 'a list table |
25391 | 57 |
val update_list: ('a * 'a -> bool) -> key * 'a -> 'a list table -> 'a list table |
18946 | 58 |
val make_list: (key * 'a) list -> 'a list table |
59 |
val dest_list: 'a list table -> (key * 'a) list |
|
33162 | 60 |
val merge_list: ('a * 'a -> bool) -> 'a list table * 'a list table -> 'a list table |
50234 | 61 |
type set = unit table |
63511 | 62 |
val insert_set: key -> set -> set |
67529 | 63 |
val remove_set: key -> set -> set |
59012
f4e9bd04e1d5
clarified Table.make_set: duplicate arguments are allowed, like Table.make_list or Scala Set() formation;
wenzelm
parents:
56051
diff
changeset
|
64 |
val make_set: key list -> set |
5015 | 65 |
end; |
66 |
||
31971
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
wenzelm
parents:
31621
diff
changeset
|
67 |
functor Table(Key: KEY): TABLE = |
5015 | 68 |
struct |
69 |
||
77733 | 70 |
(* keys *) |
71 |
||
77731 | 72 |
structure Key = Key; |
73 |
type key = Key.key; |
|
5015 | 74 |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
75 |
val eq_key = is_equal o Key.ord; |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
76 |
|
77733 | 77 |
exception DUP of key; |
78 |
||
5015 | 79 |
|
77731 | 80 |
(* datatype *) |
5015 | 81 |
|
82 |
datatype 'a table = |
|
83 |
Empty | |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
84 |
Leaf1 of key * 'a | |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
85 |
Leaf2 of (key * 'a) * (key * 'a) | |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
86 |
Leaf3 of (key * 'a) * (key * 'a) * (key * 'a) | |
5015 | 87 |
Branch2 of 'a table * (key * 'a) * 'a table | |
88 |
Branch3 of 'a table * (key * 'a) * 'a table * (key * 'a) * 'a table; |
|
89 |
||
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
90 |
(*literal copy from set.ML*) |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
91 |
fun make2 (Empty, e, Empty) = Leaf1 e |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
92 |
| make2 (Branch2 (Empty, e1, Empty), e2, right) = make2 (Leaf1 e1, e2, right) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
93 |
| make2 (left, e1, Branch2 (Empty, e2, Empty)) = make2 (left, e1, Leaf1 e2) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
94 |
| make2 (Branch3 (Empty, e1, Empty, e2, Empty), e3, right) = make2 (Leaf2 (e1, e2), e3, right) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
95 |
| make2 (left, e1, Branch3 (Empty, e2, Empty, e3, Empty)) = make2 (left, e1, Leaf2 (e2, e3)) |
77739 | 96 |
| make2 (Leaf1 e1, e2, Empty) = Leaf2 (e1, e2) |
97 |
| make2 (Empty, e1, Leaf1 e2) = Leaf2 (e1, e2) |
|
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
98 |
| make2 (Leaf1 e1, e2, Leaf1 e3) = Leaf3 (e1, e2, e3) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
99 |
| make2 (Leaf2 (e1, e2), e3, Empty) = Leaf3 (e1, e2, e3) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
100 |
| make2 (Empty, e1, Leaf2 (e2, e3)) = Leaf3 (e1, e2, e3) |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
101 |
| make2 arg = Branch2 arg; |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
102 |
|
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
103 |
(*literal copy from set.ML*) |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
104 |
fun make3 (Empty, e1, Empty, e2, Empty) = Leaf2 (e1, e2) |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
105 |
| make3 (Branch2 (Empty, e1, Empty), e2, mid, e3, right) = make3 (Leaf1 e1, e2, mid, e3, right) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
106 |
| make3 (left, e1, Branch2 (Empty, e2, Empty), e3, right) = make3 (left, e1, Leaf1 e2, e3, right) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
107 |
| make3 (left, e1, mid, e2, Branch2 (Empty, e3, Empty)) = make3 (left, e1, mid, e2, Leaf1 e3) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
108 |
| make3 (Leaf1 e1, e2, Empty, e3, Empty) = Leaf3 (e1, e2, e3) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
109 |
| make3 (Empty, e1, Leaf1 e2, e3, Empty) = Leaf3 (e1, e2, e3) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
110 |
| make3 (Empty, e1, Empty, e2, Leaf1 e3) = Leaf3 (e1, e2, e3) |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
111 |
| make3 arg = Branch3 arg; |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
112 |
|
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
113 |
(*literal copy from set.ML*) |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
114 |
fun unmake (Leaf1 e) = Branch2 (Empty, e, Empty) |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
115 |
| unmake (Leaf2 (e1, e2)) = Branch3 (Empty, e1, Empty, e2, Empty) |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
116 |
| unmake (Leaf3 (e1, e2, e3)) = |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
117 |
Branch2 (Branch2 (Empty, e1, Empty), e2, Branch2 (Empty, e3, Empty)) |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
118 |
| unmake arg = arg; |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
119 |
|
5015 | 120 |
|
67537 | 121 |
(* empty and single *) |
5681 | 122 |
|
5015 | 123 |
val empty = Empty; |
124 |
||
74232 | 125 |
fun build (f: 'a table -> 'a table) = f empty; |
126 |
||
5015 | 127 |
fun is_empty Empty = true |
128 |
| is_empty _ = false; |
|
129 |
||
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
130 |
fun is_single (Leaf1 _) = true |
67537 | 131 |
| is_single _ = false; |
132 |
||
5681 | 133 |
|
134 |
(* map and fold combinators *) |
|
135 |
||
16657 | 136 |
fun map_table f = |
137 |
let |
|
138 |
fun map Empty = Empty |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
139 |
| map (Leaf1 (k, x)) = Leaf1 (k, f k x) |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
140 |
| map (Leaf2 ((k1, x1), (k2, x2))) = Leaf2 ((k1, f k1 x1), (k2, f k2 x2)) |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
141 |
| map (Leaf3 ((k1, x1), (k2, x2), (k3, x3))) = |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
142 |
Leaf3 ((k1, f k1 x1), (k2, f k2 x2), (k3, f k3 x3)) |
16657 | 143 |
| map (Branch2 (left, (k, x), right)) = |
144 |
Branch2 (map left, (k, f k x), map right) |
|
145 |
| map (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = |
|
146 |
Branch3 (map left, (k1, f k1 x1), map mid, (k2, f k2 x2), map right); |
|
147 |
in map end; |
|
5681 | 148 |
|
16657 | 149 |
fun fold_table f = |
150 |
let |
|
151 |
fun fold Empty x = x |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
152 |
| fold (Leaf1 e) x = f e x |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
153 |
| fold (Leaf2 (e1, e2)) x = f e2 (f e1 x) |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
154 |
| fold (Leaf3 (e1, e2, e3)) x = f e3 (f e2 (f e1 x)) |
77727
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
155 |
| fold (Branch2 (left, e, right)) x = |
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
156 |
fold right (f e (fold left x)) |
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
157 |
| fold (Branch3 (left, e1, mid, e2, right)) x = |
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
158 |
fold right (f e2 (fold mid (f e1 (fold left x)))); |
16657 | 159 |
in fold end; |
5681 | 160 |
|
28334 | 161 |
fun fold_rev_table f = |
162 |
let |
|
77732 | 163 |
fun fold_rev Empty x = x |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
164 |
| fold_rev (Leaf1 e) x = f e x |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
165 |
| fold_rev (Leaf2 (e1, e2)) x = f e1 (f e2 x) |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
166 |
| fold_rev (Leaf3 (e1, e2, e3)) x = f e1 (f e2 (f e3 x)) |
77732 | 167 |
| fold_rev (Branch2 (left, e, right)) x = |
168 |
fold_rev left (f e (fold_rev right x)) |
|
169 |
| fold_rev (Branch3 (left, e1, mid, e2, right)) x = |
|
170 |
fold_rev left (f e1 (fold_rev mid (f e2 (fold_rev right x)))); |
|
171 |
in fold_rev end; |
|
28334 | 172 |
|
173 |
fun dest tab = fold_rev_table cons tab []; |
|
174 |
fun keys tab = fold_rev_table (cons o #1) tab []; |
|
16192 | 175 |
|
27508 | 176 |
|
52049 | 177 |
(* min/max entries *) |
5015 | 178 |
|
52049 | 179 |
fun min Empty = NONE |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
180 |
| min (Leaf1 e) = SOME e |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
181 |
| min (Leaf2 (e, _)) = SOME e |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
182 |
| min (Leaf3 (e, _, _)) = SOME e |
77727
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
183 |
| min (Branch2 (Empty, e, _)) = SOME e |
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
184 |
| min (Branch3 (Empty, e, _, _, _)) = SOME e |
52049 | 185 |
| min (Branch2 (left, _, _)) = min left |
186 |
| min (Branch3 (left, _, _, _, _)) = min left; |
|
8409 | 187 |
|
52049 | 188 |
fun max Empty = NONE |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
189 |
| max (Leaf1 e) = SOME e |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
190 |
| max (Leaf2 (_, e)) = SOME e |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
191 |
| max (Leaf3 (_, _, e)) = SOME e |
77727
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
192 |
| max (Branch2 (_, e, Empty)) = SOME e |
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
193 |
| max (Branch3 (_, _, _, e, Empty)) = SOME e |
52049 | 194 |
| max (Branch2 (_, _, right)) = max right |
195 |
| max (Branch3 (_, _, _, _, right)) = max right; |
|
15665 | 196 |
|
5015 | 197 |
|
74227 | 198 |
(* exists and forall *) |
199 |
||
200 |
fun exists pred = |
|
201 |
let |
|
202 |
fun ex Empty = false |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
203 |
| ex (Leaf1 e) = pred e |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
204 |
| ex (Leaf2 (e1, e2)) = pred e1 orelse pred e2 |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
205 |
| ex (Leaf3 (e1, e2, e3)) = pred e1 orelse pred e2 orelse pred e3 |
77727
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
206 |
| ex (Branch2 (left, e, right)) = |
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
207 |
ex left orelse pred e orelse ex right |
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
208 |
| ex (Branch3 (left, e1, mid, e2, right)) = |
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
209 |
ex left orelse pred e1 orelse ex mid orelse pred e2 orelse ex right; |
74227 | 210 |
in ex end; |
211 |
||
212 |
fun forall pred = not o exists (not o pred); |
|
213 |
||
214 |
||
31616 | 215 |
(* get_first *) |
216 |
||
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
217 |
fun get_first f = |
31616 | 218 |
let |
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
219 |
fun get Empty = NONE |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
220 |
| get (Leaf1 e) = f e |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
221 |
| get (Leaf2 (e1, e2)) = |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
222 |
(case f e1 of |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
223 |
NONE => f e2 |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
224 |
| some => some) |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
225 |
| get (Leaf3 (e1, e2, e3)) = |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
226 |
(case f e1 of |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
227 |
NONE => |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
228 |
(case f e2 of |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
229 |
NONE => f e3 |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
230 |
| some => some) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
231 |
| some => some) |
77727
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
232 |
| get (Branch2 (left, e, right)) = |
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
233 |
(case get left of |
31616 | 234 |
NONE => |
77727
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
235 |
(case f e of |
31616 | 236 |
NONE => get right |
237 |
| some => some) |
|
238 |
| some => some) |
|
77727
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
239 |
| get (Branch3 (left, e1, mid, e2, right)) = |
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
240 |
(case get left of |
31616 | 241 |
NONE => |
77727
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
242 |
(case f e1 of |
31616 | 243 |
NONE => |
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
244 |
(case get mid of |
31616 | 245 |
NONE => |
77727
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
wenzelm
parents:
77721
diff
changeset
|
246 |
(case f e2 of |
31616 | 247 |
NONE => get right |
248 |
| some => some) |
|
249 |
| some => some) |
|
250 |
| some => some) |
|
251 |
| some => some); |
|
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
252 |
in get end; |
31616 | 253 |
|
254 |
||
5015 | 255 |
(* lookup *) |
256 |
||
67557 | 257 |
fun lookup tab key = |
258 |
let |
|
259 |
fun look Empty = NONE |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
260 |
| look (Leaf1 (k, x)) = |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
261 |
if eq_key (key, k) then SOME x else NONE |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
262 |
| look (Leaf2 ((k1, x1), (k2, x2))) = |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
263 |
(case Key.ord (key, k1) of |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
264 |
LESS => NONE |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
265 |
| EQUAL => SOME x1 |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
266 |
| GREATER => if eq_key (key, k2) then SOME x2 else NONE) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
267 |
| look (Leaf3 ((k1, x1), (k2, x2), (k3, x3))) = |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
268 |
(case Key.ord (key, k2) of |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
269 |
LESS => if eq_key (key, k1) then SOME x1 else NONE |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
270 |
| EQUAL => SOME x2 |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
271 |
| GREATER => if eq_key (key, k3) then SOME x3 else NONE) |
67557 | 272 |
| look (Branch2 (left, (k, x), right)) = |
273 |
(case Key.ord (key, k) of |
|
274 |
LESS => look left |
|
275 |
| EQUAL => SOME x |
|
276 |
| GREATER => look right) |
|
277 |
| look (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = |
|
278 |
(case Key.ord (key, k1) of |
|
279 |
LESS => look left |
|
280 |
| EQUAL => SOME x1 |
|
281 |
| GREATER => |
|
282 |
(case Key.ord (key, k2) of |
|
283 |
LESS => look mid |
|
284 |
| EQUAL => SOME x2 |
|
285 |
| GREATER => look right)); |
|
286 |
in look tab end; |
|
287 |
||
43792
d5803c3d537a
Table.lookup_key and Graph.get_entry allow to retrieve the original key, which is not necessarily identical to the given one;
wenzelm
parents:
39020
diff
changeset
|
288 |
fun lookup_key tab key = |
19031 | 289 |
let |
290 |
fun look Empty = NONE |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
291 |
| look (Leaf1 (k, x)) = |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
292 |
if eq_key (key, k) then SOME (k, x) else NONE |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
293 |
| look (Leaf2 ((k1, x1), (k2, x2))) = |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
294 |
(case Key.ord (key, k1) of |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
295 |
LESS => NONE |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
296 |
| EQUAL => SOME (k1, x1) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
297 |
| GREATER => if eq_key (key, k2) then SOME (k2, x2) else NONE) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
298 |
| look (Leaf3 ((k1, x1), (k2, x2), (k3, x3))) = |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
299 |
(case Key.ord (key, k2) of |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
300 |
LESS => if eq_key (key, k1) then SOME (k1, x1) else NONE |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
301 |
| EQUAL => SOME (k2, x2) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
302 |
| GREATER => if eq_key (key, k3) then SOME (k3, x3) else NONE) |
19031 | 303 |
| look (Branch2 (left, (k, x), right)) = |
304 |
(case Key.ord (key, k) of |
|
305 |
LESS => look left |
|
43792
d5803c3d537a
Table.lookup_key and Graph.get_entry allow to retrieve the original key, which is not necessarily identical to the given one;
wenzelm
parents:
39020
diff
changeset
|
306 |
| EQUAL => SOME (k, x) |
19031 | 307 |
| GREATER => look right) |
308 |
| look (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = |
|
309 |
(case Key.ord (key, k1) of |
|
310 |
LESS => look left |
|
43792
d5803c3d537a
Table.lookup_key and Graph.get_entry allow to retrieve the original key, which is not necessarily identical to the given one;
wenzelm
parents:
39020
diff
changeset
|
311 |
| EQUAL => SOME (k1, x1) |
19031 | 312 |
| GREATER => |
313 |
(case Key.ord (key, k2) of |
|
314 |
LESS => look mid |
|
43792
d5803c3d537a
Table.lookup_key and Graph.get_entry allow to retrieve the original key, which is not necessarily identical to the given one;
wenzelm
parents:
39020
diff
changeset
|
315 |
| EQUAL => SOME (k2, x2) |
19031 | 316 |
| GREATER => look right)); |
317 |
in look tab end; |
|
5015 | 318 |
|
19031 | 319 |
fun defined tab key = |
320 |
let |
|
321 |
fun def Empty = false |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
322 |
| def (Leaf1 (k, _)) = eq_key (key, k) |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
323 |
| def (Leaf2 ((k1, _), (k2, _))) = |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
324 |
(case Key.ord (key, k1) of |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
325 |
LESS => false |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
326 |
| EQUAL => true |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
327 |
| GREATER => eq_key (key, k2)) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
328 |
| def (Leaf3 ((k1, _), (k2, _), (k3, _))) = |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
329 |
(case Key.ord (key, k2) of |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
330 |
LESS => eq_key (key, k1) |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
331 |
| EQUAL => true |
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
332 |
| GREATER => eq_key (key, k3)) |
77735 | 333 |
| def (Branch2 (left, (k, _), right)) = |
19031 | 334 |
(case Key.ord (key, k) of |
335 |
LESS => def left |
|
336 |
| EQUAL => true |
|
337 |
| GREATER => def right) |
|
77735 | 338 |
| def (Branch3 (left, (k1, _), mid, (k2, _), right)) = |
19031 | 339 |
(case Key.ord (key, k1) of |
340 |
LESS => def left |
|
341 |
| EQUAL => true |
|
342 |
| GREATER => |
|
343 |
(case Key.ord (key, k2) of |
|
344 |
LESS => def mid |
|
345 |
| EQUAL => true |
|
346 |
| GREATER => def right)); |
|
347 |
in def tab end; |
|
16887 | 348 |
|
5015 | 349 |
|
19031 | 350 |
(* modify *) |
5015 | 351 |
|
352 |
datatype 'a growth = |
|
353 |
Stay of 'a table | |
|
354 |
Sprout of 'a table * (key * 'a) * 'a table; |
|
355 |
||
15761 | 356 |
exception SAME; |
357 |
||
15665 | 358 |
fun modify key f tab = |
359 |
let |
|
360 |
fun modfy Empty = Sprout (Empty, (key, f NONE), Empty) |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
361 |
| modfy (t as Leaf1 _) = modfy (unmake t) |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
362 |
| modfy (t as Leaf2 _) = modfy (unmake t) |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
363 |
| modfy (t as Leaf3 _) = modfy (unmake t) |
15665 | 364 |
| modfy (Branch2 (left, p as (k, x), right)) = |
365 |
(case Key.ord (key, k) of |
|
366 |
LESS => |
|
367 |
(case modfy left of |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
368 |
Stay left' => Stay (make2 (left', p, right)) |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
369 |
| Sprout (left1, q, left2) => Stay (make3 (left1, q, left2, p, right))) |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
370 |
| EQUAL => Stay (make2 (left, (k, f (SOME x)), right)) |
15665 | 371 |
| GREATER => |
372 |
(case modfy right of |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
373 |
Stay right' => Stay (make2 (left, p, right')) |
15665 | 374 |
| Sprout (right1, q, right2) => |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
375 |
Stay (make3 (left, p, right1, q, right2)))) |
15665 | 376 |
| modfy (Branch3 (left, p1 as (k1, x1), mid, p2 as (k2, x2), right)) = |
377 |
(case Key.ord (key, k1) of |
|
5015 | 378 |
LESS => |
15665 | 379 |
(case modfy left of |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
380 |
Stay left' => Stay (make3 (left', p1, mid, p2, right)) |
15665 | 381 |
| Sprout (left1, q, left2) => |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
382 |
Sprout (make2 (left1, q, left2), p1, make2 (mid, p2, right))) |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
383 |
| EQUAL => Stay (make3 (left, (k1, f (SOME x1)), mid, p2, right)) |
5015 | 384 |
| GREATER => |
15665 | 385 |
(case Key.ord (key, k2) of |
386 |
LESS => |
|
387 |
(case modfy mid of |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
388 |
Stay mid' => Stay (make3 (left, p1, mid', p2, right)) |
15665 | 389 |
| Sprout (mid1, q, mid2) => |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
390 |
Sprout (make2 (left, p1, mid1), q, make2 (mid2, p2, right))) |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
391 |
| EQUAL => Stay (make3 (left, p1, mid, (k2, f (SOME x2)), right)) |
15665 | 392 |
| GREATER => |
393 |
(case modfy right of |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
394 |
Stay right' => Stay (make3 (left, p1, mid, p2, right')) |
15665 | 395 |
| Sprout (right1, q, right2) => |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
396 |
Sprout (make2 (left, p1, mid), p2, make2 (right1, q, right2))))); |
5015 | 397 |
|
15665 | 398 |
in |
399 |
(case modfy tab of |
|
400 |
Stay tab' => tab' |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
401 |
| Sprout br => make2 br) |
15665 | 402 |
handle SAME => tab |
403 |
end; |
|
5015 | 404 |
|
17412 | 405 |
fun update (key, x) tab = modify key (fn _ => x) tab; |
406 |
fun update_new (key, x) tab = modify key (fn NONE => x | SOME _ => raise DUP key) tab; |
|
17709 | 407 |
fun default (key, x) tab = modify key (fn NONE => x | SOME _ => raise SAME) tab; |
15761 | 408 |
fun map_entry key f = modify key (fn NONE => raise SAME | SOME x => f x); |
27783 | 409 |
fun map_default (key, x) f = modify key (fn NONE => f x | SOME y => f y); |
5015 | 410 |
|
411 |
||
15014 | 412 |
(* delete *) |
413 |
||
15665 | 414 |
exception UNDEF of key; |
415 |
||
416 |
local |
|
417 |
||
77735 | 418 |
fun compare NONE _ = LESS |
15665 | 419 |
| compare (SOME k1) (k2, _) = Key.ord (k1, k2); |
15014 | 420 |
|
77737 | 421 |
fun if_equal ord x y = if is_equal ord then x else y; |
15014 | 422 |
|
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
423 |
(*literal copy from set.ML*) |
15531 | 424 |
fun del (SOME k) Empty = raise UNDEF k |
77735 | 425 |
| del NONE Empty = raise Match |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
426 |
| del NONE (Leaf1 p) = (p, (true, Empty)) |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
427 |
| del NONE (Leaf2 (p, q)) = (p, (false, Leaf1 q)) |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
428 |
| del k (Leaf1 p) = |
77721 | 429 |
(case compare k p of |
430 |
EQUAL => (p, (true, Empty)) |
|
431 |
| _ => raise UNDEF (the k)) |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
432 |
| del k (Leaf2 (p, q)) = |
77721 | 433 |
(case compare k p of |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
434 |
EQUAL => (p, (false, Leaf1 q)) |
77721 | 435 |
| _ => |
436 |
(case compare k q of |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
437 |
EQUAL => (q, (false, Leaf1 p)) |
77721 | 438 |
| _ => raise UNDEF (the k))) |
77740
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
wenzelm
parents:
77739
diff
changeset
|
439 |
| del k (Leaf3 (p, q, r)) = del k (Branch2 (Leaf1 p, q, Leaf1 r)) |
77721 | 440 |
| del k (Branch2 (l, p, r)) = |
441 |
(case compare k p of |
|
442 |
LESS => |
|
443 |
(case del k l of |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
444 |
(p', (false, l')) => (p', (false, make2 (l', p, r))) |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
445 |
| (p', (true, l')) => (p', case unmake r of |
77721 | 446 |
Branch2 (rl, rp, rr) => |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
447 |
(true, make3 (l', p, rl, rp, rr)) |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
448 |
| Branch3 (rl, rp, rm, rq, rr) => (false, make2 |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
449 |
(make2 (l', p, rl), rp, make2 (rm, rq, rr))))) |
77721 | 450 |
| ord => |
77737 | 451 |
(case del (if_equal ord NONE k) r of |
452 |
(p', (false, r')) => (p', (false, make2 (l, if_equal ord p' p, r'))) |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
453 |
| (p', (true, r')) => (p', case unmake l of |
77721 | 454 |
Branch2 (ll, lp, lr) => |
77737 | 455 |
(true, make3 (ll, lp, lr, if_equal ord p' p, r')) |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
456 |
| Branch3 (ll, lp, lm, lq, lr) => (false, make2 |
77737 | 457 |
(make2 (ll, lp, lm), lq, make2 (lr, if_equal ord p' p, r')))))) |
77721 | 458 |
| del k (Branch3 (l, p, m, q, r)) = |
459 |
(case compare k q of |
|
460 |
LESS => |
|
461 |
(case compare k p of |
|
462 |
LESS => |
|
463 |
(case del k l of |
|
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
464 |
(p', (false, l')) => (p', (false, make3 (l', p, m, q, r))) |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
465 |
| (p', (true, l')) => (p', (false, case (unmake m, unmake r) of |
77721 | 466 |
(Branch2 (ml, mp, mr), Branch2 _) => |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
467 |
make2 (make3 (l', p, ml, mp, mr), q, r) |
77721 | 468 |
| (Branch3 (ml, mp, mm, mq, mr), _) => |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
469 |
make3 (make2 (l', p, ml), mp, make2 (mm, mq, mr), q, r) |
77721 | 470 |
| (Branch2 (ml, mp, mr), Branch3 (rl, rp, rm, rq, rr)) => |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
471 |
make3 (make2 (l', p, ml), mp, make2 (mr, q, rl), rp, |
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
472 |
make2 (rm, rq, rr))))) |
77721 | 473 |
| ord => |
77737 | 474 |
(case del (if_equal ord NONE k) m of |
77721 | 475 |
(p', (false, m')) => |
77737 | 476 |
(p', (false, make3 (l, if_equal ord p' p, m', q, r))) |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
477 |
| (p', (true, m')) => (p', (false, case (unmake l, unmake r) of |
77721 | 478 |
(Branch2 (ll, lp, lr), Branch2 _) => |
77737 | 479 |
make2 (make3 (ll, lp, lr, if_equal ord p' p, m'), q, r) |
77721 | 480 |
| (Branch3 (ll, lp, lm, lq, lr), _) => |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
481 |
make3 (make2 (ll, lp, lm), lq, |
77737 | 482 |
make2 (lr, if_equal ord p' p, m'), q, r) |
77721 | 483 |
| (_, Branch3 (rl, rp, rm, rq, rr)) => |
77737 | 484 |
make3 (l, if_equal ord p' p, make2 (m', q, rl), rp, |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
485 |
make2 (rm, rq, rr)))))) |
77721 | 486 |
| ord => |
77737 | 487 |
(case del (if_equal ord NONE k) r of |
77721 | 488 |
(q', (false, r')) => |
77737 | 489 |
(q', (false, make3 (l, p, m, if_equal ord q' q, r'))) |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
490 |
| (q', (true, r')) => (q', (false, case (unmake l, unmake m) of |
77721 | 491 |
(Branch2 _, Branch2 (ml, mp, mr)) => |
77737 | 492 |
make2 (l, p, make3 (ml, mp, mr, if_equal ord q' q, r')) |
77721 | 493 |
| (_, Branch3 (ml, mp, mm, mq, mr)) => |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
494 |
make3 (l, p, make2 (ml, mp, mm), mq, |
77737 | 495 |
make2 (mr, if_equal ord q' q, r')) |
77721 | 496 |
| (Branch3 (ll, lp, lm, lq, lr), Branch2 (ml, mp, mr)) => |
77736
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
wenzelm
parents:
77735
diff
changeset
|
497 |
make3 (make2 (ll, lp, lm), lq, make2 (lr, p, ml), mp, |
77737 | 498 |
make2 (mr, if_equal ord q' q, r')))))); |
15014 | 499 |
|
15665 | 500 |
in |
501 |
||
15761 | 502 |
fun delete key tab = snd (snd (del (SOME key) tab)); |
44336
59ff5a93eef4
tuned Table.delete_safe: avoid potentially expensive attempt of delete;
wenzelm
parents:
43792
diff
changeset
|
503 |
fun delete_safe key tab = if defined tab key then delete key tab else tab; |
15014 | 504 |
|
15665 | 505 |
end; |
506 |
||
15014 | 507 |
|
19031 | 508 |
(* membership operations *) |
16466 | 509 |
|
510 |
fun member eq tab (key, x) = |
|
17412 | 511 |
(case lookup tab key of |
16466 | 512 |
NONE => false |
513 |
| SOME y => eq (x, y)); |
|
15761 | 514 |
|
515 |
fun insert eq (key, x) = |
|
516 |
modify key (fn NONE => x | SOME y => if eq (x, y) then raise SAME else raise DUP key); |
|
517 |
||
518 |
fun remove eq (key, x) tab = |
|
17412 | 519 |
(case lookup tab key of |
15761 | 520 |
NONE => tab |
521 |
| SOME y => if eq (x, y) then delete key tab else tab); |
|
522 |
||
523 |
||
19031 | 524 |
(* simultaneous modifications *) |
525 |
||
74266 | 526 |
fun make entries = build (fold update_new entries); |
5015 | 527 |
|
12287 | 528 |
fun join f (table1, table2) = |
55727
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
wenzelm
parents:
52049
diff
changeset
|
529 |
let |
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
wenzelm
parents:
52049
diff
changeset
|
530 |
fun add (key, y) tab = modify key (fn NONE => y | SOME x => f key (x, y)) tab; |
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
wenzelm
parents:
52049
diff
changeset
|
531 |
in |
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
wenzelm
parents:
52049
diff
changeset
|
532 |
if pointer_eq (table1, table2) then table1 |
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
wenzelm
parents:
52049
diff
changeset
|
533 |
else if is_empty table1 then table2 |
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
wenzelm
parents:
52049
diff
changeset
|
534 |
else fold_table add table2 table1 |
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
wenzelm
parents:
52049
diff
changeset
|
535 |
end; |
12287 | 536 |
|
19031 | 537 |
fun merge eq = join (fn key => fn xy => if eq xy then raise SAME else raise DUP key); |
5015 | 538 |
|
539 |
||
19031 | 540 |
(* list tables *) |
15761 | 541 |
|
18946 | 542 |
fun lookup_list tab key = these (lookup tab key); |
25391 | 543 |
|
544 |
fun cons_list (key, x) tab = modify key (fn NONE => [x] | SOME xs => x :: xs) tab; |
|
5015 | 545 |
|
20124 | 546 |
fun insert_list eq (key, x) = |
547 |
modify key (fn NONE => [x] | SOME xs => if Library.member eq xs x then raise SAME else x :: xs); |
|
25391 | 548 |
|
18946 | 549 |
fun remove_list eq (key, x) tab = |
15761 | 550 |
map_entry key (fn xs => (case Library.remove eq x xs of [] => raise UNDEF key | ys => ys)) tab |
551 |
handle UNDEF _ => delete key tab; |
|
5015 | 552 |
|
25391 | 553 |
fun update_list eq (key, x) = |
554 |
modify key (fn NONE => [x] | SOME [] => [x] | SOME (xs as y :: _) => |
|
555 |
if eq (x, y) then raise SAME else Library.update eq x xs); |
|
556 |
||
74266 | 557 |
fun make_list args = build (fold_rev cons_list args); |
19482
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
wenzelm
parents:
19073
diff
changeset
|
558 |
fun dest_list tab = maps (fn (key, xs) => map (pair key) xs) (dest tab); |
19031 | 559 |
fun merge_list eq = join (fn _ => Library.merge eq); |
5015 | 560 |
|
561 |
||
74227 | 562 |
(* set operations *) |
50234 | 563 |
|
564 |
type set = unit table; |
|
565 |
||
67529 | 566 |
fun insert_set x = default (x, ()); |
567 |
fun remove_set x : set -> set = delete_safe x; |
|
74266 | 568 |
fun make_set xs = build (fold insert_set xs); |
50234 | 569 |
|
570 |
||
47980
c81801f881b3
simplified Poly/ML setup -- 5.3.0 is now the common base-line;
wenzelm
parents:
44336
diff
changeset
|
571 |
(* ML pretty-printing *) |
38635
f76ad0771f67
added ML toplevel pretty-printing for tables, using dummy for anything other than Poly/ML 5.3.0 (or later);
wenzelm
parents:
35012
diff
changeset
|
572 |
|
f76ad0771f67
added ML toplevel pretty-printing for tables, using dummy for anything other than Poly/ML 5.3.0 (or later);
wenzelm
parents:
35012
diff
changeset
|
573 |
val _ = |
62819
d3ff367a16a0
careful export of type-dependent functions, without losing their special status;
wenzelm
parents:
62503
diff
changeset
|
574 |
ML_system_pp (fn depth => fn pretty => fn tab => |
62503 | 575 |
ML_Pretty.to_polyml |
38635
f76ad0771f67
added ML toplevel pretty-printing for tables, using dummy for anything other than Poly/ML 5.3.0 (or later);
wenzelm
parents:
35012
diff
changeset
|
576 |
(ML_Pretty.enum "," "{" "}" |
62503 | 577 |
(ML_Pretty.pair |
62819
d3ff367a16a0
careful export of type-dependent functions, without losing their special status;
wenzelm
parents:
62503
diff
changeset
|
578 |
(ML_Pretty.from_polyml o ML_system_pretty) |
62503 | 579 |
(ML_Pretty.from_polyml o pretty)) |
38635
f76ad0771f67
added ML toplevel pretty-printing for tables, using dummy for anything other than Poly/ML 5.3.0 (or later);
wenzelm
parents:
35012
diff
changeset
|
580 |
(dest tab, depth))); |
f76ad0771f67
added ML toplevel pretty-printing for tables, using dummy for anything other than Poly/ML 5.3.0 (or later);
wenzelm
parents:
35012
diff
changeset
|
581 |
|
f76ad0771f67
added ML toplevel pretty-printing for tables, using dummy for anything other than Poly/ML 5.3.0 (or later);
wenzelm
parents:
35012
diff
changeset
|
582 |
|
5681 | 583 |
(*final declarations of this structure!*) |
39020 | 584 |
val map = map_table; |
16446 | 585 |
val fold = fold_table; |
28334 | 586 |
val fold_rev = fold_rev_table; |
5015 | 587 |
|
588 |
end; |
|
589 |
||
31971
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
wenzelm
parents:
31621
diff
changeset
|
590 |
structure Inttab = Table(type key = int val ord = int_ord); |
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
wenzelm
parents:
31621
diff
changeset
|
591 |
structure Symtab = Table(type key = string val ord = fast_string_ord); |
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
wenzelm
parents:
31621
diff
changeset
|
592 |
structure Symreltab = Table(type key = string * string |
30647
ef8f46c3158a
added Symreltab (binary relations of symbols) instance of TableFun
haftmann
parents:
30290
diff
changeset
|
593 |
val ord = prod_ord fast_string_ord fast_string_ord); |