1 (* Title: Pure/table.ML |
1 (* Title: Pure/table.ML |
2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Markus Wenzel, TU Muenchen |
3 Author: Markus Wenzel, TU Muenchen |
4 |
4 |
5 Generic tables (lacking delete operation). Implemented as 2-3 trees. |
5 Generic tables and tables indexed by strings. No delete operation. |
|
6 Implemented as balanced 2-3 trees. |
6 *) |
7 *) |
7 |
8 |
8 signature TABLE_DATA = |
9 signature KEY = |
9 sig |
10 sig |
10 type key |
11 type key |
11 val ord: key * key -> order |
12 val ord: key * key -> order |
12 end; |
13 end; |
13 |
14 |
20 val empty: 'a table |
21 val empty: 'a table |
21 val is_empty: 'a table -> bool |
22 val is_empty: 'a table -> bool |
22 val dest: 'a table -> (key * 'a) list |
23 val dest: 'a table -> (key * 'a) list |
23 val lookup: 'a table * key -> 'a option |
24 val lookup: 'a table * key -> 'a option |
24 val update: (key * 'a) * 'a table -> 'a table |
25 val update: (key * 'a) * 'a table -> 'a table |
25 val update_new: (key * 'a) * 'a table -> 'a table (*exception DUP*) |
26 val update_new: (key * 'a) * 'a table -> 'a table (*exception DUP*) |
26 val make: (key * 'a) list -> 'a table (*exception DUPS*) |
27 val make: (key * 'a) list -> 'a table (*exception DUPS*) |
27 val extend: 'a table * (key * 'a) list -> 'a table (*exception DUPS*) |
28 val extend: 'a table * (key * 'a) list -> 'a table (*exception DUPS*) |
28 val merge: ('a * 'a -> bool) -> 'a table * 'a table -> 'a table (*exception DUPS*) |
29 val merge: ('a * 'a -> bool) -> 'a table * 'a table -> 'a table (*exception DUPS*) |
29 val lookup_multi: 'a list table * key -> 'a list |
30 val lookup_multi: 'a list table * key -> 'a list |
30 val make_multi: (key * 'a) list -> 'a list table |
31 val make_multi: (key * 'a) list -> 'a list table |
31 val dest_multi: 'a list table -> (key * 'a) list |
32 val dest_multi: 'a list table -> (key * 'a) list |
32 val map: ('a -> 'b) -> 'a table -> 'b table |
33 val map: ('a -> 'b) -> 'a table -> 'b table |
33 end; |
34 end; |
34 |
35 |
35 functor TableFun(Data: TABLE_DATA): TABLE = |
36 functor TableFun(Key: KEY): TABLE = |
36 struct |
37 struct |
37 |
38 |
38 |
39 |
39 (* datatype table *) |
40 (* datatype table *) |
40 |
41 |
41 type key = Data.key; |
42 type key = Key.key; |
42 |
43 |
43 datatype 'a table = |
44 datatype 'a table = |
44 Empty | |
45 Empty | |
45 Branch2 of 'a table * (key * 'a) * 'a table | |
46 Branch2 of 'a table * (key * 'a) * 'a table | |
46 Branch3 of 'a table * (key * 'a) * 'a table * (key * 'a) * 'a table; |
47 Branch3 of 'a table * (key * 'a) * 'a table * (key * 'a) * 'a table; |
62 |
63 |
63 (* lookup *) |
64 (* lookup *) |
64 |
65 |
65 fun lookup (Empty, _) = None |
66 fun lookup (Empty, _) = None |
66 | lookup (Branch2 (left, (k, x), right), key) = |
67 | lookup (Branch2 (left, (k, x), right), key) = |
67 (case Data.ord (key, k) of |
68 (case Key.ord (key, k) of |
68 LESS => lookup (left, key) |
69 LESS => lookup (left, key) |
69 | EQUAL => Some x |
70 | EQUAL => Some x |
70 | GREATER => lookup (right, key)) |
71 | GREATER => lookup (right, key)) |
71 | lookup (Branch3 (left, (k1, x1), mid, (k2, x2), right), key) = |
72 | lookup (Branch3 (left, (k1, x1), mid, (k2, x2), right), key) = |
72 (case Data.ord (key, k1) of |
73 (case Key.ord (key, k1) of |
73 LESS => lookup (left, key) |
74 LESS => lookup (left, key) |
74 | EQUAL => Some x1 |
75 | EQUAL => Some x1 |
75 | GREATER => |
76 | GREATER => |
76 (case Data.ord (key, k2) of |
77 (case Key.ord (key, k2) of |
77 LESS => lookup (mid, key) |
78 LESS => lookup (mid, key) |
78 | EQUAL => Some x2 |
79 | EQUAL => Some x2 |
79 | GREATER => lookup (right, key))); |
80 | GREATER => lookup (right, key))); |
80 |
81 |
81 |
82 |
82 (* update *) |
83 (* update *) |
83 |
84 |
84 fun compare (k1, _) (k2, _) = Data.ord (k1, k2); |
85 fun compare (k1, _) (k2, _) = Key.ord (k1, k2); |
85 |
86 |
86 datatype 'a growth = |
87 datatype 'a growth = |
87 Stay of 'a table | |
88 Stay of 'a table | |
88 Sprout of 'a table * (key * 'a) * 'a table; |
89 Sprout of 'a table * (key * 'a) * 'a table; |
89 |
90 |
126 (case insert pair tab of |
127 (case insert pair tab of |
127 Stay tab => tab |
128 Stay tab => tab |
128 | Sprout br => Branch2 br); |
129 | Sprout br => Branch2 br); |
129 |
130 |
130 fun update_new (pair as (key, _), tab) = |
131 fun update_new (pair as (key, _), tab) = |
131 (case lookup (tab, key) of |
132 if is_none (lookup (tab, key)) then update (pair, tab) |
132 None => update (pair, tab) |
133 else raise DUP key; |
133 | Some _ => raise DUP key); |
|
134 |
134 |
135 |
135 |
136 (* make, extend, merge tables *) |
136 (* make, extend, merge tables *) |
137 |
137 |
138 fun add eq ((tab, dups), (key, x)) = |
138 fun add eq ((tab, dups), (key, x)) = |
154 |
154 |
155 (* tables with multiple entries per key (preserving order) *) |
155 (* tables with multiple entries per key (preserving order) *) |
156 |
156 |
157 fun lookup_multi tab_key = if_none (lookup tab_key) []; |
157 fun lookup_multi tab_key = if_none (lookup tab_key) []; |
158 |
158 |
159 fun cons_entry ((key, entry), tab) = |
159 fun cons_entry ((key, x), tab) = |
160 update ((key, entry :: lookup_multi (tab, key)), tab); |
160 update ((key, x :: lookup_multi (tab, key)), tab); |
161 |
161 |
162 fun make_multi pairs = foldr cons_entry (pairs, empty); |
162 fun make_multi pairs = foldr cons_entry (pairs, empty); |
163 |
163 |
164 fun dest_multi tab = |
164 fun dest_multi tab = |
165 flat (map (fn (key, xs) => map (pair key) xs) (dest tab)); |
165 flat (map (fn (key, xs) => map (Library.pair key) xs) (dest tab)); |
166 |
166 |
167 |
167 |
168 (* map *) |
168 (* map *) |
169 |
169 |
170 fun map _ Empty = Empty |
170 fun map _ Empty = Empty |