| author | wenzelm | 
| Thu, 12 Oct 2023 21:11:59 +0200 | |
| changeset 78768 | 280a228dc2f1 | 
| parent 77981 | f83702560730 | 
| child 79092 | 06176f4e2e70 | 
| 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 | 
| 77780 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 22 | val size: 'a table -> int | 
| 5015 | 23 | val empty: 'a table | 
| 74232 | 24 |   val build: ('a table -> 'a table) -> 'a table
 | 
| 5015 | 25 | val is_empty: '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: 
39020diff
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: 
21065diff
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: 
21065diff
changeset | 46 | 'a table * 'a table -> 'a table (*exception DUP*) | 
| 
d2d1138e0ddc
replaced exception TableFun/GraphFun.DUPS by TableFun/GraphFun.DUP;
 wenzelm parents: 
21065diff
changeset | 47 |   val merge: ('a * 'a -> bool) -> 'a table * 'a table -> 'a table      (*exception DUP*)
 | 
| 77822 | 48 | val joins: (key -> 'a * 'a -> 'a) (*exception SAME*) -> | 
| 49 | 'a table list -> 'a table (*exception DUP*) | |
| 50 |   val merges: ('a * 'a -> bool) -> 'a table list -> 'a table           (*exception DUP*)
 | |
| 15665 | 51 | val delete: key -> 'a table -> 'a table (*exception UNDEF*) | 
| 15761 | 52 | val delete_safe: key -> 'a table -> 'a table | 
| 16466 | 53 |   val member: ('b * 'a -> bool) -> 'a table -> key * 'b -> bool
 | 
| 15761 | 54 |   val insert: ('a * 'a -> bool) -> key * 'a -> 'a table -> 'a table    (*exception DUP*)
 | 
| 16139 | 55 |   val remove: ('b * 'a -> bool) -> key * 'b -> 'a table -> 'a table
 | 
| 18946 | 56 | val lookup_list: 'a list table -> key -> 'a list | 
| 31209 | 57 | val cons_list: key * 'a -> 'a list table -> 'a list table | 
| 19506 | 58 |   val insert_list: ('a * 'a -> bool) -> key * 'a -> 'a list table -> 'a list table
 | 
| 77981 | 59 |   val update_list: ('a * 'a -> bool) -> key * 'a -> 'a list table -> 'a list table
 | 
| 18946 | 60 |   val remove_list: ('b * 'a -> bool) -> key * 'b -> 'a list table -> 'a list table
 | 
| 61 | val make_list: (key * 'a) list -> 'a list table | |
| 62 | val dest_list: 'a list table -> (key * 'a) list | |
| 33162 | 63 |   val merge_list: ('a * 'a -> bool) -> 'a list table * 'a list table -> 'a list table
 | 
| 50234 | 64 | type set = unit table | 
| 63511 | 65 | val insert_set: key -> set -> set | 
| 67529 | 66 | 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 | 67 | val make_set: key list -> set | 
| 5015 | 68 | end; | 
| 69 | ||
| 31971 
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
 wenzelm parents: 
31621diff
changeset | 70 | functor Table(Key: KEY): TABLE = | 
| 5015 | 71 | struct | 
| 72 | ||
| 77733 | 73 | (* keys *) | 
| 74 | ||
| 77731 | 75 | structure Key = Key; | 
| 76 | type key = Key.key; | |
| 5015 | 77 | |
| 77733 | 78 | exception DUP of key; | 
| 79 | ||
| 5015 | 80 | |
| 77731 | 81 | (* datatype *) | 
| 5015 | 82 | |
| 83 | datatype 'a table = | |
| 84 | Empty | | |
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 85 | Leaf1 of key * 'a | | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 86 | Leaf2 of key * 'a * key * 'a | | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 87 | Leaf3 of key * 'a * key * 'a * key * 'a | | 
| 5015 | 88 | Branch2 of 'a table * (key * 'a) * 'a table | | 
| 77800 | 89 | Branch3 of 'a table * (key * 'a) * 'a table * (key * 'a) * 'a table | | 
| 90 | Size of int * 'a table; | |
| 5015 | 91 | |
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 92 | fun make2 (Empty, e, Empty) = Leaf1 e | 
| 77740 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 93 | | 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: 
77739diff
changeset | 94 | | make2 (left, e1, Branch2 (Empty, e2, Empty)) = make2 (left, e1, Leaf1 e2) | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 95 | | make2 (Branch3 (Empty, (k1, x1), Empty, (k2, x2), Empty), e3, right) = | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 96 | make2 (Leaf2 (k1, x1, k2, x2), e3, right) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 97 | | make2 (left, e1, Branch3 (Empty, (k2, x2), Empty, (k3, x3), Empty)) = | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 98 | make2 (left, e1, Leaf2 (k2, x2, k3, x3)) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 99 | | make2 (Leaf1 (k1, x1), (k2, x2), Empty) = Leaf2 (k1, x1, k2, x2) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 100 | | make2 (Empty, (k1, x1), Leaf1 (k2, x2)) = Leaf2 (k1, x1, k2, x2) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 101 | | make2 (Leaf1 (k1, x1), (k2, x2), Leaf1 (k3, x3)) = Leaf3 (k1, x1, k2, x2, k3, x3) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 102 | | make2 (Leaf2 (k1, x1, k2, x2), (k3, x3), Empty) = Leaf3 (k1, x1, k2, x2, k3, x3) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 103 | | make2 (Empty, (k1, x1), Leaf2 (k2, x2, k3, x3)) = Leaf3 (k1, x1, k2, x2, k3, x3) | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 104 | | make2 arg = Branch2 arg; | 
| 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 105 | |
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 106 | fun make3 (Empty, (k1, x1), Empty, (k2, x2), Empty) = Leaf2 (k1, x1, k2, x2) | 
| 77740 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 107 | | 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: 
77739diff
changeset | 108 | | 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: 
77739diff
changeset | 109 | | make3 (left, e1, mid, e2, Branch2 (Empty, e3, Empty)) = make3 (left, e1, mid, e2, Leaf1 e3) | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 110 | | make3 (Leaf1 (k1, x1), (k2, x2), Empty, (k3, x3), Empty) = Leaf3 (k1, x1, k2, x2, k3, x3) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 111 | | make3 (Empty, (k1, x1), Leaf1 (k2, x2), (k3, x3), Empty) = Leaf3 (k1, x1, k2, x2, k3, x3) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 112 | | make3 (Empty, (k1, x1), Empty, (k2, x2), Leaf1 (k3, x3)) = Leaf3 (k1, x1, k2, x2, k3, x3) | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 113 | | make3 arg = Branch3 arg; | 
| 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 114 | |
| 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 115 | fun unmake (Leaf1 e) = Branch2 (Empty, e, Empty) | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 116 | | unmake (Leaf2 (k1, x1, k2, x2)) = Branch3 (Empty, (k1, x1), Empty, (k2, x2), Empty) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 117 | | unmake (Leaf3 (k1, x1, k2, x2, k3, x3)) = | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 118 | Branch2 (Branch2 (Empty, (k1, x1), Empty), (k2, x2), Branch2 (Empty, (k3, x3), Empty)) | 
| 77800 | 119 | | unmake (Size (_, arg)) = arg | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 120 | | unmake arg = arg; | 
| 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 121 | |
| 5015 | 122 | |
| 77780 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 123 | (* size *) | 
| 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 124 | |
| 77800 | 125 | (*literal copy from set.ML*) | 
| 77780 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 126 | local | 
| 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 127 | fun count Empty n = n | 
| 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 128 | | count (Leaf1 _) n = n + 1 | 
| 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 129 | | count (Leaf2 _) n = n + 2 | 
| 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 130 | | count (Leaf3 _) n = n + 3 | 
| 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 131 | | count (Branch2 (left, _, right)) n = count right (count left (n + 1)) | 
| 77800 | 132 | | count (Branch3 (left, _, mid, _, right)) n = count right (count mid (count left (n + 2))) | 
| 133 | | count (Size (m, _)) n = m + n; | |
| 77802 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 134 | |
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 135 | fun box (Branch2 _) = 1 | 
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 136 | | box (Branch3 _) = 1 | 
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 137 | | box _ = 0; | 
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 138 | |
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 139 | fun bound arg b = | 
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 140 | if b > 0 then | 
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 141 | (case arg of | 
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 142 | Branch2 (left, _, right) => | 
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 143 | bound right (bound left (b - box left - box right)) | 
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 144 | | Branch3 (left, _, mid, _, right) => | 
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 145 | bound right (bound mid (bound left (b - box left - box mid - box right))) | 
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 146 | | _ => b) | 
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 147 | else b; | 
| 77780 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 148 | in | 
| 77802 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 149 | fun size arg = count arg 0; | 
| 
25c114e2528e
performance tuning: make_size accounts for boxes, i.e. pointer derefs required in "count";
 wenzelm parents: 
77800diff
changeset | 150 | fun make_size m arg = if bound arg 3 <= 0 then Size (m, arg) else arg; | 
| 77780 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 151 | end; | 
| 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 152 | |
| 
97febdb6ee58
clarified signature: more uniform Table() vs. Set();
 wenzelm parents: 
77768diff
changeset | 153 | |
| 77743 | 154 | (* empty *) | 
| 5681 | 155 | |
| 5015 | 156 | val empty = Empty; | 
| 157 | ||
| 74232 | 158 | fun build (f: 'a table -> 'a table) = f empty; | 
| 159 | ||
| 77800 | 160 | (*literal copy from set.ML*) | 
| 5015 | 161 | fun is_empty Empty = true | 
| 77800 | 162 | | is_empty (Size (_, arg)) = is_empty arg | 
| 5015 | 163 | | is_empty _ = false; | 
| 164 | ||
| 5681 | 165 | |
| 166 | (* map and fold combinators *) | |
| 167 | ||
| 16657 | 168 | fun map_table f = | 
| 169 | let | |
| 170 | fun map Empty = Empty | |
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 171 | | map (Leaf1 (k, x)) = Leaf1 (k, f k x) | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 172 | | map (Leaf2 (k1, x1, k2, x2)) = Leaf2 (k1, f k1 x1, k2, f k2 x2) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 173 | | map (Leaf3 (k1, x1, k2, x2, k3, x3)) = Leaf3 (k1, f k1 x1, k2, f k2 x2, k3, f k3 x3) | 
| 16657 | 174 | | map (Branch2 (left, (k, x), right)) = | 
| 175 | Branch2 (map left, (k, f k x), map right) | |
| 176 | | map (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = | |
| 77800 | 177 | Branch3 (map left, (k1, f k1 x1), map mid, (k2, f k2 x2), map right) | 
| 178 | | map (Size (m, arg)) = Size (m, map arg); | |
| 16657 | 179 | in map end; | 
| 5681 | 180 | |
| 16657 | 181 | fun fold_table f = | 
| 182 | let | |
| 77813 | 183 | fun fold Empty a = a | 
| 184 | | fold (Leaf1 e) a = f e a | |
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 185 | | fold (Leaf2 (k1, x1, k2, x2)) a = f (k2, x2) (f (k1, x1) a) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 186 | | fold (Leaf3 (k1, x1, k2, x2, k3, x3)) a = f (k3, x3) (f (k2, x2) (f (k1, x1) a)) | 
| 77813 | 187 | | fold (Branch2 (left, e, right)) a = | 
| 188 | fold right (f e (fold left a)) | |
| 189 | | fold (Branch3 (left, e1, mid, e2, right)) a = | |
| 190 | fold right (f e2 (fold mid (f e1 (fold left a)))) | |
| 191 | | fold (Size (_, arg)) a = fold arg a; | |
| 16657 | 192 | in fold end; | 
| 5681 | 193 | |
| 28334 | 194 | fun fold_rev_table f = | 
| 195 | let | |
| 77813 | 196 | fun fold_rev Empty a = a | 
| 197 | | fold_rev (Leaf1 e) a = f e a | |
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 198 | | fold_rev (Leaf2 (k1, x1, k2, x2)) a = f (k1, x1) (f (k2, x2) a) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 199 | | fold_rev (Leaf3 (k1, x1, k2, x2, k3, x3)) a = f (k1, x1) (f (k2, x2) (f (k3, x3) a)) | 
| 77813 | 200 | | fold_rev (Branch2 (left, e, right)) a = | 
| 201 | fold_rev left (f e (fold_rev right a)) | |
| 202 | | fold_rev (Branch3 (left, e1, mid, e2, right)) a = | |
| 203 | fold_rev left (f e1 (fold_rev mid (f e2 (fold_rev right a)))) | |
| 204 | | fold_rev (Size (_, arg)) a = fold_rev arg a; | |
| 77732 | 205 | in fold_rev end; | 
| 28334 | 206 | |
| 77768 | 207 | fun dest tab = Library.build (fold_rev_table cons tab); | 
| 208 | fun keys tab = Library.build (fold_rev_table (cons o #1) tab); | |
| 16192 | 209 | |
| 27508 | 210 | |
| 52049 | 211 | (* min/max entries *) | 
| 5015 | 212 | |
| 52049 | 213 | fun min Empty = NONE | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 214 | | min (Leaf1 e) = SOME e | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 215 | | min (Leaf2 (k, x, _, _)) = SOME (k, x) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 216 | | min (Leaf3 (k, x, _, _, _, _)) = SOME (k, x) | 
| 77727 
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
 wenzelm parents: 
77721diff
changeset | 217 | | min (Branch2 (Empty, e, _)) = SOME e | 
| 
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
 wenzelm parents: 
77721diff
changeset | 218 | | min (Branch3 (Empty, e, _, _, _)) = SOME e | 
| 52049 | 219 | | min (Branch2 (left, _, _)) = min left | 
| 77800 | 220 | | min (Branch3 (left, _, _, _, _)) = min left | 
| 221 | | min (Size (_, arg)) = min arg; | |
| 8409 | 222 | |
| 52049 | 223 | fun max Empty = NONE | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 224 | | max (Leaf1 e) = SOME e | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 225 | | max (Leaf2 (_, _, k, x)) = SOME (k, x) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 226 | | max (Leaf3 (_, _, _, _, k, x)) = SOME (k, x) | 
| 77727 
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
 wenzelm parents: 
77721diff
changeset | 227 | | max (Branch2 (_, e, Empty)) = SOME e | 
| 
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
 wenzelm parents: 
77721diff
changeset | 228 | | max (Branch3 (_, _, _, e, Empty)) = SOME e | 
| 52049 | 229 | | max (Branch2 (_, _, right)) = max right | 
| 77800 | 230 | | max (Branch3 (_, _, _, _, right)) = max right | 
| 231 | | max (Size (_, arg)) = max arg; | |
| 15665 | 232 | |
| 5015 | 233 | |
| 74227 | 234 | (* exists and forall *) | 
| 235 | ||
| 236 | fun exists pred = | |
| 237 | let | |
| 238 | fun ex Empty = false | |
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 239 | | ex (Leaf1 e) = pred e | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 240 | | ex (Leaf2 (k1, x1, k2, x2)) = pred (k1, x1) orelse pred (k2, x2) | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 241 | | ex (Leaf3 (k1, x1, k2, x2, k3, x3)) = | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 242 | pred (k1, x1) orelse pred (k2, x2) orelse pred (k3, x3) | 
| 77727 
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
 wenzelm parents: 
77721diff
changeset | 243 | | ex (Branch2 (left, e, right)) = | 
| 
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
 wenzelm parents: 
77721diff
changeset | 244 | ex left orelse pred e orelse ex right | 
| 
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
 wenzelm parents: 
77721diff
changeset | 245 | | ex (Branch3 (left, e1, mid, e2, right)) = | 
| 77800 | 246 | ex left orelse pred e1 orelse ex mid orelse pred e2 orelse ex right | 
| 247 | | ex (Size (_, arg)) = ex arg; | |
| 74227 | 248 | in ex end; | 
| 249 | ||
| 250 | fun forall pred = not o exists (not o pred); | |
| 251 | ||
| 252 | ||
| 31616 | 253 | (* get_first *) | 
| 254 | ||
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 255 | fun get_first f = | 
| 31616 | 256 | let | 
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 257 | fun get Empty = NONE | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 258 | | get (Leaf1 e) = f e | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 259 | | get (Leaf2 (k1, x1, k2, x2)) = | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 260 | (case f (k1, x1) of | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 261 | NONE => f (k2, x2) | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 262 | | some => some) | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 263 | | get (Leaf3 (k1, x1, k2, x2, k3, x3)) = | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 264 | (case f (k1, x1) of | 
| 77740 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 265 | NONE => | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 266 | (case f (k2, x2) of | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 267 | NONE => f (k3, x3) | 
| 77740 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 268 | | some => some) | 
| 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 269 | | some => some) | 
| 77727 
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
 wenzelm parents: 
77721diff
changeset | 270 | | get (Branch2 (left, e, right)) = | 
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 271 | (case get left of | 
| 31616 | 272 | NONE => | 
| 77727 
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
 wenzelm parents: 
77721diff
changeset | 273 | (case f e of | 
| 31616 | 274 | NONE => get right | 
| 275 | | some => some) | |
| 276 | | some => some) | |
| 77727 
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
 wenzelm parents: 
77721diff
changeset | 277 | | get (Branch3 (left, e1, mid, e2, right)) = | 
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 278 | (case get left of | 
| 31616 | 279 | NONE => | 
| 77727 
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
 wenzelm parents: 
77721diff
changeset | 280 | (case f e1 of | 
| 31616 | 281 | NONE => | 
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 282 | (case get mid of | 
| 31616 | 283 | NONE => | 
| 77727 
b98edf66ca96
tuned names: "e" means "entry" in table.ML and "elem" in set.ML;
 wenzelm parents: 
77721diff
changeset | 284 | (case f e2 of | 
| 31616 | 285 | NONE => get right | 
| 286 | | some => some) | |
| 287 | | some => some) | |
| 288 | | some => some) | |
| 77800 | 289 | | some => some) | 
| 290 | | get (Size (_, arg)) = get arg; | |
| 35012 
c3e3ac3ca091
removed unused "boundary" of Table/Graph.get_first;
 wenzelm parents: 
33162diff
changeset | 291 | in get end; | 
| 31616 | 292 | |
| 293 | ||
| 5015 | 294 | (* lookup *) | 
| 295 | ||
| 67557 | 296 | fun lookup tab key = | 
| 297 | let | |
| 77742 | 298 | fun key_ord k = Key.ord (key, k); | 
| 299 | val key_eq = is_equal o key_ord; | |
| 300 | ||
| 67557 | 301 | fun look Empty = NONE | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 302 | | look (Leaf1 (k, x)) = | 
| 77742 | 303 | if key_eq k then SOME x else NONE | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 304 | | look (Leaf2 (k1, x1, k2, x2)) = | 
| 77742 | 305 | (case key_ord k1 of | 
| 77740 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 306 | LESS => NONE | 
| 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 307 | | EQUAL => SOME x1 | 
| 77742 | 308 | | GREATER => if key_eq k2 then SOME x2 else NONE) | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 309 | | look (Leaf3 (k1, x1, k2, x2, k3, x3)) = | 
| 77742 | 310 | (case key_ord k2 of | 
| 311 | LESS => if key_eq k1 then SOME x1 else NONE | |
| 77740 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 312 | | EQUAL => SOME x2 | 
| 77742 | 313 | | GREATER => if key_eq k3 then SOME x3 else NONE) | 
| 67557 | 314 | | look (Branch2 (left, (k, x), right)) = | 
| 77742 | 315 | (case key_ord k of | 
| 67557 | 316 | LESS => look left | 
| 317 | | EQUAL => SOME x | |
| 318 | | GREATER => look right) | |
| 319 | | look (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = | |
| 77742 | 320 | (case key_ord k1 of | 
| 67557 | 321 | LESS => look left | 
| 322 | | EQUAL => SOME x1 | |
| 323 | | GREATER => | |
| 77742 | 324 | (case key_ord k2 of | 
| 67557 | 325 | LESS => look mid | 
| 326 | | EQUAL => SOME x2 | |
| 77800 | 327 | | GREATER => look right)) | 
| 328 | | look (Size (_, arg)) = look arg; | |
| 67557 | 329 | in look tab end; | 
| 330 | ||
| 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 | 331 | fun lookup_key tab key = | 
| 19031 | 332 | let | 
| 77742 | 333 | fun key_ord k = Key.ord (key, k); | 
| 334 | val key_eq = is_equal o key_ord; | |
| 335 | ||
| 19031 | 336 | fun look Empty = NONE | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 337 | | look (Leaf1 (k, x)) = | 
| 77742 | 338 | if key_eq k then SOME (k, x) else NONE | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 339 | | look (Leaf2 (k1, x1, k2, x2)) = | 
| 77742 | 340 | (case key_ord k1 of | 
| 77740 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 341 | LESS => NONE | 
| 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 342 | | EQUAL => SOME (k1, x1) | 
| 77742 | 343 | | GREATER => if key_eq k2 then SOME (k2, x2) else NONE) | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 344 | | look (Leaf3 (k1, x1, k2, x2, k3, x3)) = | 
| 77742 | 345 | (case key_ord k2 of | 
| 346 | LESS => if key_eq k1 then SOME (k1, x1) else NONE | |
| 77740 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 347 | | EQUAL => SOME (k2, x2) | 
| 77742 | 348 | | GREATER => if key_eq k3 then SOME (k3, x3) else NONE) | 
| 19031 | 349 | | look (Branch2 (left, (k, x), right)) = | 
| 77742 | 350 | (case key_ord k of | 
| 19031 | 351 | 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 | 352 | | EQUAL => SOME (k, x) | 
| 19031 | 353 | | GREATER => look right) | 
| 354 | | look (Branch3 (left, (k1, x1), mid, (k2, x2), right)) = | |
| 77742 | 355 | (case key_ord k1 of | 
| 19031 | 356 | 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 | 357 | | EQUAL => SOME (k1, x1) | 
| 19031 | 358 | | GREATER => | 
| 77742 | 359 | (case key_ord k2 of | 
| 19031 | 360 | 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 | 361 | | EQUAL => SOME (k2, x2) | 
| 77800 | 362 | | GREATER => look right)) | 
| 363 | | look (Size (_, arg)) = look arg; | |
| 19031 | 364 | in look tab end; | 
| 5015 | 365 | |
| 19031 | 366 | fun defined tab key = | 
| 367 | let | |
| 77742 | 368 | fun key_ord k = Key.ord (key, k); | 
| 369 | val key_eq = is_equal o key_ord; | |
| 370 | ||
| 19031 | 371 | fun def Empty = false | 
| 77742 | 372 | | def (Leaf1 (k, _)) = key_eq k | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 373 | | def (Leaf2 (k1, _, k2, _)) = | 
| 77742 | 374 | (case key_ord k1 of | 
| 77740 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 375 | LESS => false | 
| 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 376 | | EQUAL => true | 
| 77742 | 377 | | GREATER => key_eq k2) | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 378 | | def (Leaf3 (k1, _, k2, _, k3, _)) = | 
| 77742 | 379 | (case key_ord k2 of | 
| 380 | LESS => key_eq k1 | |
| 77740 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 381 | | EQUAL => true | 
| 77742 | 382 | | GREATER => key_eq k3) | 
| 77735 | 383 | | def (Branch2 (left, (k, _), right)) = | 
| 77742 | 384 | (case key_ord k of | 
| 19031 | 385 | LESS => def left | 
| 386 | | EQUAL => true | |
| 387 | | GREATER => def right) | |
| 77735 | 388 | | def (Branch3 (left, (k1, _), mid, (k2, _), right)) = | 
| 77742 | 389 | (case key_ord k1 of | 
| 19031 | 390 | LESS => def left | 
| 391 | | EQUAL => true | |
| 392 | | GREATER => | |
| 77742 | 393 | (case key_ord k2 of | 
| 19031 | 394 | LESS => def mid | 
| 395 | | EQUAL => true | |
| 77800 | 396 | | GREATER => def right)) | 
| 397 | | def (Size (_, arg)) = def arg; | |
| 19031 | 398 | in def tab end; | 
| 16887 | 399 | |
| 5015 | 400 | |
| 19031 | 401 | (* modify *) | 
| 5015 | 402 | |
| 403 | datatype 'a growth = | |
| 404 | Stay of 'a table | | |
| 405 | Sprout of 'a table * (key * 'a) * 'a table; | |
| 406 | ||
| 15761 | 407 | exception SAME; | 
| 408 | ||
| 15665 | 409 | fun modify key f tab = | 
| 410 | let | |
| 77742 | 411 | fun key_ord k = Key.ord (key, k); | 
| 412 | ||
| 77800 | 413 | val inc = Unsynchronized.ref 0; | 
| 414 | fun insert () = f NONE before ignore (Unsynchronized.inc inc); | |
| 415 | fun update x = f (SOME x); | |
| 416 | ||
| 417 | fun modfy Empty = Sprout (Empty, (key, insert ()), Empty) | |
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 418 | | 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: 
77735diff
changeset | 419 | | modfy (t as Leaf2 _) = modfy (unmake t) | 
| 77740 
19c539f5d4d3
more compact data: approx. 0.85 .. 1.10 of plain list size;
 wenzelm parents: 
77739diff
changeset | 420 | | modfy (t as Leaf3 _) = modfy (unmake t) | 
| 15665 | 421 | | modfy (Branch2 (left, p as (k, x), right)) = | 
| 77742 | 422 | (case key_ord k of | 
| 15665 | 423 | LESS => | 
| 424 | (case modfy left of | |
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 425 | 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: 
77735diff
changeset | 426 | | Sprout (left1, q, left2) => Stay (make3 (left1, q, left2, p, right))) | 
| 77800 | 427 | | EQUAL => Stay (make2 (left, (k, update x), right)) | 
| 15665 | 428 | | GREATER => | 
| 429 | (case modfy right of | |
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 430 | Stay right' => Stay (make2 (left, p, right')) | 
| 15665 | 431 | | Sprout (right1, q, right2) => | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 432 | Stay (make3 (left, p, right1, q, right2)))) | 
| 15665 | 433 | | modfy (Branch3 (left, p1 as (k1, x1), mid, p2 as (k2, x2), right)) = | 
| 77742 | 434 | (case key_ord k1 of | 
| 5015 | 435 | LESS => | 
| 15665 | 436 | (case modfy left of | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 437 | Stay left' => Stay (make3 (left', p1, mid, p2, right)) | 
| 15665 | 438 | | Sprout (left1, q, left2) => | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 439 | Sprout (make2 (left1, q, left2), p1, make2 (mid, p2, right))) | 
| 77800 | 440 | | EQUAL => Stay (make3 (left, (k1, update x1), mid, p2, right)) | 
| 5015 | 441 | | GREATER => | 
| 77742 | 442 | (case key_ord k2 of | 
| 15665 | 443 | LESS => | 
| 444 | (case modfy mid of | |
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 445 | Stay mid' => Stay (make3 (left, p1, mid', p2, right)) | 
| 15665 | 446 | | Sprout (mid1, q, mid2) => | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 447 | Sprout (make2 (left, p1, mid1), q, make2 (mid2, p2, right))) | 
| 77800 | 448 | | EQUAL => Stay (make3 (left, p1, mid, (k2, update x2), right)) | 
| 15665 | 449 | | GREATER => | 
| 450 | (case modfy right of | |
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 451 | Stay right' => Stay (make3 (left, p1, mid, p2, right')) | 
| 15665 | 452 | | Sprout (right1, q, right2) => | 
| 77800 | 453 | Sprout (make2 (left, p1, mid), p2, make2 (right1, q, right2))))) | 
| 454 | | modfy (Size (_, arg)) = modfy arg; | |
| 5015 | 455 | |
| 77800 | 456 | val tab' = | 
| 77882 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 457 | (case tab of | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 458 | Empty => Leaf1 (key, insert ()) | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 459 | | Leaf1 (k, x) => | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 460 | (case key_ord k of | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 461 | LESS => Leaf2 (key, insert (), k, x) | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 462 | | EQUAL => Leaf1 (k, update x) | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 463 | | GREATER => Leaf2 (k, x, key, insert ())) | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 464 | | Leaf2 (k1, x1, k2, x2) => | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 465 | (case key_ord k1 of | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 466 | LESS => Leaf3 (key, insert (), k1, x1, k2, x2) | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 467 | | EQUAL => Leaf2 (k1, update x1, k2, x2) | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 468 | | GREATER => | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 469 | (case key_ord k2 of | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 470 | LESS => Leaf3 (k1, x1, key, insert (), k2, x2) | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 471 | | EQUAL => Leaf2 (k1, x1, k2, update x2) | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 472 | | GREATER => Leaf3 (k1, x1, k2, x2, key, insert ()))) | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 473 | | _ => | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 474 | (case modfy tab of | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 475 | Stay tab' => tab' | 
| 
bb7238e7d2d9
minor performance tuning: avoid excessive (de)constructions for base cases;
 wenzelm parents: 
77881diff
changeset | 476 | | Sprout br => make2 br)); | 
| 15665 | 477 | in | 
| 77800 | 478 | make_size (size tab + !inc) tab' | 
| 479 | end handle SAME => tab; | |
| 5015 | 480 | |
| 17412 | 481 | fun update (key, x) tab = modify key (fn _ => x) tab; | 
| 482 | fun update_new (key, x) tab = modify key (fn NONE => x | SOME _ => raise DUP key) tab; | |
| 17709 | 483 | fun default (key, x) tab = modify key (fn NONE => x | SOME _ => raise SAME) tab; | 
| 15761 | 484 | fun map_entry key f = modify key (fn NONE => raise SAME | SOME x => f x); | 
| 27783 | 485 | fun map_default (key, x) f = modify key (fn NONE => f x | SOME y => f y); | 
| 5015 | 486 | |
| 487 | ||
| 15014 | 488 | (* delete *) | 
| 489 | ||
| 15665 | 490 | exception UNDEF of key; | 
| 491 | ||
| 492 | local | |
| 493 | ||
| 77735 | 494 | fun compare NONE _ = LESS | 
| 15665 | 495 | | compare (SOME k1) (k2, _) = Key.ord (k1, k2); | 
| 15014 | 496 | |
| 77737 | 497 | fun if_equal ord x y = if is_equal ord then x else y; | 
| 15014 | 498 | |
| 15531 | 499 | fun del (SOME k) Empty = raise UNDEF k | 
| 77735 | 500 | | del NONE Empty = raise Match | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 501 | | del NONE (Leaf1 p) = (p, (true, Empty)) | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 502 | | del NONE (Leaf2 (k1, x1, k2, x2)) = ((k1, x1), (false, Leaf1 (k2, x2))) | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 503 | | del k (Leaf1 p) = | 
| 77721 | 504 | (case compare k p of | 
| 505 | EQUAL => (p, (true, Empty)) | |
| 506 | | _ => raise UNDEF (the k)) | |
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 507 | | del k (Leaf2 (k1, x1, k2, x2)) = | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 508 | (case compare k (k1, x1) of | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 509 | EQUAL => ((k1, x1), (false, Leaf1 (k2, x2))) | 
| 77721 | 510 | | _ => | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 511 | (case compare k (k2, x2) of | 
| 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 512 | EQUAL => ((k2, x2), (false, Leaf1 (k1, x1))) | 
| 77721 | 513 | | _ => raise UNDEF (the k))) | 
| 77814 
53c5ad1a7ac0
more compact data: approx. 75% .. 85% of AList size;
 wenzelm parents: 
77813diff
changeset | 514 | | del k (Leaf3 (k1, x1, k2, x2, k3, x3)) = del k (Branch2 (Leaf1 (k1, x1), (k2, x2), Leaf1 (k3, x3))) | 
| 77721 | 515 | | del k (Branch2 (l, p, r)) = | 
| 516 | (case compare k p of | |
| 517 | LESS => | |
| 518 | (case del k l of | |
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 519 | (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: 
77735diff
changeset | 520 | | (p', (true, l')) => (p', case unmake r of | 
| 77721 | 521 | Branch2 (rl, rp, rr) => | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 522 | (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: 
77735diff
changeset | 523 | | 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: 
77735diff
changeset | 524 | (make2 (l', p, rl), rp, make2 (rm, rq, rr))))) | 
| 77721 | 525 | | ord => | 
| 77737 | 526 | (case del (if_equal ord NONE k) r of | 
| 527 | (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: 
77735diff
changeset | 528 | | (p', (true, r')) => (p', case unmake l of | 
| 77721 | 529 | Branch2 (ll, lp, lr) => | 
| 77737 | 530 | (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: 
77735diff
changeset | 531 | | Branch3 (ll, lp, lm, lq, lr) => (false, make2 | 
| 77737 | 532 | (make2 (ll, lp, lm), lq, make2 (lr, if_equal ord p' p, r')))))) | 
| 77721 | 533 | | del k (Branch3 (l, p, m, q, r)) = | 
| 534 | (case compare k q of | |
| 535 | LESS => | |
| 536 | (case compare k p of | |
| 537 | LESS => | |
| 538 | (case del k l of | |
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 539 | (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: 
77735diff
changeset | 540 | | (p', (true, l')) => (p', (false, case (unmake m, unmake r) of | 
| 77721 | 541 | (Branch2 (ml, mp, mr), Branch2 _) => | 
| 77736 
570f1436fe0a
more compact representation of leaf nodes: only 1.10 .. 1.33 larger than plain list;
 wenzelm parents: 
77735diff
changeset | 542 | make2 (make3 (l', p, ml, mp, mr), q, r) | 
| 77721 | 543 | | (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: 
77735diff
changeset | 544 | make3 (make2 (l', p, ml), mp, make2 (mm, mq, mr), q, r) | 
| 77721 | 545 | | (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: 
77735diff
changeset | 546 | 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: 
77735diff
changeset | 547 | make2 (rm, rq, rr))))) | 
| 77721 | 548 | | ord => | 
| 77737 | 549 | (case del (if_equal ord NONE k) m of | 
| 77721 | 550 | (p', (false, m')) => | 
| 77737 | 551 | (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: 
77735diff
changeset | 552 | | (p', (true, m')) => (p', (false, case (unmake l, unmake r) of | 
| 77721 | 553 | (Branch2 (ll, lp, lr), Branch2 _) => | 
| 77737 | 554 | make2 (make3 (ll, lp, lr, if_equal ord p' p, m'), q, r) | 
| 77721 | 555 | | (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: 
77735diff
changeset | 556 | make3 (make2 (ll, lp, lm), lq, | 
| 77737 | 557 | make2 (lr, if_equal ord p' p, m'), q, r) | 
| 77721 | 558 | | (_, Branch3 (rl, rp, rm, rq, rr)) => | 
| 77737 | 559 | 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: 
77735diff
changeset | 560 | make2 (rm, rq, rr)))))) | 
| 77721 | 561 | | ord => | 
| 77737 | 562 | (case del (if_equal ord NONE k) r of | 
| 77721 | 563 | (q', (false, r')) => | 
| 77737 | 564 | (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: 
77735diff
changeset | 565 | | (q', (true, r')) => (q', (false, case (unmake l, unmake m) of | 
| 77721 | 566 | (Branch2 _, Branch2 (ml, mp, mr)) => | 
| 77737 | 567 | make2 (l, p, make3 (ml, mp, mr, if_equal ord q' q, r')) | 
| 77721 | 568 | | (_, 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: 
77735diff
changeset | 569 | make3 (l, p, make2 (ml, mp, mm), mq, | 
| 77737 | 570 | make2 (mr, if_equal ord q' q, r')) | 
| 77721 | 571 | | (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: 
77735diff
changeset | 572 | make3 (make2 (ll, lp, lm), lq, make2 (lr, p, ml), mp, | 
| 77800 | 573 | make2 (mr, if_equal ord q' q, r')))))) | 
| 574 | | del k (Size (_, arg)) = del k arg; | |
| 15665 | 575 | in | 
| 576 | ||
| 77800 | 577 | fun delete key tab = make_size (size tab - 1) (snd (snd (del (SOME key) tab))); | 
| 44336 
59ff5a93eef4
tuned Table.delete_safe: avoid potentially expensive attempt of delete;
 wenzelm parents: 
43792diff
changeset | 578 | fun delete_safe key tab = if defined tab key then delete key tab else tab; | 
| 15014 | 579 | |
| 15665 | 580 | end; | 
| 581 | ||
| 15014 | 582 | |
| 19031 | 583 | (* membership operations *) | 
| 16466 | 584 | |
| 585 | fun member eq tab (key, x) = | |
| 17412 | 586 | (case lookup tab key of | 
| 16466 | 587 | NONE => false | 
| 588 | | SOME y => eq (x, y)); | |
| 15761 | 589 | |
| 590 | fun insert eq (key, x) = | |
| 591 | modify key (fn NONE => x | SOME y => if eq (x, y) then raise SAME else raise DUP key); | |
| 592 | ||
| 593 | fun remove eq (key, x) tab = | |
| 17412 | 594 | (case lookup tab key of | 
| 15761 | 595 | NONE => tab | 
| 596 | | SOME y => if eq (x, y) then delete key tab else tab); | |
| 597 | ||
| 598 | ||
| 19031 | 599 | (* simultaneous modifications *) | 
| 600 | ||
| 74266 | 601 | fun make entries = build (fold update_new entries); | 
| 5015 | 602 | |
| 77781 | 603 | fun join f (tab1, tab2) = | 
| 55727 
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
 wenzelm parents: 
52049diff
changeset | 604 | let | 
| 
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
 wenzelm parents: 
52049diff
changeset | 605 | 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 | 606 | in | 
| 77781 | 607 | if pointer_eq (tab1, tab2) then tab1 | 
| 608 | else if is_empty tab1 then tab2 | |
| 609 | else fold_table add tab2 tab1 | |
| 55727 
7e330ae052bb
optimize special case according to Library.merge (see also 8fbc355100f2, 520872460b7b);
 wenzelm parents: 
52049diff
changeset | 610 | end; | 
| 12287 | 611 | |
| 19031 | 612 | fun merge eq = join (fn key => fn xy => if eq xy then raise SAME else raise DUP key); | 
| 5015 | 613 | |
| 77822 | 614 | fun joins f tabs = Library.foldl (join f) (empty, tabs); | 
| 615 | fun merges eq tabs = Library.foldl (merge eq) (empty, tabs); | |
| 616 | ||
| 5015 | 617 | |
| 19031 | 618 | (* list tables *) | 
| 15761 | 619 | |
| 18946 | 620 | fun lookup_list tab key = these (lookup tab key); | 
| 25391 | 621 | |
| 622 | fun cons_list (key, x) tab = modify key (fn NONE => [x] | SOME xs => x :: xs) tab; | |
| 5015 | 623 | |
| 77981 | 624 | fun modify_list key f = | 
| 625 | modify key (fn arg => | |
| 626 | let | |
| 627 | val xs = the_default [] arg; | |
| 628 | val ys = f xs; | |
| 629 | in if pointer_eq (xs, ys) then raise SAME else ys end); | |
| 630 | ||
| 631 | fun insert_list eq (key, x) = modify_list key (Library.insert eq x); | |
| 632 | fun update_list eq (key, x) = modify_list key (Library.update eq x); | |
| 25391 | 633 | |
| 18946 | 634 | fun remove_list eq (key, x) tab = | 
| 77981 | 635 | map_entry key (fn xs => | 
| 636 | (case Library.remove eq x xs of | |
| 637 | [] => raise UNDEF key | |
| 638 | | ys => if pointer_eq (xs, ys) then raise SAME else ys)) tab | |
| 15761 | 639 | handle UNDEF _ => delete key tab; | 
| 5015 | 640 | |
| 74266 | 641 | fun make_list args = build (fold_rev cons_list args); | 
| 19482 
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
 wenzelm parents: 
19073diff
changeset | 642 | fun dest_list tab = maps (fn (key, xs) => map (pair key) xs) (dest tab); | 
| 77973 | 643 | fun merge_list eq = | 
| 77975 | 644 | join (fn _ => fn xy => if eq_list eq xy then raise SAME else Library.merge eq xy); | 
| 5015 | 645 | |
| 646 | ||
| 74227 | 647 | (* set operations *) | 
| 50234 | 648 | |
| 649 | type set = unit table; | |
| 650 | ||
| 67529 | 651 | fun insert_set x = default (x, ()); | 
| 652 | fun remove_set x : set -> set = delete_safe x; | |
| 74266 | 653 | fun make_set xs = build (fold insert_set xs); | 
| 50234 | 654 | |
| 655 | ||
| 47980 
c81801f881b3
simplified Poly/ML setup -- 5.3.0 is now the common base-line;
 wenzelm parents: 
44336diff
changeset | 656 | (* 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 | 657 | |
| 
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 | 658 | val _ = | 
| 62819 
d3ff367a16a0
careful export of type-dependent functions, without losing their special status;
 wenzelm parents: 
62503diff
changeset | 659 | ML_system_pp (fn depth => fn pretty => fn tab => | 
| 62503 | 660 | 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 | 661 |       (ML_Pretty.enum "," "{" "}"
 | 
| 62503 | 662 | (ML_Pretty.pair | 
| 62819 
d3ff367a16a0
careful export of type-dependent functions, without losing their special status;
 wenzelm parents: 
62503diff
changeset | 663 | (ML_Pretty.from_polyml o ML_system_pretty) | 
| 62503 | 664 | (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 | 665 | (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 | 666 | |
| 
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 | 667 | |
| 5681 | 668 | (*final declarations of this structure!*) | 
| 39020 | 669 | val map = map_table; | 
| 16446 | 670 | val fold = fold_table; | 
| 28334 | 671 | val fold_rev = fold_rev_table; | 
| 5015 | 672 | |
| 673 | end; | |
| 674 | ||
| 31971 
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
 wenzelm parents: 
31621diff
changeset | 675 | structure Inttab = Table(type key = int val ord = int_ord); | 
| 
8c1b845ed105
renamed functor TableFun to Table, and GraphFun to Graph;
 wenzelm parents: 
31621diff
changeset | 676 | 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 | 677 | structure Symreltab = Table(type key = string * string | 
| 30647 
ef8f46c3158a
added Symreltab (binary relations of symbols) instance of TableFun
 haftmann parents: 
30290diff
changeset | 678 | val ord = prod_ord fast_string_ord fast_string_ord); |