src/Pure/table.ML
changeset 4485 697972696f71
parent 4482 43620c417579
equal deleted inserted replaced
4484:220ccae8a590 4485:697972696f71
     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
   177 end;
   177 end;
   178 
   178 
   179 
   179 
   180 (*tables indexed by strings*)
   180 (*tables indexed by strings*)
   181 structure Symtab = TableFun(type key = string val ord = string_ord);
   181 structure Symtab = TableFun(type key = string val ord = string_ord);
   182 
       
   183 (* FIXME demo *)
       
   184 structure IntTab = TableFun(type key = int val ord = int_ord);
       
   185 val make = IntTab.make o map (rpair ());
       
   186 fun dest tab = IntTab.dest tab |> map fst;