6 Unbalanced binary trees indexed by strings; no way to delete an entry. |
6 Unbalanced binary trees indexed by strings; no way to delete an entry. |
7 *) |
7 *) |
8 |
8 |
9 signature SYMTAB = |
9 signature SYMTAB = |
10 sig |
10 sig |
11 exception DUPLICATE of string |
11 exception DUP of string |
12 exception DUPS of string list |
12 exception DUPS of string list |
13 type 'a table |
13 type 'a table |
14 val null: 'a table |
14 val empty: 'a table |
15 val is_null: 'a table -> bool |
15 val is_empty: 'a table -> bool |
16 val lookup: 'a table * string -> 'a option |
16 val lookup: 'a table * string -> 'a option |
17 val find_first: (string * 'a -> bool) -> 'a table -> (string * 'a) option |
17 val find_first: (string * 'a -> bool) -> 'a table -> (string * 'a) option |
18 val update: (string * 'a) * 'a table -> 'a table |
18 val update: (string * 'a) * 'a table -> 'a table |
19 val update_new: (string * 'a) * 'a table -> 'a table |
19 val update_new: (string * 'a) * 'a table -> 'a table |
20 val map: ('a -> 'b) -> 'a table -> 'b table |
20 val map: ('a -> 'b) -> 'a table -> 'b table |
21 val balance: 'a table -> 'a table |
21 val balance: 'a table -> 'a table |
22 val st_of_declist: (string list * 'a) list * 'a table -> 'a table |
22 val st_of_declist: (string list * 'a) list * 'a table -> 'a table |
23 val make: (string * 'a) list -> 'a table |
23 val make: (string * 'a) list -> 'a table |
24 val dest: 'a table -> (string * 'a) list |
24 val dest: 'a table -> (string * 'a) list |
25 val extend: ('a * 'a -> bool) -> 'a table * (string * 'a) list -> 'a table |
25 val extend: 'a table * (string * 'a) list -> 'a table |
26 val extend_new: 'a table * (string * 'a) list -> 'a table |
|
27 val merge: ('a * 'a -> bool) -> 'a table * 'a table -> 'a table |
26 val merge: ('a * 'a -> bool) -> 'a table * 'a table -> 'a table |
28 val lookup_multi: 'a list table * string -> 'a list |
27 val lookup_multi: 'a list table * string -> 'a list |
29 val make_multi: (string * 'a) list -> 'a list table |
28 val make_multi: (string * 'a) list -> 'a list table |
30 val dest_multi: 'a list table -> (string * 'a) list |
29 val dest_multi: 'a list table -> (string * 'a) list |
31 end; |
30 end; |
32 |
31 |
33 structure Symtab: SYMTAB = |
32 structure Symtab: SYMTAB = |
34 struct |
33 struct |
35 |
34 |
36 (*symbol table errors, such as from update_new*) |
35 (*symbol table errors, such as from update_new*) |
37 exception DUPLICATE of string; |
36 exception DUP of string; |
38 exception DUPS of string list; |
37 exception DUPS of string list; |
39 |
38 |
40 datatype 'a table = Tip | Branch of (string * 'a * 'a table * 'a table); |
39 datatype 'a table = Tip | Branch of (string * 'a * 'a table * 'a table); |
41 |
40 |
42 |
41 |
43 val null = Tip; |
42 val empty = Tip; |
44 |
43 |
45 fun is_null Tip = true |
44 fun is_empty Tip = true |
46 | is_null _ = false; |
45 | is_empty _ = false; |
47 |
46 |
48 |
47 |
49 fun lookup (symtab: 'a table, key: string) : 'a option = |
48 fun lookup (symtab: 'a table, key: string) : 'a option = |
50 let fun look Tip = None |
49 let fun look Tip = None |
51 | look (Branch (key', entry, left, right)) = |
50 | look (Branch (key', entry, left, right)) = |
79 : 'a table = |
78 : 'a table = |
80 let fun upd Tip = Branch (key, entry, Tip, Tip) |
79 let fun upd Tip = Branch (key, entry, Tip, Tip) |
81 | upd (Branch(key', entry', left, right)) = |
80 | upd (Branch(key', entry', left, right)) = |
82 if key < key' then Branch (key', entry', upd left, right) |
81 if key < key' then Branch (key', entry', upd left, right) |
83 else if key' < key then Branch (key', entry', left, upd right) |
82 else if key' < key then Branch (key', entry', left, upd right) |
84 else raise DUPLICATE(key) |
83 else raise DUP(key) |
85 in upd symtab end; |
84 in upd symtab end; |
86 |
85 |
87 |
86 |
88 (*conversion of symbol table to sorted association list*) |
87 (*conversion of symbol table to sorted association list*) |
89 fun dest (symtab : 'a table) : (string * 'a) list = |
88 fun dest (symtab : 'a table) : (string * 'a) list = |
131 fun make alst = |
130 fun make alst = |
132 (case gen_duplicates eq_fst alst of |
131 (case gen_duplicates eq_fst alst of |
133 [] => balance (foldr update_new (alst, Tip)) |
132 [] => balance (foldr update_new (alst, Tip)) |
134 | dups => raise DUPS (map fst dups)); |
133 | dups => raise DUPS (map fst dups)); |
135 |
134 |
136 fun extend eq (tab, alst) = |
135 fun pre_extend eq (tab, alst) = |
137 generic_extend (eq_pair eq) dest make tab alst; |
136 generic_extend (eq_pair eq) dest make tab alst; |
138 |
137 |
139 fun extend_new (tab, alst) = extend (K false) (tab, alst); |
138 fun extend (tab, alst) = pre_extend (K false) (tab, alst); |
140 |
139 |
141 fun merge eq (tab1, tab2) = |
140 fun merge eq (tab1, tab2) = |
142 generic_merge (eq_pair eq) dest make tab1 tab2; |
141 generic_merge (eq_pair eq) dest make tab1 tab2; |
143 |
142 |
144 |
143 |