src/Pure/General/linear_set.ML
author haftmann
Mon, 30 Aug 2010 09:35:30 +0200
changeset 38865 43c934dd4bc3
parent 38448 62d16c415019
child 44476 e8a87398f35d
permissions -rw-r--r--
merged
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
38448
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
     1
(*  Title:      Pure/General/linear_set.ML
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
     3
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
     4
Sets with canonical linear order, or immutable linked-lists.
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
     5
*)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
     6
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
     7
signature LINEAR_SET =
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
     8
sig
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
     9
  type key
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    10
  type 'a T
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    11
  exception DUPLICATE of key
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    12
  exception UNDEFINED of key
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    13
  exception NEXT_UNDEFINED of key option
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    14
  val empty: 'a T
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    15
  val is_empty: 'a T -> bool
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    16
  val defined: 'a T -> key -> bool
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    17
  val lookup: 'a T -> key -> 'a option
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    18
  val update: key * 'a -> 'a T -> 'a T
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    19
  val fold: key option ->
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    20
    ((key option * key) * 'a -> 'b -> 'b) -> 'a T -> 'b -> 'b
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    21
  val get_first: key option ->
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    22
    ((key option * key) * 'a -> bool) -> 'a T -> ((key option * key) * 'a) option
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    23
  val get_after: 'a T -> key option -> key option
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    24
  val insert_after: key option -> key * 'a -> 'a T -> 'a T
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    25
  val delete_after: key option -> 'a T -> 'a T
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    26
end;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    27
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    28
functor Linear_Set(Key: KEY): LINEAR_SET =
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    29
struct
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    30
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    31
(* type key *)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    32
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    33
type key = Key.key;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    34
structure Table = Table(Key);
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    35
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    36
exception DUPLICATE of key;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    37
exception UNDEFINED of key;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    38
exception NEXT_UNDEFINED of key option;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    39
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    40
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    41
(* raw entries *)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    42
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    43
fun the_entry entries key =
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    44
  (case Table.lookup entries key of
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    45
    NONE => raise UNDEFINED key
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    46
  | SOME entry => entry);
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    47
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    48
fun next_entry entries key = snd (the_entry entries key);
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    49
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    50
fun put_entry entry entries = Table.update entry entries;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    51
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    52
fun new_entry entry entries = Table.update_new entry entries
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    53
  handle Table.DUP key => raise DUPLICATE key;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    54
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    55
fun del_entry key entries = Table.delete_safe key entries;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    56
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    57
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    58
(* set representation and basic operations *)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    59
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    60
datatype 'a T = Set of {start: key option, entries: ('a * key option) Table.table};
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    61
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    62
fun make_set (start, entries) = Set {start = start, entries = entries};
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    63
fun map_set f (Set {start, entries}) = make_set (f (start, entries));
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    64
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    65
fun start_of (Set {start, ...}) = start;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    66
fun entries_of (Set {entries, ...}) = entries;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    67
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    68
val empty = Set {start = NONE, entries = Table.empty};
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    69
fun is_empty set = is_none (start_of set);
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    70
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    71
fun defined set key = Table.defined (entries_of set) key;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    72
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    73
fun lookup set key = Option.map fst (Table.lookup (entries_of set) key);
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    74
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    75
fun update (key, x) = map_set (fn (start, entries) =>
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    76
  (start, put_entry (key, (x, next_entry entries key)) entries));
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    77
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    78
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    79
(* iterate entries *)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    80
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    81
fun optional_start set NONE = start_of set
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    82
  | optional_start _ some = some;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    83
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    84
fun fold opt_start f set =
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    85
  let
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    86
    val entries = entries_of set;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    87
    fun apply _ NONE y = y
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    88
      | apply prev (SOME key) y =
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    89
          let
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    90
            val (x, next) = the_entry entries key;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    91
            val item = ((prev, key), x);
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    92
          in apply (SOME key) next (f item y) end;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    93
  in apply NONE (optional_start set opt_start) end;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    94
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    95
fun get_first opt_start P set =
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    96
  let
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    97
    val entries = entries_of set;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    98
    fun first _ NONE = NONE
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    99
      | first prev (SOME key) =
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   100
          let
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   101
            val (x, next) = the_entry entries key;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   102
            val item = ((prev, key), x);
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   103
          in if P item then SOME item else first (SOME key) next end;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   104
  in first NONE (optional_start set opt_start) end;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   105
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   106
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   107
(* relative addressing *)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   108
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   109
fun get_after set hook =
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   110
  (case hook of
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   111
    NONE => start_of set
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   112
  | SOME key => next_entry (entries_of set) key);
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   113
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   114
fun insert_after hook (key, x) = map_set (fn (start, entries) =>
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   115
  (case hook of
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   116
    NONE => (SOME key, new_entry (key, (x, start)) entries)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   117
  | SOME key1 =>
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   118
      let
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   119
        val (x1, next) = the_entry entries key1;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   120
        val entries' = entries
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   121
          |> put_entry (key1, (x1, SOME key))
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   122
          |> new_entry (key, (x, next));
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   123
      in (start, entries') end));
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   124
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   125
fun delete_after hook set = set |> map_set (fn (start, entries) =>
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   126
  (case hook of
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   127
    NONE =>
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   128
      (case start of
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   129
        NONE => raise NEXT_UNDEFINED NONE
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   130
      | SOME key1 => (next_entry entries key1, del_entry key1 entries))
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   131
  | SOME key1 =>
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   132
      (case the_entry entries key1 of
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   133
        (_, NONE) => raise NEXT_UNDEFINED (SOME key1)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   134
      | (x1, SOME key2) =>
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   135
          let
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   136
            val entries' = entries
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   137
              |> put_entry (key1, (x1, next_entry entries key2))
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   138
              |> del_entry key2;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   139
          in (start, entries') end)));
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   140
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   141
end;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   142