author | blanchet |
Tue, 20 Mar 2012 10:06:35 +0100 | |
changeset 47039 | 1b36a05a070d |
parent 44483 | 383a5b9efbd0 |
child 47403 | 296b478df14e |
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 |
38448
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
21 |
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
|
22 |
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
|
23 |
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
|
24 |
end; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
25 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
26 |
functor Linear_Set(Key: KEY): LINEAR_SET = |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
27 |
struct |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
28 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
29 |
(* type key *) |
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 = Key.key; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
32 |
structure Table = Table(Key); |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
33 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
34 |
exception DUPLICATE of key; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
35 |
exception UNDEFINED of key; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
36 |
exception NEXT_UNDEFINED of key option; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
37 |
|
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 |
(* raw entries *) |
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 |
fun the_entry entries key = |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
42 |
(case Table.lookup entries key of |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
43 |
NONE => raise UNDEFINED key |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
44 |
| SOME entry => entry); |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
45 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
46 |
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
|
47 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
48 |
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
|
49 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
50 |
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
|
51 |
handle Table.DUP key => raise DUPLICATE key; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
52 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
53 |
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
|
54 |
|
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 |
(* set representation and basic operations *) |
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 |
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
|
59 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
60 |
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
|
61 |
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
|
62 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
63 |
fun start_of (Set {start, ...}) = start; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
64 |
fun entries_of (Set {entries, ...}) = entries; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
65 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
66 |
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
|
67 |
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
|
68 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
69 |
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
|
70 |
|
44476
e8a87398f35d
propagate information about last command with exec state assignment through document model;
wenzelm
parents:
38448
diff
changeset
|
71 |
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
|
72 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
73 |
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
|
74 |
(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
|
75 |
|
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 |
(* iterate entries *) |
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 |
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
|
80 |
| optional_start _ some = some; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
81 |
|
44483
383a5b9efbd0
tuned signature -- iterate subsumes both fold and get_first;
wenzelm
parents:
44479
diff
changeset
|
82 |
fun iterate opt_start f set = |
38448
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
83 |
let |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
84 |
val entries = entries_of set; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
85 |
fun apply _ NONE y = y |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
86 |
| apply prev (SOME key) y = |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
87 |
let |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
88 |
val (x, next) = the_entry entries key; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
89 |
val item = ((prev, key), x); |
44479
9a04e7502e22
refined document state assignment: observe perspective, more explicit assignment message;
wenzelm
parents:
44476
diff
changeset
|
90 |
in |
9a04e7502e22
refined document state assignment: observe perspective, more explicit assignment message;
wenzelm
parents:
44476
diff
changeset
|
91 |
(case f item y of |
9a04e7502e22
refined document state assignment: observe perspective, more explicit assignment message;
wenzelm
parents:
44476
diff
changeset
|
92 |
NONE => y |
9a04e7502e22
refined document state assignment: observe perspective, more explicit assignment message;
wenzelm
parents:
44476
diff
changeset
|
93 |
| SOME y' => apply (SOME key) next y') |
9a04e7502e22
refined document state assignment: observe perspective, more explicit assignment message;
wenzelm
parents:
44476
diff
changeset
|
94 |
end; |
38448
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
95 |
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
|
96 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
97 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
98 |
(* relative addressing *) |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
99 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
100 |
fun get_after set hook = |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
101 |
(case hook of |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
102 |
NONE => start_of set |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
103 |
| 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
|
104 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
105 |
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
|
106 |
(case hook of |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
107 |
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
|
108 |
| SOME key1 => |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
109 |
let |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
110 |
val (x1, next) = the_entry entries key1; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
111 |
val entries' = entries |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
112 |
|> put_entry (key1, (x1, SOME key)) |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
113 |
|> new_entry (key, (x, next)); |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
114 |
in (start, entries') end)); |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
115 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
116 |
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
|
117 |
(case hook of |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
118 |
NONE => |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
119 |
(case start of |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
120 |
NONE => raise NEXT_UNDEFINED NONE |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
121 |
| 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
|
122 |
| SOME key1 => |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
123 |
(case the_entry entries key1 of |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
124 |
(_, NONE) => raise NEXT_UNDEFINED (SOME key1) |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
125 |
| (x1, SOME key2) => |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
126 |
let |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
127 |
val entries' = entries |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
128 |
|> 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
|
129 |
|> del_entry key2; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
130 |
in (start, entries') end))); |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
131 |
|
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
132 |
end; |
62d16c415019
added functor Linear_Set, based on former adhoc structures in document.ML;
wenzelm
parents:
diff
changeset
|
133 |