src/Pure/General/linear_set.ML
author wenzelm
Thu, 23 Aug 2012 20:34:51 +0200
changeset 48913 f686cb016c0c
parent 47980 c81801f881b3
child 52562 3261ee47bb95
permissions -rw-r--r--
more direct File.read_bytes -- avoid cumulative copying of StringBuilder;
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
44476
e8a87398f35d propagate information about last command with exec state assignment through document model;
wenzelm
parents: 38448
diff changeset
    17
  val lookup: 'a T -> key -> ('a * key option) option
38448
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
44483
383a5b9efbd0 tuned signature -- iterate subsumes both fold and get_first;
wenzelm
parents: 44479
diff changeset
    19
  val iterate: key option ->
44479
9a04e7502e22 refined document state assignment: observe perspective, more explicit assignment message;
wenzelm
parents: 44476
diff changeset
    20
    ((key option * key) * 'a -> 'b -> 'b option) -> 'a T -> 'b -> 'b
47403
296b478df14e added ML pretty-printing;
wenzelm
parents: 44483
diff changeset
    21
  val dest: 'a T -> (key * 'a) list
38448
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    22
  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
    23
  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
    24
  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
    25
end;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    26
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    27
functor Linear_Set(Key: KEY): LINEAR_SET =
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    28
struct
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    29
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    30
(* type key *)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    31
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    32
type key = Key.key;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    33
structure Table = Table(Key);
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    34
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    35
exception DUPLICATE of key;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    36
exception UNDEFINED of key;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    37
exception NEXT_UNDEFINED of key option;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    38
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
(* raw entries *)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    41
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    42
fun the_entry entries key =
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    43
  (case Table.lookup entries key of
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    44
    NONE => raise UNDEFINED key
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    45
  | SOME entry => entry);
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    46
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    47
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
    48
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    49
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
    50
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    51
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
    52
  handle Table.DUP key => raise DUPLICATE key;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    53
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    54
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
    55
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
(* set representation and basic operations *)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    58
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    59
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
    60
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    61
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
    62
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
    63
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    64
fun start_of (Set {start, ...}) = start;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    65
fun entries_of (Set {entries, ...}) = entries;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    66
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    67
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
    68
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
    69
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    70
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
    71
44476
e8a87398f35d propagate information about last command with exec state assignment through document model;
wenzelm
parents: 38448
diff changeset
    72
fun lookup set key = Table.lookup (entries_of set) key;
38448
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    73
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    74
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
    75
  (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
    76
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
(* iterate entries *)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    79
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    80
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
    81
  | optional_start _ some = some;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    82
44483
383a5b9efbd0 tuned signature -- iterate subsumes both fold and get_first;
wenzelm
parents: 44479
diff changeset
    83
fun iterate opt_start f set =
38448
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    84
  let
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    85
    val entries = entries_of set;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    86
    fun apply _ NONE y = y
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    87
      | apply prev (SOME key) y =
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    88
          let
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    89
            val (x, next) = the_entry entries key;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    90
            val item = ((prev, key), x);
44479
9a04e7502e22 refined document state assignment: observe perspective, more explicit assignment message;
wenzelm
parents: 44476
diff changeset
    91
          in
9a04e7502e22 refined document state assignment: observe perspective, more explicit assignment message;
wenzelm
parents: 44476
diff changeset
    92
            (case f item y of
9a04e7502e22 refined document state assignment: observe perspective, more explicit assignment message;
wenzelm
parents: 44476
diff changeset
    93
              NONE => y
9a04e7502e22 refined document state assignment: observe perspective, more explicit assignment message;
wenzelm
parents: 44476
diff changeset
    94
            | SOME y' => apply (SOME key) next y')
9a04e7502e22 refined document state assignment: observe perspective, more explicit assignment message;
wenzelm
parents: 44476
diff changeset
    95
          end;
38448
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
    96
  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
    97
47403
296b478df14e added ML pretty-printing;
wenzelm
parents: 44483
diff changeset
    98
fun dest set = rev (iterate NONE (fn ((_, key), x) => SOME o cons (key, x)) set []);
296b478df14e added ML pretty-printing;
wenzelm
parents: 44483
diff changeset
    99
38448
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   100
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   101
(* relative addressing *)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   102
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   103
fun get_after set hook =
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   104
  (case hook of
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   105
    NONE => start_of set
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   106
  | 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
   107
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   108
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
   109
  (case hook of
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   110
    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
   111
  | SOME key1 =>
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   112
      let
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   113
        val (x1, next) = the_entry entries key1;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   114
        val entries' = entries
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   115
          |> put_entry (key1, (x1, SOME key))
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   116
          |> new_entry (key, (x, next));
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   117
      in (start, entries') end));
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   118
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   119
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
   120
  (case hook of
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   121
    NONE =>
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   122
      (case start of
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   123
        NONE => raise NEXT_UNDEFINED NONE
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   124
      | 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
   125
  | SOME key1 =>
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   126
      (case the_entry entries key1 of
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   127
        (_, NONE) => raise NEXT_UNDEFINED (SOME key1)
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   128
      | (x1, SOME key2) =>
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   129
          let
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   130
            val entries' = entries
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   131
              |> 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
   132
              |> del_entry key2;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   133
          in (start, entries') end)));
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   134
47403
296b478df14e added ML pretty-printing;
wenzelm
parents: 44483
diff changeset
   135
47980
c81801f881b3 simplified Poly/ML setup -- 5.3.0 is now the common base-line;
wenzelm
parents: 47403
diff changeset
   136
(* ML pretty-printing *)
47403
296b478df14e added ML pretty-printing;
wenzelm
parents: 44483
diff changeset
   137
296b478df14e added ML pretty-printing;
wenzelm
parents: 44483
diff changeset
   138
val _ =
296b478df14e added ML pretty-printing;
wenzelm
parents: 44483
diff changeset
   139
  PolyML.addPrettyPrinter (fn depth => fn pretty => fn set =>
296b478df14e added ML pretty-printing;
wenzelm
parents: 44483
diff changeset
   140
    ml_pretty
296b478df14e added ML pretty-printing;
wenzelm
parents: 44483
diff changeset
   141
      (ML_Pretty.enum "," "{" "}"
296b478df14e added ML pretty-printing;
wenzelm
parents: 44483
diff changeset
   142
        (ML_Pretty.pair (pretty_ml o PolyML.prettyRepresentation) (pretty_ml o pretty))
296b478df14e added ML pretty-printing;
wenzelm
parents: 44483
diff changeset
   143
        (dest set, depth)));
296b478df14e added ML pretty-printing;
wenzelm
parents: 44483
diff changeset
   144
38448
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   145
end;
62d16c415019 added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff changeset
   146