| author | wenzelm | 
| Thu, 07 Jul 2022 16:37:56 +0200 | |
| changeset 75656 | 7900336c82b6 | 
| parent 74269 | f084d599bb44 | 
| child 77721 | 7c1cc9ce9340 | 
| 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 | |
| 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 | 
| 74232 | 22 |   val build: ('a table -> 'a table) -> 'a table
 | 
| 5015 | 23 | val is_empty: 'a table -> bool | 
| 67537 | 24 | val is_single: 'a table -> bool | 
| 39020 | 25 | val map: (key -> 'a -> 'b) -> 'a table -> 'b table | 
| 16446 | 26 | val fold: (key * 'b -> 'a -> 'a) -> 'b table -> 'a -> 'a | 
| 28334 | 27 | val fold_rev: (key * 'b -> 'a -> 'a) -> 'b table -> 'a -> 'a | 
| 5015 | 28 | val dest: 'a table -> (key * 'a) list | 
| 5681 | 29 | val keys: 'a table -> key list | 
| 52049 | 30 | val min: 'a table -> (key * 'a) option | 
| 31 | val max: 'a table -> (key * 'a) option | |
| 27508 | 32 | val exists: (key * 'a -> bool) -> 'a table -> bool | 
| 33 | val forall: (key * 'a -> bool) -> 'a table -> bool | |
| 74227 | 34 | 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: 
39020diff
changeset | 35 | val lookup_key: 'a table -> key -> (key * 'a) option | 
| 31616 | 36 | val lookup: 'a table -> key -> 'a option | 
| 16887 | 37 | val defined: 'a table -> key -> bool | 
| 31209 | 38 | val update: key * 'a -> 'a table -> 'a table | 
| 39 | val update_new: key * 'a -> 'a table -> 'a table (*exception DUP*) | |
| 17179 | 40 | val default: key * 'a -> 'a table -> 'a table | 
| 56051 | 41 |   val map_entry: key -> ('a -> 'a) (*exception SAME*) -> 'a table -> 'a table
 | 
| 31209 | 42 |   val map_default: key * 'a -> ('a -> 'a) -> 'a table -> 'a table
 | 
| 23655 
d2d1138e0ddc
replaced exception TableFun/GraphFun.DUPS by TableFun/GraphFun.DUP;
 wenzelm parents: 
21065diff
changeset | 43 | val make: (key * 'a) list -> 'a table (*exception DUP*) | 
| 56051 | 44 | val join: (key -> 'a * 'a -> 'a) (*exception SAME*) -> | 
| 23655 
d2d1138e0ddc
replaced exception TableFun/GraphFun.DUPS by TableFun/GraphFun.DUP;
 wenzelm parents: 
21065diff
changeset | 45 | 'a table * 'a table -> 'a table (*exception DUP*) | 
| 
d2d1138e0ddc
replaced exception TableFun/GraphFun.DUPS by TableFun/GraphFun.DUP;
 wenzelm parents: 
21065diff
changeset | 46 |   val merge: ('a * 'a -> bool) -> 'a table * 'a table -> 'a table      (*exception DUP*)
 | 
| 15665 | 47 | val delete: key -> 'a table -> 'a table (*exception UNDEF*) | 
| 15761 | 48 | val delete_safe: key -> 'a table -> 'a table | 
| 16466 | 49 |   val member: ('b * 'a -> bool) -> 'a table -> key * 'b -> bool
 | 
| 15761 | 50 |   val insert: ('a * 'a -> bool) -> key * 'a -> 'a table -> 'a table    (*exception DUP*)
 | 
| 16139 | 51 |   val remove: ('b * 'a -> bool) -> key * 'b -> 'a table -> 'a table
 | 
| 18946 | 52 | val lookup_list: 'a list table -> key -> 'a list | 
| 31209 | 53 | val cons_list: key * 'a -> 'a list table -> 'a list table | 
| 19506 | 54 |   val insert_list: ('a * 'a -> bool) -> key * 'a -> 'a list table -> 'a list table
 | 
| 18946 | 55 |   val remove_list: ('b * 'a -> bool) -> key * 'b -> 'a list table -> 'a list table
 | 
| 25391 | 56 |   val update_list: ('a * 'a -> bool) -> key * 'a -> 'a list table -> 'a list table
 | 
| 18946 | 57 | val make_list: (key * 'a) list -> 'a list table | 
| 58 | val dest_list: 'a list table -> (key * 'a) list | |
| 33162 | 59 |   val merge_list: ('a * 'a -> bool) -> 'a list table * 'a list table -> 'a list table
 | 
| 50234 | 60 | type set = unit table | 
| 63511 | 61 | val insert_set: key -> set -> set | 
| 67529 | 62 | 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: 
56051diff
changeset | 63 | val make_set: key list -> set | 
| 5015 | 64 | end; | 
| 65 | ||
| 31971 
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
 wenzelm parents: 
31621diff
changeset | 66 | functor Table(Key: KEY): TABLE = | 
| 5015 | 67 | struct | 
| 68 | ||
| 69 | ||
| 70 | (* datatype table *) | |
| 71 | ||
| 72 | type key = Key.key; | |
| 73 | ||
| 74 | datatype 'a table = | |
| 75 | Empty | | |
| 76 | Branch2 of 'a table * (key * 'a) * 'a table | | |
| 77 | Branch3 of 'a table * (key * 'a) * 'a table * (key * 'a) * 'a table; | |
| 78 | ||
| 79 | exception DUP of key; | |
| 80 | ||
| 81 | ||
| 67537 | 82 | (* empty and single *) | 
| 5681 | 83 | |
| 5015 | 84 | val empty = Empty; | 
| 85 | ||
| 74232 | 86 | fun build (f: 'a table -> 'a table) = f empty; | 
| 87 | ||
| 5015 | 88 | fun is_empty Empty = true | 
| 89 | | is_empty _ = false; | |
| 90 | ||
| 67537 | 91 | fun is_single (Branch2 (Empty, _, Empty)) = true | 
| 92 | | is_single _ = false; | |
| 93 | ||
| 5681 | 94 | |
| 95 | (* map and fold combinators *) | |
| 96 | ||
| 16657 | 97 | fun map_table f = | 
| 98 | let | |
| 99 | fun map Empty = Empty | |
| 100 | | map (Branch2 (left, (k, x), right)) = | |
| 101 | Branch2 (map left, (k, f k x), map right) | |
| 102 | | map (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = | |
| 103 | Branch3 (map left, (k1, f k1 x1), map mid, (k2, f k2 x2), map right); | |
| 104 | in map end; | |
| 5681 | 105 | |
| 16657 | 106 | fun fold_table f = | 
| 107 | let | |
| 108 | fun fold Empty x = x | |
| 109 | | fold (Branch2 (left, p, right)) x = | |
| 110 | fold right (f p (fold left x)) | |
| 111 | | fold (Branch3 (left, p1, mid, p2, right)) x = | |
| 112 | fold right (f p2 (fold mid (f p1 (fold left x)))); | |
| 113 | in fold end; | |
| 5681 | 114 | |
| 28334 | 115 | fun fold_rev_table f = | 
| 116 | let | |
| 117 | fun fold Empty x = x | |
| 118 | | fold (Branch2 (left, p, right)) x = | |
| 119 | fold left (f p (fold right x)) | |
| 120 | | fold (Branch3 (left, p1, mid, p2, right)) x = | |
| 121 | fold left (f p1 (fold mid (f p2 (fold right x)))); | |
| 122 | in fold end; | |
| 123 | ||
| 124 | fun dest tab = fold_rev_table cons tab []; | |
| 125 | fun keys tab = fold_rev_table (cons o #1) tab []; | |
| 16192 | 126 | |
| 27508 | 127 | |
| 52049 | 128 | (* min/max entries *) | 
| 5015 | 129 | |
| 52049 | 130 | fun min Empty = NONE | 
| 131 | | min (Branch2 (Empty, p, _)) = SOME p | |
| 132 | | min (Branch3 (Empty, p, _, _, _)) = SOME p | |
| 133 | | min (Branch2 (left, _, _)) = min left | |
| 134 | | min (Branch3 (left, _, _, _, _)) = min left; | |
| 8409 | 135 | |
| 52049 | 136 | fun max Empty = NONE | 
| 137 | | max (Branch2 (_, p, Empty)) = SOME p | |
| 138 | | max (Branch3 (_, _, _, p, Empty)) = SOME p | |
| 139 | | max (Branch2 (_, _, right)) = max right | |
| 140 | | max (Branch3 (_, _, _, _, right)) = max right; | |
| 15665 | 141 | |
| 5015 | 142 | |
| 74227 | 143 | (* exists and forall *) | 
| 144 | ||
| 145 | fun exists pred = | |
| 146 | let | |
| 147 | fun ex Empty = false | |
| 148 | | ex (Branch2 (left, (k, x), right)) = | |
| 149 | ex left orelse pred (k, x) orelse ex right | |
| 150 | | ex (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = | |
| 151 | ex left orelse pred (k1, x1) orelse ex mid orelse pred (k2, x2) orelse ex right; | |
| 152 | in ex end; | |
| 153 | ||
| 154 | fun forall pred = not o exists (not o pred); | |
| 155 | ||
| 156 | ||
| 31616 | 157 | (* get_first *) | 
| 158 | ||
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 159 | fun get_first f = | 
| 31616 | 160 | let | 
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 161 | fun get Empty = NONE | 
| 31618 
2e4430b84303
improved get_first: check boundary before entering subtrees;
 wenzelm parents: 
31616diff
changeset | 162 | | get (Branch2 (left, (k, x), right)) = | 
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 163 | (case get left of | 
| 31616 | 164 | NONE => | 
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 165 | (case f (k, x) of | 
| 31616 | 166 | NONE => get right | 
| 167 | | some => some) | |
| 168 | | some => some) | |
| 31618 
2e4430b84303
improved get_first: check boundary before entering subtrees;
 wenzelm parents: 
31616diff
changeset | 169 | | get (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = | 
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 170 | (case get left of | 
| 31616 | 171 | NONE => | 
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 172 | (case f (k1, x1) of | 
| 31616 | 173 | NONE => | 
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 174 | (case get mid of | 
| 31616 | 175 | NONE => | 
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 176 | (case f (k2, x2) of | 
| 31616 | 177 | NONE => get right | 
| 178 | | some => some) | |
| 179 | | some => some) | |
| 180 | | some => some) | |
| 181 | | some => some); | |
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 182 | in get end; | 
| 31616 | 183 | |
| 184 | ||
| 5015 | 185 | (* lookup *) | 
| 186 | ||
| 67557 | 187 | fun lookup tab key = | 
| 188 | let | |
| 189 | fun look Empty = NONE | |
| 190 | | look (Branch2 (left, (k, x), right)) = | |
| 191 | (case Key.ord (key, k) of | |
| 192 | LESS => look left | |
| 193 | | EQUAL => SOME x | |
| 194 | | GREATER => look right) | |
| 195 | | look (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = | |
| 196 | (case Key.ord (key, k1) of | |
| 197 | LESS => look left | |
| 198 | | EQUAL => SOME x1 | |
| 199 | | GREATER => | |
| 200 | (case Key.ord (key, k2) of | |
| 201 | LESS => look mid | |
| 202 | | EQUAL => SOME x2 | |
| 203 | | GREATER => look right)); | |
| 204 | in look tab end; | |
| 205 | ||
| 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: 
39020diff
changeset | 206 | fun lookup_key tab key = | 
| 19031 | 207 | let | 
| 208 | fun look Empty = NONE | |
| 209 | | look (Branch2 (left, (k, x), right)) = | |
| 210 | (case Key.ord (key, k) of | |
| 211 | 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: 
39020diff
changeset | 212 | | EQUAL => SOME (k, x) | 
| 19031 | 213 | | GREATER => look right) | 
| 214 | | look (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = | |
| 215 | (case Key.ord (key, k1) of | |
| 216 | 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: 
39020diff
changeset | 217 | | EQUAL => SOME (k1, x1) | 
| 19031 | 218 | | GREATER => | 
| 219 | (case Key.ord (key, k2) of | |
| 220 | 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: 
39020diff
changeset | 221 | | EQUAL => SOME (k2, x2) | 
| 19031 | 222 | | GREATER => look right)); | 
| 223 | in look tab end; | |
| 5015 | 224 | |
| 19031 | 225 | fun defined tab key = | 
| 226 | let | |
| 227 | fun def Empty = false | |
| 228 | | def (Branch2 (left, (k, x), right)) = | |
| 229 | (case Key.ord (key, k) of | |
| 230 | LESS => def left | |
| 231 | | EQUAL => true | |
| 232 | | GREATER => def right) | |
| 233 | | def (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = | |
| 234 | (case Key.ord (key, k1) of | |
| 235 | LESS => def left | |
| 236 | | EQUAL => true | |
| 237 | | GREATER => | |
| 238 | (case Key.ord (key, k2) of | |
| 239 | LESS => def mid | |
| 240 | | EQUAL => true | |
| 241 | | GREATER => def right)); | |
| 242 | in def tab end; | |
| 16887 | 243 | |
| 5015 | 244 | |
| 19031 | 245 | (* modify *) | 
| 5015 | 246 | |
| 247 | datatype 'a growth = | |
| 248 | Stay of 'a table | | |
| 249 | Sprout of 'a table * (key * 'a) * 'a table; | |
| 250 | ||
| 15761 | 251 | exception SAME; | 
| 252 | ||
| 15665 | 253 | fun modify key f tab = | 
| 254 | let | |
| 255 | fun modfy Empty = Sprout (Empty, (key, f NONE), Empty) | |
| 256 | | modfy (Branch2 (left, p as (k, x), right)) = | |
| 257 | (case Key.ord (key, k) of | |
| 258 | LESS => | |
| 259 | (case modfy left of | |
| 260 | Stay left' => Stay (Branch2 (left', p, right)) | |
| 261 | | Sprout (left1, q, left2) => Stay (Branch3 (left1, q, left2, p, right))) | |
| 262 | | EQUAL => Stay (Branch2 (left, (k, f (SOME x)), right)) | |
| 263 | | GREATER => | |
| 264 | (case modfy right of | |
| 265 | Stay right' => Stay (Branch2 (left, p, right')) | |
| 266 | | Sprout (right1, q, right2) => | |
| 267 | Stay (Branch3 (left, p, right1, q, right2)))) | |
| 268 | | modfy (Branch3 (left, p1 as (k1, x1), mid, p2 as (k2, x2), right)) = | |
| 269 | (case Key.ord (key, k1) of | |
| 5015 | 270 | LESS => | 
| 15665 | 271 | (case modfy left of | 
| 272 | Stay left' => Stay (Branch3 (left', p1, mid, p2, right)) | |
| 273 | | Sprout (left1, q, left2) => | |
| 274 | Sprout (Branch2 (left1, q, left2), p1, Branch2 (mid, p2, right))) | |
| 275 | | EQUAL => Stay (Branch3 (left, (k1, f (SOME x1)), mid, p2, right)) | |
| 5015 | 276 | | GREATER => | 
| 15665 | 277 | (case Key.ord (key, k2) of | 
| 278 | LESS => | |
| 279 | (case modfy mid of | |
| 280 | Stay mid' => Stay (Branch3 (left, p1, mid', p2, right)) | |
| 281 | | Sprout (mid1, q, mid2) => | |
| 282 | Sprout (Branch2 (left, p1, mid1), q, Branch2 (mid2, p2, right))) | |
| 283 | | EQUAL => Stay (Branch3 (left, p1, mid, (k2, f (SOME x2)), right)) | |
| 284 | | GREATER => | |
| 285 | (case modfy right of | |
| 286 | Stay right' => Stay (Branch3 (left, p1, mid, p2, right')) | |
| 287 | | Sprout (right1, q, right2) => | |
| 288 | Sprout (Branch2 (left, p1, mid), p2, Branch2 (right1, q, right2))))); | |
| 5015 | 289 | |
| 15665 | 290 | in | 
| 291 | (case modfy tab of | |
| 292 | Stay tab' => tab' | |
| 293 | | Sprout br => Branch2 br) | |
| 294 | handle SAME => tab | |
| 295 | end; | |
| 5015 | 296 | |
| 17412 | 297 | fun update (key, x) tab = modify key (fn _ => x) tab; | 
| 298 | fun update_new (key, x) tab = modify key (fn NONE => x | SOME _ => raise DUP key) tab; | |
| 17709 | 299 | fun default (key, x) tab = modify key (fn NONE => x | SOME _ => raise SAME) tab; | 
| 15761 | 300 | fun map_entry key f = modify key (fn NONE => raise SAME | SOME x => f x); | 
| 27783 | 301 | fun map_default (key, x) f = modify key (fn NONE => f x | SOME y => f y); | 
| 5015 | 302 | |
| 303 | ||
| 15014 | 304 | (* delete *) | 
| 305 | ||
| 15665 | 306 | exception UNDEF of key; | 
| 307 | ||
| 308 | local | |
| 309 | ||
| 310 | fun compare NONE (k2, _) = LESS | |
| 311 | | compare (SOME k1) (k2, _) = Key.ord (k1, k2); | |
| 15014 | 312 | |
| 313 | fun if_eq EQUAL x y = x | |
| 314 | | if_eq _ x y = y; | |
| 315 | ||
| 15531 | 316 | fun del (SOME k) Empty = raise UNDEF k | 
| 317 | | del NONE (Branch2 (Empty, p, Empty)) = (p, (true, Empty)) | |
| 318 | | del NONE (Branch3 (Empty, p, Empty, q, Empty)) = | |
| 15014 | 319 | (p, (false, Branch2 (Empty, q, Empty))) | 
| 15665 | 320 | | del k (Branch2 (Empty, p, Empty)) = (case compare k p of | 
| 16002 | 321 | EQUAL => (p, (true, Empty)) | _ => raise UNDEF (the k)) | 
| 15665 | 322 | | del k (Branch3 (Empty, p, Empty, q, Empty)) = (case compare k p of | 
| 15014 | 323 | EQUAL => (p, (false, Branch2 (Empty, q, Empty))) | 
| 15665 | 324 | | _ => (case compare k q of | 
| 15014 | 325 | EQUAL => (q, (false, Branch2 (Empty, p, Empty))) | 
| 16002 | 326 | | _ => raise UNDEF (the k))) | 
| 15665 | 327 | | del k (Branch2 (l, p, r)) = (case compare k p of | 
| 15014 | 328 | LESS => (case del k l of | 
| 329 | (p', (false, l')) => (p', (false, Branch2 (l', p, r))) | |
| 330 | | (p', (true, l')) => (p', case r of | |
| 331 | Branch2 (rl, rp, rr) => | |
| 332 | (true, Branch3 (l', p, rl, rp, rr)) | |
| 333 | | Branch3 (rl, rp, rm, rq, rr) => (false, Branch2 | |
| 334 | (Branch2 (l', p, rl), rp, Branch2 (rm, rq, rr))))) | |
| 15531 | 335 | | ord => (case del (if_eq ord NONE k) r of | 
| 15014 | 336 | (p', (false, r')) => (p', (false, Branch2 (l, if_eq ord p' p, r'))) | 
| 337 | | (p', (true, r')) => (p', case l of | |
| 338 | Branch2 (ll, lp, lr) => | |
| 339 | (true, Branch3 (ll, lp, lr, if_eq ord p' p, r')) | |
| 340 | | Branch3 (ll, lp, lm, lq, lr) => (false, Branch2 | |
| 341 | (Branch2 (ll, lp, lm), lq, Branch2 (lr, if_eq ord p' p, r')))))) | |
| 15665 | 342 | | del k (Branch3 (l, p, m, q, r)) = (case compare k q of | 
| 343 | LESS => (case compare k p of | |
| 15014 | 344 | LESS => (case del k l of | 
| 345 | (p', (false, l')) => (p', (false, Branch3 (l', p, m, q, r))) | |
| 346 | | (p', (true, l')) => (p', (false, case (m, r) of | |
| 347 | (Branch2 (ml, mp, mr), Branch2 _) => | |
| 348 | Branch2 (Branch3 (l', p, ml, mp, mr), q, r) | |
| 349 | | (Branch3 (ml, mp, mm, mq, mr), _) => | |
| 350 | Branch3 (Branch2 (l', p, ml), mp, Branch2 (mm, mq, mr), q, r) | |
| 351 | | (Branch2 (ml, mp, mr), Branch3 (rl, rp, rm, rq, rr)) => | |
| 352 | Branch3 (Branch2 (l', p, ml), mp, Branch2 (mr, q, rl), rp, | |
| 353 | Branch2 (rm, rq, rr))))) | |
| 15531 | 354 | | ord => (case del (if_eq ord NONE k) m of | 
| 15014 | 355 | (p', (false, m')) => | 
| 356 | (p', (false, Branch3 (l, if_eq ord p' p, m', q, r))) | |
| 357 | | (p', (true, m')) => (p', (false, case (l, r) of | |
| 358 | (Branch2 (ll, lp, lr), Branch2 _) => | |
| 359 | Branch2 (Branch3 (ll, lp, lr, if_eq ord p' p, m'), q, r) | |
| 360 | | (Branch3 (ll, lp, lm, lq, lr), _) => | |
| 361 | Branch3 (Branch2 (ll, lp, lm), lq, | |
| 362 | Branch2 (lr, if_eq ord p' p, m'), q, r) | |
| 363 | | (_, Branch3 (rl, rp, rm, rq, rr)) => | |
| 364 | Branch3 (l, if_eq ord p' p, Branch2 (m', q, rl), rp, | |
| 365 | Branch2 (rm, rq, rr)))))) | |
| 15531 | 366 | | ord => (case del (if_eq ord NONE k) r of | 
| 15014 | 367 | (q', (false, r')) => | 
| 368 | (q', (false, Branch3 (l, p, m, if_eq ord q' q, r'))) | |
| 369 | | (q', (true, r')) => (q', (false, case (l, m) of | |
| 370 | (Branch2 _, Branch2 (ml, mp, mr)) => | |
| 371 | Branch2 (l, p, Branch3 (ml, mp, mr, if_eq ord q' q, r')) | |
| 372 | | (_, Branch3 (ml, mp, mm, mq, mr)) => | |
| 373 | Branch3 (l, p, Branch2 (ml, mp, mm), mq, | |
| 374 | Branch2 (mr, if_eq ord q' q, r')) | |
| 375 | | (Branch3 (ll, lp, lm, lq, lr), Branch2 (ml, mp, mr)) => | |
| 376 | Branch3 (Branch2 (ll, lp, lm), lq, Branch2 (lr, p, ml), mp, | |
| 377 | Branch2 (mr, if_eq ord q' q, r')))))); | |
| 378 | ||
| 15665 | 379 | in | 
| 380 | ||
| 15761 | 381 | fun delete key tab = snd (snd (del (SOME key) tab)); | 
| 44336 
59ff5a93eef4
tuned Table.delete_safe: avoid potentially expensive attempt of delete;
 wenzelm parents: 
43792diff
changeset | 382 | fun delete_safe key tab = if defined tab key then delete key tab else tab; | 
| 15014 | 383 | |
| 15665 | 384 | end; | 
| 385 | ||
| 15014 | 386 | |
| 19031 | 387 | (* membership operations *) | 
| 16466 | 388 | |
| 389 | fun member eq tab (key, x) = | |
| 17412 | 390 | (case lookup tab key of | 
| 16466 | 391 | NONE => false | 
| 392 | | SOME y => eq (x, y)); | |
| 15761 | 393 | |
| 394 | fun insert eq (key, x) = | |
| 395 | modify key (fn NONE => x | SOME y => if eq (x, y) then raise SAME else raise DUP key); | |
| 396 | ||
| 397 | fun remove eq (key, x) tab = | |
| 17412 | 398 | (case lookup tab key of | 
| 15761 | 399 | NONE => tab | 
| 400 | | SOME y => if eq (x, y) then delete key tab else tab); | |
| 401 | ||
| 402 | ||
| 19031 | 403 | (* simultaneous modifications *) | 
| 404 | ||
| 74266 | 405 | fun make entries = build (fold update_new entries); | 
| 5015 | 406 | |
| 12287 | 407 | fun join f (table1, table2) = | 
| 55727 
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
 wenzelm parents: 
52049diff
changeset | 408 | let | 
| 
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
 wenzelm parents: 
52049diff
changeset | 409 | 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: 
52049diff
changeset | 410 | in | 
| 
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
 wenzelm parents: 
52049diff
changeset | 411 | if pointer_eq (table1, table2) then table1 | 
| 
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
 wenzelm parents: 
52049diff
changeset | 412 | else if is_empty table1 then table2 | 
| 
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
 wenzelm parents: 
52049diff
changeset | 413 | else fold_table add table2 table1 | 
| 
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
 wenzelm parents: 
52049diff
changeset | 414 | end; | 
| 12287 | 415 | |
| 19031 | 416 | fun merge eq = join (fn key => fn xy => if eq xy then raise SAME else raise DUP key); | 
| 5015 | 417 | |
| 418 | ||
| 19031 | 419 | (* list tables *) | 
| 15761 | 420 | |
| 18946 | 421 | fun lookup_list tab key = these (lookup tab key); | 
| 25391 | 422 | |
| 423 | fun cons_list (key, x) tab = modify key (fn NONE => [x] | SOME xs => x :: xs) tab; | |
| 5015 | 424 | |
| 20124 | 425 | fun insert_list eq (key, x) = | 
| 426 | modify key (fn NONE => [x] | SOME xs => if Library.member eq xs x then raise SAME else x :: xs); | |
| 25391 | 427 | |
| 18946 | 428 | fun remove_list eq (key, x) tab = | 
| 15761 | 429 | map_entry key (fn xs => (case Library.remove eq x xs of [] => raise UNDEF key | ys => ys)) tab | 
| 430 | handle UNDEF _ => delete key tab; | |
| 5015 | 431 | |
| 25391 | 432 | fun update_list eq (key, x) = | 
| 433 | modify key (fn NONE => [x] | SOME [] => [x] | SOME (xs as y :: _) => | |
| 434 | if eq (x, y) then raise SAME else Library.update eq x xs); | |
| 435 | ||
| 74266 | 436 | fun make_list args = build (fold_rev cons_list args); | 
| 19482 
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
 wenzelm parents: 
19073diff
changeset | 437 | fun dest_list tab = maps (fn (key, xs) => map (pair key) xs) (dest tab); | 
| 19031 | 438 | fun merge_list eq = join (fn _ => Library.merge eq); | 
| 5015 | 439 | |
| 440 | ||
| 74227 | 441 | (* set operations *) | 
| 50234 | 442 | |
| 443 | type set = unit table; | |
| 444 | ||
| 67529 | 445 | fun insert_set x = default (x, ()); | 
| 446 | fun remove_set x : set -> set = delete_safe x; | |
| 74266 | 447 | fun make_set xs = build (fold insert_set xs); | 
| 50234 | 448 | |
| 449 | ||
| 47980 
c81801f881b3
simplified Poly/ML setup -- 5.3.0 is now the common base-line;
 wenzelm parents: 
44336diff
changeset | 450 | (* 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: 
35012diff
changeset | 451 | |
| 
f76ad0771f67
added ML toplevel pretty-printing for tables, using dummy for anything other than Poly/ML 5.3.0 (or later);
 wenzelm parents: 
35012diff
changeset | 452 | val _ = | 
| 62819 
d3ff367a16a0
careful export of type-dependent functions, without losing their special status;
 wenzelm parents: 
62503diff
changeset | 453 | ML_system_pp (fn depth => fn pretty => fn tab => | 
| 62503 | 454 | 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: 
35012diff
changeset | 455 |       (ML_Pretty.enum "," "{" "}"
 | 
| 62503 | 456 | (ML_Pretty.pair | 
| 62819 
d3ff367a16a0
careful export of type-dependent functions, without losing their special status;
 wenzelm parents: 
62503diff
changeset | 457 | (ML_Pretty.from_polyml o ML_system_pretty) | 
| 62503 | 458 | (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: 
35012diff
changeset | 459 | (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: 
35012diff
changeset | 460 | |
| 
f76ad0771f67
added ML toplevel pretty-printing for tables, using dummy for anything other than Poly/ML 5.3.0 (or later);
 wenzelm parents: 
35012diff
changeset | 461 | |
| 5681 | 462 | (*final declarations of this structure!*) | 
| 39020 | 463 | val map = map_table; | 
| 16446 | 464 | val fold = fold_table; | 
| 28334 | 465 | val fold_rev = fold_rev_table; | 
| 5015 | 466 | |
| 467 | end; | |
| 468 | ||
| 31971 
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
 wenzelm parents: 
31621diff
changeset | 469 | structure Inttab = Table(type key = int val ord = int_ord); | 
| 
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
 wenzelm parents: 
31621diff
changeset | 470 | structure Symtab = Table(type key = string val ord = fast_string_ord); | 
| 
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
 wenzelm parents: 
31621diff
changeset | 471 | structure Symreltab = Table(type key = string * string | 
| 30647 
ef8f46c3158a
added Symreltab (binary relations of symbols) instance of TableFun
 haftmann parents: 
30290diff
changeset | 472 | val ord = prod_ord fast_string_ord fast_string_ord); |