author | wenzelm |
Mon, 17 Oct 2022 12:15:23 +0200 | |
changeset 76322 | 43e66527fa93 |
parent 62819 | d3ff367a16a0 |
child 80809 | 4a64fc4d1cde |
permissions | -rw-r--r-- |
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 | 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; |
52562 | 86 |
fun iter _ NONE y = y |
87 |
| iter prev (SOME key) y = |
|
38448
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 |
52562 | 94 |
| SOME y' => iter (SOME key) next y') |
44479
9a04e7502e22
refined document state assignment: observe perspective, more explicit assignment message;
wenzelm
parents:
44476
diff
changeset
|
95 |
end; |
52562 | 96 |
in iter NONE (optional_start set opt_start) end; |
38448
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
97 |
|
47403 | 98 |
fun dest set = rev (iterate NONE (fn ((_, key), x) => SOME o cons (key, x)) set []); |
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 | 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 | 137 |
|
138 |
val _ = |
|
62819
d3ff367a16a0
careful export of type-dependent functions, without losing their special status;
wenzelm
parents:
62503
diff
changeset
|
139 |
ML_system_pp (fn depth => fn pretty => fn set => |
62503 | 140 |
ML_Pretty.to_polyml |
47403 | 141 |
(ML_Pretty.enum "," "{" "}" |
62503 | 142 |
(ML_Pretty.pair |
62819
d3ff367a16a0
careful export of type-dependent functions, without losing their special status;
wenzelm
parents:
62503
diff
changeset
|
143 |
(ML_Pretty.from_polyml o ML_system_pretty) |
62503 | 144 |
(ML_Pretty.from_polyml o pretty)) |
47403 | 145 |
(dest set, depth))); |
146 |
||
38448
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
147 |
end; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
148 |