author | haftmann |
Wed, 01 Sep 2010 15:33:59 +0200 | |
changeset 39020 | ac0f24f850c9 |
parent 38635 | f76ad0771f67 |
child 43792 | d5803c3d537a |
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 |
|
11 |
val ord: key * key -> order |
|
12 |
end; |
|
13 |
||
14 |
signature TABLE = |
|
15 |
sig |
|
16 |
type key |
|
17 |
type 'a table |
|
18 |
exception DUP of key |
|
19031 | 19 |
exception SAME |
15014 | 20 |
exception UNDEF of key |
5015 | 21 |
val empty: 'a table |
22 |
val is_empty: 'a table -> bool |
|
39020 | 23 |
val map: (key -> 'a -> 'b) -> 'a table -> 'b table |
16446 | 24 |
val fold: (key * 'b -> 'a -> 'a) -> 'b table -> 'a -> 'a |
28334 | 25 |
val fold_rev: (key * 'b -> 'a -> 'a) -> 'b table -> 'a -> 'a |
5015 | 26 |
val dest: 'a table -> (key * 'a) list |
5681 | 27 |
val keys: 'a table -> key list |
31616 | 28 |
val min_key: 'a table -> key option |
29 |
val max_key: 'a table -> key option |
|
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
30 |
val get_first: (key * 'a -> 'b option) -> 'a table -> 'b option |
27508 | 31 |
val exists: (key * 'a -> bool) -> 'a table -> bool |
32 |
val forall: (key * 'a -> bool) -> 'a table -> bool |
|
31616 | 33 |
val lookup: 'a table -> key -> 'a option |
16887 | 34 |
val defined: 'a table -> key -> bool |
31209 | 35 |
val update: key * 'a -> 'a table -> 'a table |
36 |
val update_new: key * 'a -> 'a table -> 'a table (*exception DUP*) |
|
17179 | 37 |
val default: key * 'a -> 'a table -> 'a table |
15665 | 38 |
val map_entry: key -> ('a -> 'a) -> 'a table -> 'a table |
31209 | 39 |
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
|
40 |
val make: (key * 'a) list -> 'a table (*exception DUP*) |
19031 | 41 |
val join: (key -> 'a * 'a -> 'a) (*exception DUP/SAME*) -> |
23655
d2d1138e0ddc
replaced exception TableFun/GraphFun.DUPS by TableFun/GraphFun.DUP;
wenzelm
parents:
21065
diff
changeset
|
42 |
'a table * 'a table -> 'a table (*exception DUP*) |
d2d1138e0ddc
replaced exception TableFun/GraphFun.DUPS by TableFun/GraphFun.DUP;
wenzelm
parents:
21065
diff
changeset
|
43 |
val merge: ('a * 'a -> bool) -> 'a table * 'a table -> 'a table (*exception DUP*) |
15665 | 44 |
val delete: key -> 'a table -> 'a table (*exception UNDEF*) |
15761 | 45 |
val delete_safe: key -> 'a table -> 'a table |
16466 | 46 |
val member: ('b * 'a -> bool) -> 'a table -> key * 'b -> bool |
15761 | 47 |
val insert: ('a * 'a -> bool) -> key * 'a -> 'a table -> 'a table (*exception DUP*) |
16139 | 48 |
val remove: ('b * 'a -> bool) -> key * 'b -> 'a table -> 'a table |
18946 | 49 |
val lookup_list: 'a list table -> key -> 'a list |
31209 | 50 |
val cons_list: key * 'a -> 'a list table -> 'a list table |
19506 | 51 |
val insert_list: ('a * 'a -> bool) -> key * 'a -> 'a list table -> 'a list table |
18946 | 52 |
val remove_list: ('b * 'a -> bool) -> key * 'b -> 'a list table -> 'a list table |
25391 | 53 |
val update_list: ('a * 'a -> bool) -> key * 'a -> 'a list table -> 'a list table |
18946 | 54 |
val make_list: (key * 'a) list -> 'a list table |
55 |
val dest_list: 'a list table -> (key * 'a) list |
|
33162 | 56 |
val merge_list: ('a * 'a -> bool) -> 'a list table * 'a list table -> 'a list table |
5015 | 57 |
end; |
58 |
||
31971
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
wenzelm
parents:
31621
diff
changeset
|
59 |
functor Table(Key: KEY): TABLE = |
5015 | 60 |
struct |
61 |
||
62 |
||
63 |
(* datatype table *) |
|
64 |
||
65 |
type key = Key.key; |
|
66 |
||
67 |
datatype 'a table = |
|
68 |
Empty | |
|
69 |
Branch2 of 'a table * (key * 'a) * 'a table | |
|
70 |
Branch3 of 'a table * (key * 'a) * 'a table * (key * 'a) * 'a table; |
|
71 |
||
72 |
exception DUP of key; |
|
73 |
||
74 |
||
5681 | 75 |
(* empty *) |
76 |
||
5015 | 77 |
val empty = Empty; |
78 |
||
79 |
fun is_empty Empty = true |
|
80 |
| is_empty _ = false; |
|
81 |
||
5681 | 82 |
|
83 |
(* map and fold combinators *) |
|
84 |
||
16657 | 85 |
fun map_table f = |
86 |
let |
|
87 |
fun map Empty = Empty |
|
88 |
| map (Branch2 (left, (k, x), right)) = |
|
89 |
Branch2 (map left, (k, f k x), map right) |
|
90 |
| map (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = |
|
91 |
Branch3 (map left, (k1, f k1 x1), map mid, (k2, f k2 x2), map right); |
|
92 |
in map end; |
|
5681 | 93 |
|
16657 | 94 |
fun fold_table f = |
95 |
let |
|
96 |
fun fold Empty x = x |
|
97 |
| fold (Branch2 (left, p, right)) x = |
|
98 |
fold right (f p (fold left x)) |
|
99 |
| fold (Branch3 (left, p1, mid, p2, right)) x = |
|
100 |
fold right (f p2 (fold mid (f p1 (fold left x)))); |
|
101 |
in fold end; |
|
5681 | 102 |
|
28334 | 103 |
fun fold_rev_table f = |
104 |
let |
|
105 |
fun fold Empty x = x |
|
106 |
| fold (Branch2 (left, p, right)) x = |
|
107 |
fold left (f p (fold right x)) |
|
108 |
| fold (Branch3 (left, p1, mid, p2, right)) x = |
|
109 |
fold left (f p1 (fold mid (f p2 (fold right x)))); |
|
110 |
in fold end; |
|
111 |
||
112 |
fun dest tab = fold_rev_table cons tab []; |
|
113 |
fun keys tab = fold_rev_table (cons o #1) tab []; |
|
16192 | 114 |
|
27508 | 115 |
|
116 |
(* min/max keys *) |
|
5015 | 117 |
|
15531 | 118 |
fun min_key Empty = NONE |
16864 | 119 |
| min_key (Branch2 (Empty, (k, _), _)) = SOME k |
120 |
| min_key (Branch3 (Empty, (k, _), _, _, _)) = SOME k |
|
121 |
| min_key (Branch2 (left, _, _)) = min_key left |
|
122 |
| min_key (Branch3 (left, _, _, _, _)) = min_key left; |
|
8409 | 123 |
|
15531 | 124 |
fun max_key Empty = NONE |
16864 | 125 |
| max_key (Branch2 (_, (k, _), Empty)) = SOME k |
126 |
| max_key (Branch3 (_, _, _, (k, _), Empty)) = SOME k |
|
127 |
| max_key (Branch2 (_, _, right)) = max_key right |
|
128 |
| max_key (Branch3 (_, _, _, _, right)) = max_key right; |
|
15665 | 129 |
|
5015 | 130 |
|
31616 | 131 |
(* get_first *) |
132 |
||
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
133 |
fun get_first f = |
31616 | 134 |
let |
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
135 |
fun get Empty = NONE |
31618
2e4430b84303
improved get_first: check boundary before entering subtrees;
wenzelm
parents:
31616
diff
changeset
|
136 |
| get (Branch2 (left, (k, x), right)) = |
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
137 |
(case get left of |
31616 | 138 |
NONE => |
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
139 |
(case f (k, x) of |
31616 | 140 |
NONE => get right |
141 |
| some => some) |
|
142 |
| some => some) |
|
31618
2e4430b84303
improved get_first: check boundary before entering subtrees;
wenzelm
parents:
31616
diff
changeset
|
143 |
| get (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = |
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
144 |
(case get left of |
31616 | 145 |
NONE => |
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
146 |
(case f (k1, x1) of |
31616 | 147 |
NONE => |
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
148 |
(case get mid of |
31616 | 149 |
NONE => |
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
150 |
(case f (k2, x2) of |
31616 | 151 |
NONE => get right |
152 |
| some => some) |
|
153 |
| some => some) |
|
154 |
| some => some) |
|
155 |
| some => some); |
|
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
156 |
in get end; |
31616 | 157 |
|
35012
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
wenzelm
parents:
33162
diff
changeset
|
158 |
fun exists pred = is_some o get_first (fn entry => if pred entry then SOME () else NONE); |
31616 | 159 |
fun forall pred = not o exists (not o pred); |
160 |
||
161 |
||
5015 | 162 |
(* lookup *) |
163 |
||
19031 | 164 |
fun lookup tab key = |
165 |
let |
|
166 |
fun look Empty = NONE |
|
167 |
| look (Branch2 (left, (k, x), right)) = |
|
168 |
(case Key.ord (key, k) of |
|
169 |
LESS => look left |
|
170 |
| EQUAL => SOME x |
|
171 |
| GREATER => look right) |
|
172 |
| look (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = |
|
173 |
(case Key.ord (key, k1) of |
|
174 |
LESS => look left |
|
175 |
| EQUAL => SOME x1 |
|
176 |
| GREATER => |
|
177 |
(case Key.ord (key, k2) of |
|
178 |
LESS => look mid |
|
179 |
| EQUAL => SOME x2 |
|
180 |
| GREATER => look right)); |
|
181 |
in look tab end; |
|
5015 | 182 |
|
19031 | 183 |
fun defined tab key = |
184 |
let |
|
185 |
fun def Empty = false |
|
186 |
| def (Branch2 (left, (k, x), right)) = |
|
187 |
(case Key.ord (key, k) of |
|
188 |
LESS => def left |
|
189 |
| EQUAL => true |
|
190 |
| GREATER => def right) |
|
191 |
| def (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = |
|
192 |
(case Key.ord (key, k1) of |
|
193 |
LESS => def left |
|
194 |
| EQUAL => true |
|
195 |
| GREATER => |
|
196 |
(case Key.ord (key, k2) of |
|
197 |
LESS => def mid |
|
198 |
| EQUAL => true |
|
199 |
| GREATER => def right)); |
|
200 |
in def tab end; |
|
16887 | 201 |
|
5015 | 202 |
|
19031 | 203 |
(* modify *) |
5015 | 204 |
|
205 |
datatype 'a growth = |
|
206 |
Stay of 'a table | |
|
207 |
Sprout of 'a table * (key * 'a) * 'a table; |
|
208 |
||
15761 | 209 |
exception SAME; |
210 |
||
15665 | 211 |
fun modify key f tab = |
212 |
let |
|
213 |
fun modfy Empty = Sprout (Empty, (key, f NONE), Empty) |
|
214 |
| modfy (Branch2 (left, p as (k, x), right)) = |
|
215 |
(case Key.ord (key, k) of |
|
216 |
LESS => |
|
217 |
(case modfy left of |
|
218 |
Stay left' => Stay (Branch2 (left', p, right)) |
|
219 |
| Sprout (left1, q, left2) => Stay (Branch3 (left1, q, left2, p, right))) |
|
220 |
| EQUAL => Stay (Branch2 (left, (k, f (SOME x)), right)) |
|
221 |
| GREATER => |
|
222 |
(case modfy right of |
|
223 |
Stay right' => Stay (Branch2 (left, p, right')) |
|
224 |
| Sprout (right1, q, right2) => |
|
225 |
Stay (Branch3 (left, p, right1, q, right2)))) |
|
226 |
| modfy (Branch3 (left, p1 as (k1, x1), mid, p2 as (k2, x2), right)) = |
|
227 |
(case Key.ord (key, k1) of |
|
5015 | 228 |
LESS => |
15665 | 229 |
(case modfy left of |
230 |
Stay left' => Stay (Branch3 (left', p1, mid, p2, right)) |
|
231 |
| Sprout (left1, q, left2) => |
|
232 |
Sprout (Branch2 (left1, q, left2), p1, Branch2 (mid, p2, right))) |
|
233 |
| EQUAL => Stay (Branch3 (left, (k1, f (SOME x1)), mid, p2, right)) |
|
5015 | 234 |
| GREATER => |
15665 | 235 |
(case Key.ord (key, k2) of |
236 |
LESS => |
|
237 |
(case modfy mid of |
|
238 |
Stay mid' => Stay (Branch3 (left, p1, mid', p2, right)) |
|
239 |
| Sprout (mid1, q, mid2) => |
|
240 |
Sprout (Branch2 (left, p1, mid1), q, Branch2 (mid2, p2, right))) |
|
241 |
| EQUAL => Stay (Branch3 (left, p1, mid, (k2, f (SOME x2)), right)) |
|
242 |
| GREATER => |
|
243 |
(case modfy right of |
|
244 |
Stay right' => Stay (Branch3 (left, p1, mid, p2, right')) |
|
245 |
| Sprout (right1, q, right2) => |
|
246 |
Sprout (Branch2 (left, p1, mid), p2, Branch2 (right1, q, right2))))); |
|
5015 | 247 |
|
15665 | 248 |
in |
249 |
(case modfy tab of |
|
250 |
Stay tab' => tab' |
|
251 |
| Sprout br => Branch2 br) |
|
252 |
handle SAME => tab |
|
253 |
end; |
|
5015 | 254 |
|
17412 | 255 |
fun update (key, x) tab = modify key (fn _ => x) tab; |
256 |
fun update_new (key, x) tab = modify key (fn NONE => x | SOME _ => raise DUP key) tab; |
|
17709 | 257 |
fun default (key, x) tab = modify key (fn NONE => x | SOME _ => raise SAME) tab; |
15761 | 258 |
fun map_entry key f = modify key (fn NONE => raise SAME | SOME x => f x); |
27783 | 259 |
fun map_default (key, x) f = modify key (fn NONE => f x | SOME y => f y); |
5015 | 260 |
|
261 |
||
15014 | 262 |
(* delete *) |
263 |
||
15665 | 264 |
exception UNDEF of key; |
265 |
||
266 |
local |
|
267 |
||
268 |
fun compare NONE (k2, _) = LESS |
|
269 |
| compare (SOME k1) (k2, _) = Key.ord (k1, k2); |
|
15014 | 270 |
|
271 |
fun if_eq EQUAL x y = x |
|
272 |
| if_eq _ x y = y; |
|
273 |
||
15531 | 274 |
fun del (SOME k) Empty = raise UNDEF k |
275 |
| del NONE (Branch2 (Empty, p, Empty)) = (p, (true, Empty)) |
|
276 |
| del NONE (Branch3 (Empty, p, Empty, q, Empty)) = |
|
15014 | 277 |
(p, (false, Branch2 (Empty, q, Empty))) |
15665 | 278 |
| del k (Branch2 (Empty, p, Empty)) = (case compare k p of |
16002 | 279 |
EQUAL => (p, (true, Empty)) | _ => raise UNDEF (the k)) |
15665 | 280 |
| del k (Branch3 (Empty, p, Empty, q, Empty)) = (case compare k p of |
15014 | 281 |
EQUAL => (p, (false, Branch2 (Empty, q, Empty))) |
15665 | 282 |
| _ => (case compare k q of |
15014 | 283 |
EQUAL => (q, (false, Branch2 (Empty, p, Empty))) |
16002 | 284 |
| _ => raise UNDEF (the k))) |
15665 | 285 |
| del k (Branch2 (l, p, r)) = (case compare k p of |
15014 | 286 |
LESS => (case del k l of |
287 |
(p', (false, l')) => (p', (false, Branch2 (l', p, r))) |
|
288 |
| (p', (true, l')) => (p', case r of |
|
289 |
Branch2 (rl, rp, rr) => |
|
290 |
(true, Branch3 (l', p, rl, rp, rr)) |
|
291 |
| Branch3 (rl, rp, rm, rq, rr) => (false, Branch2 |
|
292 |
(Branch2 (l', p, rl), rp, Branch2 (rm, rq, rr))))) |
|
15531 | 293 |
| ord => (case del (if_eq ord NONE k) r of |
15014 | 294 |
(p', (false, r')) => (p', (false, Branch2 (l, if_eq ord p' p, r'))) |
295 |
| (p', (true, r')) => (p', case l of |
|
296 |
Branch2 (ll, lp, lr) => |
|
297 |
(true, Branch3 (ll, lp, lr, if_eq ord p' p, r')) |
|
298 |
| Branch3 (ll, lp, lm, lq, lr) => (false, Branch2 |
|
299 |
(Branch2 (ll, lp, lm), lq, Branch2 (lr, if_eq ord p' p, r')))))) |
|
15665 | 300 |
| del k (Branch3 (l, p, m, q, r)) = (case compare k q of |
301 |
LESS => (case compare k p of |
|
15014 | 302 |
LESS => (case del k l of |
303 |
(p', (false, l')) => (p', (false, Branch3 (l', p, m, q, r))) |
|
304 |
| (p', (true, l')) => (p', (false, case (m, r) of |
|
305 |
(Branch2 (ml, mp, mr), Branch2 _) => |
|
306 |
Branch2 (Branch3 (l', p, ml, mp, mr), q, r) |
|
307 |
| (Branch3 (ml, mp, mm, mq, mr), _) => |
|
308 |
Branch3 (Branch2 (l', p, ml), mp, Branch2 (mm, mq, mr), q, r) |
|
309 |
| (Branch2 (ml, mp, mr), Branch3 (rl, rp, rm, rq, rr)) => |
|
310 |
Branch3 (Branch2 (l', p, ml), mp, Branch2 (mr, q, rl), rp, |
|
311 |
Branch2 (rm, rq, rr))))) |
|
15531 | 312 |
| ord => (case del (if_eq ord NONE k) m of |
15014 | 313 |
(p', (false, m')) => |
314 |
(p', (false, Branch3 (l, if_eq ord p' p, m', q, r))) |
|
315 |
| (p', (true, m')) => (p', (false, case (l, r) of |
|
316 |
(Branch2 (ll, lp, lr), Branch2 _) => |
|
317 |
Branch2 (Branch3 (ll, lp, lr, if_eq ord p' p, m'), q, r) |
|
318 |
| (Branch3 (ll, lp, lm, lq, lr), _) => |
|
319 |
Branch3 (Branch2 (ll, lp, lm), lq, |
|
320 |
Branch2 (lr, if_eq ord p' p, m'), q, r) |
|
321 |
| (_, Branch3 (rl, rp, rm, rq, rr)) => |
|
322 |
Branch3 (l, if_eq ord p' p, Branch2 (m', q, rl), rp, |
|
323 |
Branch2 (rm, rq, rr)))))) |
|
15531 | 324 |
| ord => (case del (if_eq ord NONE k) r of |
15014 | 325 |
(q', (false, r')) => |
326 |
(q', (false, Branch3 (l, p, m, if_eq ord q' q, r'))) |
|
327 |
| (q', (true, r')) => (q', (false, case (l, m) of |
|
328 |
(Branch2 _, Branch2 (ml, mp, mr)) => |
|
329 |
Branch2 (l, p, Branch3 (ml, mp, mr, if_eq ord q' q, r')) |
|
330 |
| (_, Branch3 (ml, mp, mm, mq, mr)) => |
|
331 |
Branch3 (l, p, Branch2 (ml, mp, mm), mq, |
|
332 |
Branch2 (mr, if_eq ord q' q, r')) |
|
333 |
| (Branch3 (ll, lp, lm, lq, lr), Branch2 (ml, mp, mr)) => |
|
334 |
Branch3 (Branch2 (ll, lp, lm), lq, Branch2 (lr, p, ml), mp, |
|
335 |
Branch2 (mr, if_eq ord q' q, r')))))); |
|
336 |
||
15665 | 337 |
in |
338 |
||
15761 | 339 |
fun delete key tab = snd (snd (del (SOME key) tab)); |
340 |
fun delete_safe key tab = delete key tab handle UNDEF _ => tab; |
|
15014 | 341 |
|
15665 | 342 |
end; |
343 |
||
15014 | 344 |
|
19031 | 345 |
(* membership operations *) |
16466 | 346 |
|
347 |
fun member eq tab (key, x) = |
|
17412 | 348 |
(case lookup tab key of |
16466 | 349 |
NONE => false |
350 |
| SOME y => eq (x, y)); |
|
15761 | 351 |
|
352 |
fun insert eq (key, x) = |
|
353 |
modify key (fn NONE => x | SOME y => if eq (x, y) then raise SAME else raise DUP key); |
|
354 |
||
355 |
fun remove eq (key, x) tab = |
|
17412 | 356 |
(case lookup tab key of |
15761 | 357 |
NONE => tab |
358 |
| SOME y => if eq (x, y) then delete key tab else tab); |
|
359 |
||
360 |
||
19031 | 361 |
(* simultaneous modifications *) |
362 |
||
29004 | 363 |
fun make entries = fold update_new entries empty; |
5015 | 364 |
|
12287 | 365 |
fun join f (table1, table2) = |
23655
d2d1138e0ddc
replaced exception TableFun/GraphFun.DUPS by TableFun/GraphFun.DUP;
wenzelm
parents:
21065
diff
changeset
|
366 |
let fun add (key, y) tab = modify key (fn NONE => y | SOME x => f key (x, y)) tab; |
30283
520872460b7b
TableFun.join/merge: optimize the important special case where the tables coincide -- NOTE: this changes both the operational behaviour and the result for non-standard join/eq notion;
wenzelm
parents:
29606
diff
changeset
|
367 |
in if pointer_eq (table1, table2) then table1 else fold_table add table2 table1 end; |
12287 | 368 |
|
19031 | 369 |
fun merge eq = join (fn key => fn xy => if eq xy then raise SAME else raise DUP key); |
5015 | 370 |
|
371 |
||
19031 | 372 |
(* list tables *) |
15761 | 373 |
|
18946 | 374 |
fun lookup_list tab key = these (lookup tab key); |
25391 | 375 |
|
376 |
fun cons_list (key, x) tab = modify key (fn NONE => [x] | SOME xs => x :: xs) tab; |
|
5015 | 377 |
|
20124 | 378 |
fun insert_list eq (key, x) = |
379 |
modify key (fn NONE => [x] | SOME xs => if Library.member eq xs x then raise SAME else x :: xs); |
|
25391 | 380 |
|
18946 | 381 |
fun remove_list eq (key, x) tab = |
15761 | 382 |
map_entry key (fn xs => (case Library.remove eq x xs of [] => raise UNDEF key | ys => ys)) tab |
383 |
handle UNDEF _ => delete key tab; |
|
5015 | 384 |
|
25391 | 385 |
fun update_list eq (key, x) = |
386 |
modify key (fn NONE => [x] | SOME [] => [x] | SOME (xs as y :: _) => |
|
387 |
if eq (x, y) then raise SAME else Library.update eq x xs); |
|
388 |
||
389 |
fun make_list args = fold_rev cons_list args empty; |
|
19482
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
wenzelm
parents:
19073
diff
changeset
|
390 |
fun dest_list tab = maps (fn (key, xs) => map (pair key) xs) (dest tab); |
19031 | 391 |
fun merge_list eq = join (fn _ => Library.merge eq); |
5015 | 392 |
|
393 |
||
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
|
394 |
(* ML pretty-printing -- requires Poly/ML 5.3.0 or later *) |
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
|
395 |
|
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
|
396 |
val _ = |
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
|
397 |
PolyML.addPrettyPrinter (fn depth => fn pretty => fn tab => |
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
|
398 |
ml_pretty |
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
|
399 |
(ML_Pretty.enum "," "{" "}" |
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
|
400 |
(ML_Pretty.pair (pretty_ml o PolyML.prettyRepresentation) (pretty_ml o pretty)) |
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
|
401 |
(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
|
402 |
|
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
|
403 |
|
5681 | 404 |
(*final declarations of this structure!*) |
39020 | 405 |
val map = map_table; |
16446 | 406 |
val fold = fold_table; |
28334 | 407 |
val fold_rev = fold_rev_table; |
5015 | 408 |
|
409 |
end; |
|
410 |
||
31971
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
wenzelm
parents:
31621
diff
changeset
|
411 |
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
|
412 |
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
|
413 |
structure Symreltab = Table(type key = string * string |
30647
ef8f46c3158a
added Symreltab (binary relations of symbols) instance of TableFun
haftmann
parents:
30290
diff
changeset
|
414 |
val ord = prod_ord fast_string_ord fast_string_ord); |
ef8f46c3158a
added Symreltab (binary relations of symbols) instance of TableFun
haftmann
parents:
30290
diff
changeset
|
415 |