author | haftmann |
Mon, 30 Aug 2010 09:35:30 +0200 | |
changeset 38865 | 43c934dd4bc3 |
parent 38448 | 62d16c415019 |
child 44476 | e8a87398f35d |
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 |
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 |