wenzelm@6185
|
1 |
(* Title: Pure/context.ML
|
wenzelm@6185
|
2 |
Author: Markus Wenzel, TU Muenchen
|
wenzelm@6185
|
3 |
|
wenzelm@16436
|
4 |
Generic theory contexts with unique identity, arbitrarily typed data,
|
wenzelm@24141
|
5 |
monotonic development graph and history support. Generic proof
|
wenzelm@24141
|
6 |
contexts with arbitrarily typed data.
|
wenzelm@33031
|
7 |
|
wenzelm@33031
|
8 |
Firm naming conventions:
|
wenzelm@33031
|
9 |
thy, thy', thy1, thy2: theory
|
wenzelm@33031
|
10 |
ctxt, ctxt', ctxt1, ctxt2: Proof.context
|
wenzelm@33031
|
11 |
context: Context.generic
|
wenzelm@6185
|
12 |
*)
|
wenzelm@6185
|
13 |
|
wenzelm@6185
|
14 |
signature BASIC_CONTEXT =
|
wenzelm@6185
|
15 |
sig
|
wenzelm@16436
|
16 |
type theory
|
wenzelm@16436
|
17 |
type theory_ref
|
wenzelm@16436
|
18 |
exception THEORY of string * theory list
|
wenzelm@33031
|
19 |
structure Proof: sig type context end
|
wenzelm@42360
|
20 |
structure Proof_Context:
|
wenzelm@33031
|
21 |
sig
|
wenzelm@33031
|
22 |
val theory_of: Proof.context -> theory
|
wenzelm@36610
|
23 |
val init_global: theory -> Proof.context
|
wenzelm@51686
|
24 |
val get_global: theory -> string -> Proof.context
|
wenzelm@33031
|
25 |
end
|
wenzelm@6185
|
26 |
end;
|
wenzelm@6185
|
27 |
|
wenzelm@6185
|
28 |
signature CONTEXT =
|
wenzelm@6185
|
29 |
sig
|
wenzelm@6185
|
30 |
include BASIC_CONTEXT
|
wenzelm@16436
|
31 |
(*theory context*)
|
wenzelm@42818
|
32 |
val timing: bool Unsynchronized.ref
|
wenzelm@42383
|
33 |
type pretty
|
wenzelm@16436
|
34 |
val parents_of: theory -> theory list
|
wenzelm@16436
|
35 |
val ancestors_of: theory -> theory list
|
wenzelm@29069
|
36 |
val theory_name: theory -> string
|
wenzelm@16436
|
37 |
val is_stale: theory -> bool
|
wenzelm@26623
|
38 |
val is_draft: theory -> bool
|
wenzelm@28317
|
39 |
val reject_draft: theory -> theory
|
wenzelm@29093
|
40 |
val PureN: string
|
wenzelm@29093
|
41 |
val display_names: theory -> string list
|
wenzelm@16436
|
42 |
val pretty_thy: theory -> Pretty.T
|
wenzelm@16436
|
43 |
val string_of_thy: theory -> string
|
wenzelm@16436
|
44 |
val pretty_abbrev_thy: theory -> Pretty.T
|
wenzelm@16436
|
45 |
val str_of_thy: theory -> string
|
wenzelm@37867
|
46 |
val get_theory: theory -> string -> theory
|
wenzelm@37871
|
47 |
val this_theory: theory -> string -> theory
|
wenzelm@24141
|
48 |
val deref: theory_ref -> theory
|
wenzelm@24141
|
49 |
val check_thy: theory -> theory_ref
|
wenzelm@16436
|
50 |
val eq_thy: theory * theory -> bool
|
wenzelm@16436
|
51 |
val subthy: theory * theory -> bool
|
wenzelm@16594
|
52 |
val joinable: theory * theory -> bool
|
wenzelm@23355
|
53 |
val merge: theory * theory -> theory
|
wenzelm@23355
|
54 |
val merge_refs: theory_ref * theory_ref -> theory_ref
|
wenzelm@16436
|
55 |
val copy_thy: theory -> theory
|
wenzelm@16436
|
56 |
val checkpoint_thy: theory -> theory
|
wenzelm@16489
|
57 |
val finish_thy: theory -> theory
|
wenzelm@42383
|
58 |
val begin_thy: (theory -> pretty) -> string -> theory list -> theory
|
wenzelm@16533
|
59 |
(*proof context*)
|
wenzelm@33031
|
60 |
val raw_transfer: theory -> Proof.context -> Proof.context
|
wenzelm@16533
|
61 |
(*generic context*)
|
wenzelm@33031
|
62 |
datatype generic = Theory of theory | Proof of Proof.context
|
wenzelm@33031
|
63 |
val cases: (theory -> 'a) -> (Proof.context -> 'a) -> generic -> 'a
|
wenzelm@33031
|
64 |
val mapping: (theory -> theory) -> (Proof.context -> Proof.context) -> generic -> generic
|
wenzelm@33031
|
65 |
val mapping_result: (theory -> 'a * theory) -> (Proof.context -> 'a * Proof.context) ->
|
wenzelm@33031
|
66 |
generic -> 'a * generic
|
wenzelm@18632
|
67 |
val the_theory: generic -> theory
|
wenzelm@33031
|
68 |
val the_proof: generic -> Proof.context
|
wenzelm@18731
|
69 |
val map_theory: (theory -> theory) -> generic -> generic
|
wenzelm@33031
|
70 |
val map_proof: (Proof.context -> Proof.context) -> generic -> generic
|
wenzelm@26486
|
71 |
val map_theory_result: (theory -> 'a * theory) -> generic -> 'a * generic
|
wenzelm@33031
|
72 |
val map_proof_result: (Proof.context -> 'a * Proof.context) -> generic -> 'a * generic
|
wenzelm@18731
|
73 |
val theory_map: (generic -> generic) -> theory -> theory
|
wenzelm@33031
|
74 |
val proof_map: (generic -> generic) -> Proof.context -> Proof.context
|
wenzelm@33031
|
75 |
val theory_of: generic -> theory (*total*)
|
wenzelm@33031
|
76 |
val proof_of: generic -> Proof.context (*total*)
|
wenzelm@42383
|
77 |
(*pretty printing context*)
|
wenzelm@42383
|
78 |
val pretty: Proof.context -> pretty
|
wenzelm@42383
|
79 |
val pretty_global: theory -> pretty
|
wenzelm@47005
|
80 |
val pretty_generic: generic -> pretty
|
wenzelm@42383
|
81 |
val pretty_context: (theory -> Proof.context) -> pretty -> Proof.context
|
wenzelm@26413
|
82 |
(*thread data*)
|
wenzelm@26413
|
83 |
val thread_data: unit -> generic option
|
wenzelm@26413
|
84 |
val the_thread_data: unit -> generic
|
wenzelm@26413
|
85 |
val set_thread_data: generic option -> unit
|
wenzelm@26413
|
86 |
val setmp_thread_data: generic option -> ('a -> 'b) -> 'a -> 'b
|
wenzelm@26463
|
87 |
val >> : (generic -> generic) -> unit
|
wenzelm@26463
|
88 |
val >>> : (generic -> 'a * generic) -> 'a
|
wenzelm@6185
|
89 |
end;
|
wenzelm@6185
|
90 |
|
wenzelm@16436
|
91 |
signature PRIVATE_CONTEXT =
|
wenzelm@16436
|
92 |
sig
|
wenzelm@16436
|
93 |
include CONTEXT
|
wenzelm@33033
|
94 |
structure Theory_Data:
|
wenzelm@16436
|
95 |
sig
|
wenzelm@51368
|
96 |
val declare: Position.T -> Any.T -> (Any.T -> Any.T) ->
|
wenzelm@51368
|
97 |
(pretty -> Any.T * Any.T -> Any.T) -> serial
|
wenzelm@51368
|
98 |
val get: serial -> (Any.T -> 'a) -> theory -> 'a
|
wenzelm@51368
|
99 |
val put: serial -> ('a -> Any.T) -> 'a -> theory -> theory
|
wenzelm@16489
|
100 |
end
|
wenzelm@33033
|
101 |
structure Proof_Data:
|
wenzelm@16533
|
102 |
sig
|
wenzelm@51368
|
103 |
val declare: (theory -> Any.T) -> serial
|
wenzelm@51368
|
104 |
val get: serial -> (Any.T -> 'a) -> Proof.context -> 'a
|
wenzelm@51368
|
105 |
val put: serial -> ('a -> Any.T) -> 'a -> Proof.context -> Proof.context
|
wenzelm@16533
|
106 |
end
|
wenzelm@16436
|
107 |
end;
|
wenzelm@16436
|
108 |
|
wenzelm@16436
|
109 |
structure Context: PRIVATE_CONTEXT =
|
wenzelm@6185
|
110 |
struct
|
wenzelm@6185
|
111 |
|
wenzelm@16436
|
112 |
(*** theory context ***)
|
wenzelm@6185
|
113 |
|
wenzelm@16489
|
114 |
(** theory data **)
|
wenzelm@16489
|
115 |
|
wenzelm@16489
|
116 |
(* data kinds and access methods *)
|
wenzelm@16489
|
117 |
|
wenzelm@42818
|
118 |
val timing = Unsynchronized.ref false;
|
wenzelm@42818
|
119 |
|
wenzelm@19028
|
120 |
(*private copy avoids potential conflict of table exceptions*)
|
wenzelm@31971
|
121 |
structure Datatab = Table(type key = int val ord = int_ord);
|
wenzelm@19028
|
122 |
|
wenzelm@51368
|
123 |
datatype pretty = Pretty of Any.T;
|
wenzelm@42383
|
124 |
|
wenzelm@16489
|
125 |
local
|
wenzelm@16489
|
126 |
|
wenzelm@16489
|
127 |
type kind =
|
wenzelm@42818
|
128 |
{pos: Position.T,
|
wenzelm@51368
|
129 |
empty: Any.T,
|
wenzelm@51368
|
130 |
extend: Any.T -> Any.T,
|
wenzelm@51368
|
131 |
merge: pretty -> Any.T * Any.T -> Any.T};
|
wenzelm@16489
|
132 |
|
wenzelm@43684
|
133 |
val kinds = Synchronized.var "Theory_Data" (Datatab.empty: kind Datatab.table);
|
wenzelm@16489
|
134 |
|
wenzelm@42818
|
135 |
fun invoke name f k x =
|
wenzelm@43684
|
136 |
(case Datatab.lookup (Synchronized.value kinds) k of
|
wenzelm@42818
|
137 |
SOME kind =>
|
wenzelm@42818
|
138 |
if ! timing andalso name <> "" then
|
wenzelm@48992
|
139 |
Timing.cond_timeit true ("Theory_Data." ^ name ^ Position.here (#pos kind))
|
wenzelm@42818
|
140 |
(fn () => f kind x)
|
wenzelm@42818
|
141 |
else f kind x
|
wenzelm@37852
|
142 |
| NONE => raise Fail "Invalid theory data identifier");
|
wenzelm@16489
|
143 |
|
wenzelm@16489
|
144 |
in
|
wenzelm@16489
|
145 |
|
wenzelm@42818
|
146 |
fun invoke_empty k = invoke "" (K o #empty) k ();
|
wenzelm@42818
|
147 |
val invoke_extend = invoke "extend" #extend;
|
wenzelm@42818
|
148 |
fun invoke_merge pp = invoke "merge" (fn kind => #merge kind pp);
|
wenzelm@16489
|
149 |
|
wenzelm@42818
|
150 |
fun declare_theory_data pos empty extend merge =
|
wenzelm@16489
|
151 |
let
|
wenzelm@16489
|
152 |
val k = serial ();
|
wenzelm@42818
|
153 |
val kind = {pos = pos, empty = empty, extend = extend, merge = merge};
|
wenzelm@43684
|
154 |
val _ = Synchronized.change kinds (Datatab.update (k, kind));
|
wenzelm@16489
|
155 |
in k end;
|
wenzelm@16489
|
156 |
|
haftmann@39020
|
157 |
val extend_data = Datatab.map invoke_extend;
|
wenzelm@43610
|
158 |
fun merge_data pp = Datatab.join (invoke_merge pp) o pairself extend_data;
|
wenzelm@16489
|
159 |
|
wenzelm@16489
|
160 |
end;
|
wenzelm@16489
|
161 |
|
wenzelm@16489
|
162 |
|
wenzelm@16489
|
163 |
|
wenzelm@16489
|
164 |
(** datatype theory **)
|
wenzelm@16489
|
165 |
|
wenzelm@16436
|
166 |
datatype theory =
|
wenzelm@16436
|
167 |
Theory of
|
wenzelm@16533
|
168 |
(*identity*)
|
wenzelm@32738
|
169 |
{self: theory Unsynchronized.ref option, (*dynamic self reference -- follows theory changes*)
|
wenzelm@29095
|
170 |
draft: bool, (*draft mode -- linear destructive changes*)
|
wenzelm@29093
|
171 |
id: serial, (*identifier*)
|
wenzelm@29093
|
172 |
ids: unit Inttab.table} * (*cumulative identifiers of non-drafts -- symbolic body content*)
|
wenzelm@29095
|
173 |
(*data*)
|
wenzelm@51368
|
174 |
Any.T Datatab.table * (*body content*)
|
wenzelm@29095
|
175 |
(*ancestry*)
|
wenzelm@29093
|
176 |
{parents: theory list, (*immediate predecessors*)
|
wenzelm@29093
|
177 |
ancestors: theory list} * (*all predecessors -- canonical reverse order*)
|
wenzelm@29095
|
178 |
(*history*)
|
wenzelm@29093
|
179 |
{name: string, (*official theory name*)
|
wenzelm@29093
|
180 |
stage: int}; (*checkpoint counter*)
|
wenzelm@16436
|
181 |
|
wenzelm@16436
|
182 |
exception THEORY of string * theory list;
|
wenzelm@16436
|
183 |
|
wenzelm@16436
|
184 |
fun rep_theory (Theory args) = args;
|
wenzelm@16436
|
185 |
|
wenzelm@16436
|
186 |
val identity_of = #1 o rep_theory;
|
wenzelm@33033
|
187 |
val data_of = #2 o rep_theory;
|
wenzelm@16489
|
188 |
val ancestry_of = #3 o rep_theory;
|
wenzelm@33033
|
189 |
val history_of = #4 o rep_theory;
|
wenzelm@16436
|
190 |
|
wenzelm@29093
|
191 |
fun make_identity self draft id ids = {self = self, draft = draft, id = id, ids = ids};
|
wenzelm@16489
|
192 |
fun make_ancestry parents ancestors = {parents = parents, ancestors = ancestors};
|
wenzelm@29093
|
193 |
fun make_history name stage = {name = name, stage = stage};
|
wenzelm@16436
|
194 |
|
wenzelm@16533
|
195 |
val the_self = the o #self o identity_of;
|
wenzelm@16436
|
196 |
val parents_of = #parents o ancestry_of;
|
wenzelm@16436
|
197 |
val ancestors_of = #ancestors o ancestry_of;
|
wenzelm@16489
|
198 |
val theory_name = #name o history_of;
|
wenzelm@16436
|
199 |
|
wenzelm@16436
|
200 |
|
wenzelm@16436
|
201 |
(* staleness *)
|
wenzelm@16436
|
202 |
|
wenzelm@29093
|
203 |
fun eq_id (i: int, j) = i = j;
|
wenzelm@16436
|
204 |
|
wenzelm@16436
|
205 |
fun is_stale
|
wenzelm@32738
|
206 |
(Theory ({self =
|
wenzelm@32738
|
207 |
SOME (Unsynchronized.ref (Theory ({id = id', ...}, _, _, _))), id, ...}, _, _, _)) =
|
wenzelm@16436
|
208 |
not (eq_id (id, id'))
|
wenzelm@16436
|
209 |
| is_stale (Theory ({self = NONE, ...}, _, _, _)) = true;
|
wenzelm@16436
|
210 |
|
wenzelm@16436
|
211 |
fun vitalize (thy as Theory ({self = SOME r, ...}, _, _, _)) = (r := thy; thy)
|
wenzelm@29093
|
212 |
| vitalize (thy as Theory ({self = NONE, draft, id, ids}, data, ancestry, history)) =
|
wenzelm@16436
|
213 |
let
|
wenzelm@32738
|
214 |
val r = Unsynchronized.ref thy;
|
wenzelm@29093
|
215 |
val thy' = Theory (make_identity (SOME r) draft id ids, data, ancestry, history);
|
wenzelm@16436
|
216 |
in r := thy'; thy' end;
|
wenzelm@16436
|
217 |
|
wenzelm@16436
|
218 |
|
wenzelm@29093
|
219 |
(* draft mode *)
|
wenzelm@16436
|
220 |
|
wenzelm@29093
|
221 |
val is_draft = #draft o identity_of;
|
wenzelm@16436
|
222 |
|
wenzelm@28317
|
223 |
fun reject_draft thy =
|
wenzelm@33031
|
224 |
if is_draft thy then
|
wenzelm@33031
|
225 |
raise THEORY ("Illegal draft theory -- stable checkpoint required", [thy])
|
wenzelm@28317
|
226 |
else thy;
|
wenzelm@28317
|
227 |
|
wenzelm@29093
|
228 |
|
wenzelm@29093
|
229 |
(* names *)
|
wenzelm@29093
|
230 |
|
wenzelm@29093
|
231 |
val PureN = "Pure";
|
wenzelm@29093
|
232 |
val draftN = "#";
|
wenzelm@29095
|
233 |
val finished = ~1;
|
wenzelm@16436
|
234 |
|
wenzelm@29093
|
235 |
fun display_names thy =
|
wenzelm@29093
|
236 |
let
|
wenzelm@29093
|
237 |
val draft = if is_draft thy then [draftN] else [];
|
wenzelm@29095
|
238 |
val {stage, ...} = history_of thy;
|
wenzelm@29093
|
239 |
val name =
|
wenzelm@29095
|
240 |
if stage = finished then theory_name thy
|
wenzelm@29095
|
241 |
else theory_name thy ^ ":" ^ string_of_int stage;
|
wenzelm@29093
|
242 |
val ancestor_names = map theory_name (ancestors_of thy);
|
wenzelm@29093
|
243 |
val stale = if is_stale thy then ["!"] else [];
|
wenzelm@29093
|
244 |
in rev (stale @ draft @ [name] @ ancestor_names) end;
|
wenzelm@29069
|
245 |
|
wenzelm@29093
|
246 |
val pretty_thy = Pretty.str_list "{" "}" o display_names;
|
wenzelm@16436
|
247 |
val string_of_thy = Pretty.string_of o pretty_thy;
|
wenzelm@16436
|
248 |
|
wenzelm@16436
|
249 |
fun pretty_abbrev_thy thy =
|
wenzelm@16436
|
250 |
let
|
wenzelm@29093
|
251 |
val names = display_names thy;
|
wenzelm@16436
|
252 |
val n = length names;
|
wenzelm@16436
|
253 |
val abbrev = if n > 5 then "..." :: List.drop (names, n - 5) else names;
|
wenzelm@16436
|
254 |
in Pretty.str_list "{" "}" abbrev end;
|
wenzelm@16436
|
255 |
|
wenzelm@16436
|
256 |
val str_of_thy = Pretty.str_of o pretty_abbrev_thy;
|
wenzelm@16436
|
257 |
|
wenzelm@37867
|
258 |
fun get_theory thy name =
|
wenzelm@37867
|
259 |
if theory_name thy <> name then
|
wenzelm@37867
|
260 |
(case find_first (fn thy' => theory_name thy' = name) (ancestors_of thy) of
|
wenzelm@37867
|
261 |
SOME thy' => thy'
|
wenzelm@37867
|
262 |
| NONE => error ("Unknown ancestor theory " ^ quote name))
|
wenzelm@37867
|
263 |
else if #stage (history_of thy) = finished then thy
|
wenzelm@37867
|
264 |
else error ("Unfinished theory " ^ quote name);
|
wenzelm@37867
|
265 |
|
wenzelm@37871
|
266 |
fun this_theory thy name =
|
wenzelm@37871
|
267 |
if theory_name thy = name then thy
|
wenzelm@37871
|
268 |
else get_theory thy name;
|
wenzelm@37871
|
269 |
|
wenzelm@16436
|
270 |
|
wenzelm@24141
|
271 |
(* theory references *)
|
wenzelm@24141
|
272 |
|
wenzelm@24141
|
273 |
(*theory_ref provides a safe way to store dynamic references to a
|
wenzelm@24141
|
274 |
theory in external data structures -- a plain theory value would
|
wenzelm@24141
|
275 |
become stale as the self reference moves on*)
|
wenzelm@24141
|
276 |
|
wenzelm@33033
|
277 |
datatype theory_ref = Theory_Ref of theory Unsynchronized.ref;
|
wenzelm@16436
|
278 |
|
wenzelm@33033
|
279 |
fun deref (Theory_Ref (Unsynchronized.ref thy)) = thy;
|
wenzelm@24141
|
280 |
|
wenzelm@24141
|
281 |
fun check_thy thy = (*thread-safe version*)
|
wenzelm@33033
|
282 |
let val thy_ref = Theory_Ref (the_self thy) in
|
wenzelm@24141
|
283 |
if is_stale thy then error ("Stale theory encountered:\n" ^ string_of_thy thy)
|
wenzelm@24141
|
284 |
else thy_ref
|
wenzelm@24141
|
285 |
end;
|
wenzelm@24141
|
286 |
|
wenzelm@24141
|
287 |
|
wenzelm@29093
|
288 |
(* build ids *)
|
wenzelm@29093
|
289 |
|
wenzelm@29093
|
290 |
fun insert_id draft id ids =
|
wenzelm@29093
|
291 |
if draft then ids
|
wenzelm@29093
|
292 |
else Inttab.update (id, ()) ids;
|
wenzelm@16436
|
293 |
|
wenzelm@29093
|
294 |
fun merge_ids
|
wenzelm@29093
|
295 |
(Theory ({draft = draft1, id = id1, ids = ids1, ...}, _, _, _))
|
wenzelm@29093
|
296 |
(Theory ({draft = draft2, id = id2, ids = ids2, ...}, _, _, _)) =
|
wenzelm@29093
|
297 |
Inttab.merge (K true) (ids1, ids2)
|
wenzelm@29093
|
298 |
|> insert_id draft1 id1
|
wenzelm@29093
|
299 |
|> insert_id draft2 id2;
|
wenzelm@16436
|
300 |
|
wenzelm@16436
|
301 |
|
wenzelm@16533
|
302 |
(* equality and inclusion *)
|
wenzelm@16533
|
303 |
|
wenzelm@24141
|
304 |
val eq_thy = eq_id o pairself (#id o identity_of);
|
wenzelm@16533
|
305 |
|
wenzelm@29069
|
306 |
fun proper_subthy (Theory ({id, ...}, _, _, _), Theory ({ids, ...}, _, _, _)) =
|
wenzelm@29093
|
307 |
Inttab.defined ids id;
|
wenzelm@16533
|
308 |
|
wenzelm@16533
|
309 |
fun subthy thys = eq_thy thys orelse proper_subthy thys;
|
wenzelm@16533
|
310 |
|
wenzelm@16594
|
311 |
fun joinable (thy1, thy2) = subthy (thy1, thy2) orelse subthy (thy2, thy1);
|
wenzelm@16594
|
312 |
|
wenzelm@16533
|
313 |
|
wenzelm@29093
|
314 |
(* consistent ancestors *)
|
wenzelm@29093
|
315 |
|
wenzelm@50431
|
316 |
fun eq_thy_consistent (thy1, thy2) =
|
wenzelm@50431
|
317 |
eq_thy (thy1, thy2) orelse
|
wenzelm@50431
|
318 |
(theory_name thy1 = theory_name thy2 andalso
|
wenzelm@50431
|
319 |
raise THEORY ("Duplicate theory name", [thy1, thy2]));
|
wenzelm@50431
|
320 |
|
wenzelm@29093
|
321 |
fun extend_ancestors thy thys =
|
wenzelm@50431
|
322 |
if member eq_thy_consistent thys thy then
|
wenzelm@33033
|
323 |
raise THEORY ("Duplicate theory node", thy :: thys)
|
wenzelm@29093
|
324 |
else thy :: thys;
|
wenzelm@29093
|
325 |
|
wenzelm@50431
|
326 |
val merge_ancestors = merge eq_thy_consistent;
|
wenzelm@29093
|
327 |
|
wenzelm@29093
|
328 |
|
wenzelm@23355
|
329 |
(* trivial merge *)
|
wenzelm@16436
|
330 |
|
wenzelm@16436
|
331 |
fun merge (thy1, thy2) =
|
wenzelm@16719
|
332 |
if eq_thy (thy1, thy2) then thy1
|
wenzelm@16719
|
333 |
else if proper_subthy (thy2, thy1) then thy1
|
wenzelm@16719
|
334 |
else if proper_subthy (thy1, thy2) then thy2
|
wenzelm@29093
|
335 |
else error (cat_lines ["Attempt to perform non-trivial merge of theories:",
|
wenzelm@29093
|
336 |
str_of_thy thy1, str_of_thy thy2]);
|
wenzelm@16436
|
337 |
|
wenzelm@16719
|
338 |
fun merge_refs (ref1, ref2) =
|
wenzelm@16719
|
339 |
if ref1 = ref2 then ref1
|
wenzelm@24141
|
340 |
else check_thy (merge (deref ref1, deref ref2));
|
wenzelm@16436
|
341 |
|
wenzelm@16436
|
342 |
|
wenzelm@16489
|
343 |
|
wenzelm@16489
|
344 |
(** build theories **)
|
wenzelm@16489
|
345 |
|
wenzelm@16489
|
346 |
(* primitives *)
|
wenzelm@16489
|
347 |
|
wenzelm@33606
|
348 |
local
|
wenzelm@33606
|
349 |
val lock = Mutex.mutex ();
|
wenzelm@33606
|
350 |
in
|
wenzelm@37216
|
351 |
fun SYNCHRONIZED e = Simple_Thread.synchronized "theory" lock e;
|
wenzelm@33606
|
352 |
end;
|
wenzelm@33606
|
353 |
|
wenzelm@29093
|
354 |
fun create_thy self draft ids data ancestry history =
|
wenzelm@29093
|
355 |
let val identity = make_identity self draft (serial ()) ids;
|
wenzelm@29093
|
356 |
in vitalize (Theory (identity, data, ancestry, history)) end;
|
wenzelm@16436
|
357 |
|
wenzelm@29093
|
358 |
fun change_thy draft' f thy =
|
wenzelm@16489
|
359 |
let
|
wenzelm@29093
|
360 |
val Theory ({self, draft, id, ids}, data, ancestry, history) = thy;
|
wenzelm@16489
|
361 |
val (self', data', ancestry') =
|
wenzelm@29093
|
362 |
if draft then (self, data, ancestry) (*destructive change!*)
|
wenzelm@29093
|
363 |
else if #stage history > 0
|
haftmann@34245
|
364 |
then (NONE, data, ancestry)
|
wenzelm@50431
|
365 |
else (NONE, extend_data data, make_ancestry [thy] (extend_ancestors thy (ancestors_of thy)));
|
wenzelm@29093
|
366 |
val ids' = insert_id draft id ids;
|
wenzelm@16489
|
367 |
val data'' = f data';
|
wenzelm@33606
|
368 |
val thy' = SYNCHRONIZED (fn () =>
|
wenzelm@29093
|
369 |
(check_thy thy; create_thy self' draft' ids' data'' ancestry' history));
|
wenzelm@24369
|
370 |
in thy' end;
|
wenzelm@16489
|
371 |
|
wenzelm@29093
|
372 |
val name_thy = change_thy false I;
|
wenzelm@29093
|
373 |
val extend_thy = change_thy true I;
|
wenzelm@29093
|
374 |
val modify_thy = change_thy true;
|
wenzelm@16489
|
375 |
|
wenzelm@24369
|
376 |
fun copy_thy thy =
|
wenzelm@24141
|
377 |
let
|
wenzelm@29093
|
378 |
val Theory ({draft, id, ids, ...}, data, ancestry, history) = thy;
|
wenzelm@29093
|
379 |
val ids' = insert_id draft id ids;
|
wenzelm@33606
|
380 |
val thy' = SYNCHRONIZED (fn () =>
|
haftmann@34245
|
381 |
(check_thy thy; create_thy NONE true ids' data ancestry history));
|
wenzelm@24369
|
382 |
in thy' end;
|
wenzelm@16489
|
383 |
|
wenzelm@29093
|
384 |
val pre_pure_thy = create_thy NONE true Inttab.empty
|
wenzelm@29069
|
385 |
Datatab.empty (make_ancestry [] []) (make_history PureN 0);
|
wenzelm@16489
|
386 |
|
wenzelm@16489
|
387 |
|
wenzelm@16489
|
388 |
(* named theory nodes *)
|
wenzelm@16489
|
389 |
|
wenzelm@16489
|
390 |
fun merge_thys pp (thy1, thy2) =
|
wenzelm@26957
|
391 |
let
|
wenzelm@29093
|
392 |
val ids = merge_ids thy1 thy2;
|
wenzelm@26957
|
393 |
val data = merge_data (pp thy1) (data_of thy1, data_of thy2);
|
wenzelm@26957
|
394 |
val ancestry = make_ancestry [] [];
|
wenzelm@29069
|
395 |
val history = make_history "" 0;
|
wenzelm@33606
|
396 |
val thy' = SYNCHRONIZED (fn () =>
|
wenzelm@29093
|
397 |
(check_thy thy1; check_thy thy2; create_thy NONE true ids data ancestry history));
|
wenzelm@26957
|
398 |
in thy' end;
|
wenzelm@16489
|
399 |
|
wenzelm@16533
|
400 |
fun maximal_thys thys =
|
wenzelm@28617
|
401 |
thys |> filter_out (fn thy => exists (fn thy' => proper_subthy (thy, thy')) thys);
|
wenzelm@16533
|
402 |
|
wenzelm@16489
|
403 |
fun begin_thy pp name imports =
|
wenzelm@29093
|
404 |
if name = "" orelse name = draftN then error ("Bad theory name: " ^ quote name)
|
wenzelm@24369
|
405 |
else
|
wenzelm@16489
|
406 |
let
|
wenzelm@24141
|
407 |
val parents = maximal_thys (distinct eq_thy imports);
|
wenzelm@29093
|
408 |
val ancestors =
|
wenzelm@29093
|
409 |
Library.foldl merge_ancestors ([], map ancestors_of parents)
|
wenzelm@29093
|
410 |
|> fold extend_ancestors parents;
|
wenzelm@29093
|
411 |
|
wenzelm@29093
|
412 |
val Theory ({ids, ...}, data, _, _) =
|
wenzelm@16489
|
413 |
(case parents of
|
wenzelm@48638
|
414 |
[] => error "Missing theory imports"
|
wenzelm@16533
|
415 |
| [thy] => extend_thy thy
|
wenzelm@16533
|
416 |
| thy :: thys => Library.foldl (merge_thys pp) (thy, thys));
|
wenzelm@29093
|
417 |
|
wenzelm@16489
|
418 |
val ancestry = make_ancestry parents ancestors;
|
wenzelm@29069
|
419 |
val history = make_history name 0;
|
wenzelm@33606
|
420 |
val thy' = SYNCHRONIZED (fn () =>
|
wenzelm@29093
|
421 |
(map check_thy imports; create_thy NONE true ids data ancestry history));
|
wenzelm@24369
|
422 |
in thy' end;
|
wenzelm@16436
|
423 |
|
wenzelm@16436
|
424 |
|
wenzelm@29093
|
425 |
(* history stages *)
|
wenzelm@29093
|
426 |
|
wenzelm@29093
|
427 |
fun history_stage f thy =
|
wenzelm@29093
|
428 |
let
|
wenzelm@29093
|
429 |
val {name, stage} = history_of thy;
|
wenzelm@29095
|
430 |
val _ = stage = finished andalso raise THEORY ("Theory already finished", [thy]);
|
wenzelm@29093
|
431 |
val history' = make_history name (f stage);
|
wenzelm@29093
|
432 |
val thy' as Theory (identity', data', ancestry', _) = name_thy thy;
|
wenzelm@33606
|
433 |
val thy'' = SYNCHRONIZED (fn () =>
|
wenzelm@29093
|
434 |
(check_thy thy'; vitalize (Theory (identity', data', ancestry', history'))));
|
wenzelm@29093
|
435 |
in thy'' end;
|
wenzelm@16436
|
436 |
|
wenzelm@16489
|
437 |
fun checkpoint_thy thy =
|
wenzelm@29093
|
438 |
if is_draft thy then history_stage (fn stage => stage + 1) thy
|
wenzelm@29093
|
439 |
else thy;
|
wenzelm@16489
|
440 |
|
wenzelm@29095
|
441 |
val finish_thy = history_stage (fn _ => finished);
|
wenzelm@16489
|
442 |
|
wenzelm@16489
|
443 |
|
wenzelm@16489
|
444 |
(* theory data *)
|
wenzelm@16436
|
445 |
|
wenzelm@33033
|
446 |
structure Theory_Data =
|
wenzelm@16489
|
447 |
struct
|
wenzelm@16489
|
448 |
|
wenzelm@16489
|
449 |
val declare = declare_theory_data;
|
wenzelm@16489
|
450 |
|
wenzelm@16489
|
451 |
fun get k dest thy =
|
wenzelm@34253
|
452 |
(case Datatab.lookup (data_of thy) k of
|
wenzelm@22847
|
453 |
SOME x => x
|
wenzelm@34253
|
454 |
| NONE => invoke_empty k) |> dest;
|
wenzelm@16489
|
455 |
|
wenzelm@22847
|
456 |
fun put k mk x = modify_thy (Datatab.update (k, mk x));
|
wenzelm@16489
|
457 |
|
wenzelm@16489
|
458 |
end;
|
wenzelm@16436
|
459 |
|
wenzelm@16436
|
460 |
|
wenzelm@16436
|
461 |
|
wenzelm@16533
|
462 |
(*** proof context ***)
|
wenzelm@16533
|
463 |
|
wenzelm@33031
|
464 |
(* datatype Proof.context *)
|
wenzelm@17060
|
465 |
|
wenzelm@33031
|
466 |
structure Proof =
|
wenzelm@33031
|
467 |
struct
|
wenzelm@51368
|
468 |
datatype context = Context of Any.T Datatab.table * theory_ref;
|
wenzelm@33031
|
469 |
end;
|
wenzelm@33031
|
470 |
|
wenzelm@33031
|
471 |
fun theory_of_proof (Proof.Context (_, thy_ref)) = deref thy_ref;
|
wenzelm@33031
|
472 |
fun data_of_proof (Proof.Context (data, _)) = data;
|
wenzelm@33031
|
473 |
fun map_prf f (Proof.Context (data, thy_ref)) = Proof.Context (f data, thy_ref);
|
wenzelm@17060
|
474 |
|
wenzelm@16533
|
475 |
|
wenzelm@16533
|
476 |
(* proof data kinds *)
|
wenzelm@16533
|
477 |
|
wenzelm@16533
|
478 |
local
|
wenzelm@16533
|
479 |
|
wenzelm@51368
|
480 |
val kinds = Synchronized.var "Proof_Data" (Datatab.empty: (theory -> Any.T) Datatab.table);
|
wenzelm@16533
|
481 |
|
wenzelm@22847
|
482 |
fun invoke_init k =
|
wenzelm@43684
|
483 |
(case Datatab.lookup (Synchronized.value kinds) k of
|
wenzelm@22847
|
484 |
SOME init => init
|
wenzelm@37852
|
485 |
| NONE => raise Fail "Invalid proof data identifier");
|
wenzelm@16533
|
486 |
|
wenzelm@22847
|
487 |
fun init_data thy =
|
wenzelm@43684
|
488 |
Datatab.map (fn k => fn _ => invoke_init k thy) (Synchronized.value kinds);
|
wenzelm@22847
|
489 |
|
wenzelm@22847
|
490 |
fun init_new_data data thy =
|
wenzelm@22847
|
491 |
Datatab.merge (K true) (data, init_data thy);
|
wenzelm@16533
|
492 |
|
wenzelm@16533
|
493 |
in
|
wenzelm@16533
|
494 |
|
wenzelm@33031
|
495 |
fun raw_transfer thy' (Proof.Context (data, thy_ref)) =
|
wenzelm@24141
|
496 |
let
|
wenzelm@24141
|
497 |
val thy = deref thy_ref;
|
wenzelm@24141
|
498 |
val _ = subthy (thy, thy') orelse error "transfer proof context: not a super theory";
|
wenzelm@24141
|
499 |
val _ = check_thy thy;
|
wenzelm@24184
|
500 |
val data' = init_new_data data thy';
|
wenzelm@24141
|
501 |
val thy_ref' = check_thy thy';
|
wenzelm@33031
|
502 |
in Proof.Context (data', thy_ref') end;
|
wenzelm@22847
|
503 |
|
wenzelm@42360
|
504 |
structure Proof_Context =
|
wenzelm@33031
|
505 |
struct
|
wenzelm@33031
|
506 |
val theory_of = theory_of_proof;
|
wenzelm@36610
|
507 |
fun init_global thy = Proof.Context (init_data thy, check_thy thy);
|
wenzelm@51686
|
508 |
fun get_global thy name = init_global (get_theory thy name);
|
wenzelm@33031
|
509 |
end;
|
wenzelm@16533
|
510 |
|
wenzelm@33033
|
511 |
structure Proof_Data =
|
wenzelm@16533
|
512 |
struct
|
wenzelm@16533
|
513 |
|
wenzelm@22847
|
514 |
fun declare init =
|
wenzelm@16533
|
515 |
let
|
wenzelm@16533
|
516 |
val k = serial ();
|
wenzelm@43684
|
517 |
val _ = Synchronized.change kinds (Datatab.update (k, init));
|
wenzelm@16533
|
518 |
in k end;
|
wenzelm@16533
|
519 |
|
wenzelm@16533
|
520 |
fun get k dest prf =
|
wenzelm@22847
|
521 |
dest (case Datatab.lookup (data_of_proof prf) k of
|
wenzelm@22847
|
522 |
SOME x => x
|
wenzelm@42360
|
523 |
| NONE => invoke_init k (Proof_Context.theory_of prf)); (*adhoc value*)
|
wenzelm@16533
|
524 |
|
wenzelm@19028
|
525 |
fun put k mk x = map_prf (Datatab.update (k, mk x));
|
wenzelm@16533
|
526 |
|
wenzelm@16533
|
527 |
end;
|
wenzelm@16533
|
528 |
|
wenzelm@16533
|
529 |
end;
|
wenzelm@16533
|
530 |
|
wenzelm@16533
|
531 |
|
wenzelm@18632
|
532 |
|
wenzelm@16533
|
533 |
(*** generic context ***)
|
wenzelm@16533
|
534 |
|
wenzelm@33031
|
535 |
datatype generic = Theory of theory | Proof of Proof.context;
|
wenzelm@18632
|
536 |
|
wenzelm@18632
|
537 |
fun cases f _ (Theory thy) = f thy
|
wenzelm@18632
|
538 |
| cases _ g (Proof prf) = g prf;
|
wenzelm@16533
|
539 |
|
wenzelm@19678
|
540 |
fun mapping f g = cases (Theory o f) (Proof o g);
|
wenzelm@21660
|
541 |
fun mapping_result f g = cases (apsnd Theory o f) (apsnd Proof o g);
|
wenzelm@19678
|
542 |
|
wenzelm@23595
|
543 |
val the_theory = cases I (fn _ => error "Ill-typed context: theory expected");
|
wenzelm@23595
|
544 |
val the_proof = cases (fn _ => error "Ill-typed context: proof expected") I;
|
wenzelm@16533
|
545 |
|
wenzelm@18731
|
546 |
fun map_theory f = Theory o f o the_theory;
|
wenzelm@18731
|
547 |
fun map_proof f = Proof o f o the_proof;
|
wenzelm@18731
|
548 |
|
wenzelm@26486
|
549 |
fun map_theory_result f = apsnd Theory o f o the_theory;
|
wenzelm@26486
|
550 |
fun map_proof_result f = apsnd Proof o f o the_proof;
|
wenzelm@26486
|
551 |
|
wenzelm@18731
|
552 |
fun theory_map f = the_theory o f o Theory;
|
wenzelm@18731
|
553 |
fun proof_map f = the_proof o f o Proof;
|
wenzelm@18665
|
554 |
|
wenzelm@42360
|
555 |
val theory_of = cases I Proof_Context.theory_of;
|
wenzelm@42360
|
556 |
val proof_of = cases Proof_Context.init_global I;
|
wenzelm@16533
|
557 |
|
wenzelm@22085
|
558 |
|
wenzelm@42383
|
559 |
(* pretty printing context *)
|
wenzelm@42383
|
560 |
|
wenzelm@42383
|
561 |
exception PRETTY of generic;
|
wenzelm@42383
|
562 |
|
wenzelm@47005
|
563 |
val pretty_generic = Pretty o PRETTY;
|
wenzelm@47005
|
564 |
val pretty = pretty_generic o Proof;
|
wenzelm@47005
|
565 |
val pretty_global = pretty_generic o Theory;
|
wenzelm@42383
|
566 |
|
wenzelm@42383
|
567 |
fun pretty_context init (Pretty (PRETTY context)) = cases init I context;
|
wenzelm@42383
|
568 |
|
wenzelm@42383
|
569 |
|
wenzelm@22085
|
570 |
|
wenzelm@26413
|
571 |
(** thread data **)
|
wenzelm@26413
|
572 |
|
wenzelm@26413
|
573 |
local val tag = Universal.tag () : generic option Universal.tag in
|
wenzelm@26413
|
574 |
|
wenzelm@26413
|
575 |
fun thread_data () =
|
wenzelm@28122
|
576 |
(case Thread.getLocal tag of
|
wenzelm@26413
|
577 |
SOME (SOME context) => SOME context
|
wenzelm@26413
|
578 |
| _ => NONE);
|
wenzelm@26413
|
579 |
|
wenzelm@26413
|
580 |
fun the_thread_data () =
|
wenzelm@26413
|
581 |
(case thread_data () of
|
wenzelm@26413
|
582 |
SOME context => context
|
wenzelm@26413
|
583 |
| _ => error "Unknown context");
|
wenzelm@26413
|
584 |
|
wenzelm@28122
|
585 |
fun set_thread_data context = Thread.setLocal (tag, context);
|
wenzelm@26413
|
586 |
fun setmp_thread_data context = Library.setmp_thread_data tag (thread_data ()) context;
|
wenzelm@26413
|
587 |
|
wenzelm@26428
|
588 |
end;
|
wenzelm@26428
|
589 |
|
wenzelm@26428
|
590 |
fun >>> f =
|
wenzelm@26428
|
591 |
let
|
wenzelm@26463
|
592 |
val (res, context') = f (the_thread_data ());
|
wenzelm@26463
|
593 |
val _ = set_thread_data (SOME context');
|
wenzelm@26428
|
594 |
in res end;
|
wenzelm@26428
|
595 |
|
wenzelm@26421
|
596 |
nonfix >>;
|
wenzelm@26463
|
597 |
fun >> f = >>> (fn context => ((), f context));
|
wenzelm@26413
|
598 |
|
wenzelm@26428
|
599 |
val _ = set_thread_data (SOME (Theory pre_pure_thy));
|
wenzelm@26413
|
600 |
|
wenzelm@6185
|
601 |
end;
|
wenzelm@6185
|
602 |
|
wenzelm@33031
|
603 |
structure Basic_Context: BASIC_CONTEXT = Context;
|
wenzelm@33031
|
604 |
open Basic_Context;
|
wenzelm@16436
|
605 |
|
wenzelm@16436
|
606 |
|
wenzelm@16436
|
607 |
|
wenzelm@16533
|
608 |
(*** type-safe interfaces for data declarations ***)
|
wenzelm@16533
|
609 |
|
wenzelm@16533
|
610 |
(** theory data **)
|
wenzelm@16436
|
611 |
|
wenzelm@34259
|
612 |
signature THEORY_DATA_PP_ARGS =
|
wenzelm@16436
|
613 |
sig
|
wenzelm@16436
|
614 |
type T
|
wenzelm@16436
|
615 |
val empty: T
|
wenzelm@16436
|
616 |
val extend: T -> T
|
wenzelm@42383
|
617 |
val merge: Context.pretty -> T * T -> T
|
wenzelm@16436
|
618 |
end;
|
wenzelm@16436
|
619 |
|
wenzelm@34259
|
620 |
signature THEORY_DATA_ARGS =
|
wenzelm@34259
|
621 |
sig
|
wenzelm@34259
|
622 |
type T
|
wenzelm@34259
|
623 |
val empty: T
|
wenzelm@34259
|
624 |
val extend: T -> T
|
wenzelm@34259
|
625 |
val merge: T * T -> T
|
wenzelm@34259
|
626 |
end;
|
wenzelm@34259
|
627 |
|
wenzelm@34253
|
628 |
signature THEORY_DATA =
|
wenzelm@16436
|
629 |
sig
|
wenzelm@16436
|
630 |
type T
|
wenzelm@16436
|
631 |
val get: theory -> T
|
wenzelm@16436
|
632 |
val put: T -> theory -> theory
|
wenzelm@16436
|
633 |
val map: (T -> T) -> theory -> theory
|
wenzelm@16436
|
634 |
end;
|
wenzelm@16436
|
635 |
|
wenzelm@34259
|
636 |
functor Theory_Data_PP(Data: THEORY_DATA_PP_ARGS): THEORY_DATA =
|
wenzelm@16436
|
637 |
struct
|
wenzelm@16436
|
638 |
|
wenzelm@16436
|
639 |
type T = Data.T;
|
wenzelm@16436
|
640 |
exception Data of T;
|
wenzelm@16436
|
641 |
|
wenzelm@42818
|
642 |
val kind =
|
wenzelm@42818
|
643 |
Context.Theory_Data.declare
|
wenzelm@42818
|
644 |
(Position.thread_data ())
|
wenzelm@42818
|
645 |
(Data Data.empty)
|
wenzelm@42818
|
646 |
(fn Data x => Data (Data.extend x))
|
wenzelm@42818
|
647 |
(fn pp => fn (Data x1, Data x2) => Data (Data.merge pp (x1, x2)));
|
wenzelm@16436
|
648 |
|
wenzelm@33033
|
649 |
val get = Context.Theory_Data.get kind (fn Data x => x);
|
wenzelm@33033
|
650 |
val put = Context.Theory_Data.put kind Data;
|
wenzelm@16436
|
651 |
fun map f thy = put (f (get thy)) thy;
|
wenzelm@16436
|
652 |
|
wenzelm@16436
|
653 |
end;
|
wenzelm@16436
|
654 |
|
wenzelm@33517
|
655 |
functor Theory_Data(Data: THEORY_DATA_ARGS): THEORY_DATA =
|
wenzelm@34259
|
656 |
Theory_Data_PP
|
wenzelm@34259
|
657 |
(
|
wenzelm@34259
|
658 |
type T = Data.T;
|
wenzelm@34259
|
659 |
val empty = Data.empty;
|
wenzelm@34259
|
660 |
val extend = Data.extend;
|
wenzelm@34259
|
661 |
fun merge _ = Data.merge;
|
wenzelm@34259
|
662 |
);
|
wenzelm@33517
|
663 |
|
wenzelm@16533
|
664 |
|
wenzelm@16533
|
665 |
|
wenzelm@16533
|
666 |
(** proof data **)
|
wenzelm@16533
|
667 |
|
wenzelm@16533
|
668 |
signature PROOF_DATA_ARGS =
|
wenzelm@16533
|
669 |
sig
|
wenzelm@16533
|
670 |
type T
|
wenzelm@16533
|
671 |
val init: theory -> T
|
wenzelm@16533
|
672 |
end;
|
wenzelm@16533
|
673 |
|
wenzelm@16533
|
674 |
signature PROOF_DATA =
|
wenzelm@16533
|
675 |
sig
|
wenzelm@16533
|
676 |
type T
|
wenzelm@33031
|
677 |
val get: Proof.context -> T
|
wenzelm@33031
|
678 |
val put: T -> Proof.context -> Proof.context
|
wenzelm@33031
|
679 |
val map: (T -> T) -> Proof.context -> Proof.context
|
wenzelm@16533
|
680 |
end;
|
wenzelm@16533
|
681 |
|
wenzelm@33517
|
682 |
functor Proof_Data(Data: PROOF_DATA_ARGS): PROOF_DATA =
|
wenzelm@16533
|
683 |
struct
|
wenzelm@16533
|
684 |
|
wenzelm@16533
|
685 |
type T = Data.T;
|
wenzelm@16533
|
686 |
exception Data of T;
|
wenzelm@16533
|
687 |
|
wenzelm@33033
|
688 |
val kind = Context.Proof_Data.declare (Data o Data.init);
|
wenzelm@16533
|
689 |
|
wenzelm@33033
|
690 |
val get = Context.Proof_Data.get kind (fn Data x => x);
|
wenzelm@33033
|
691 |
val put = Context.Proof_Data.put kind Data;
|
wenzelm@16533
|
692 |
fun map f prf = put (f (get prf)) prf;
|
wenzelm@16533
|
693 |
|
wenzelm@16533
|
694 |
end;
|
wenzelm@16533
|
695 |
|
wenzelm@18632
|
696 |
|
wenzelm@18632
|
697 |
|
wenzelm@18632
|
698 |
(** generic data **)
|
wenzelm@18632
|
699 |
|
wenzelm@18632
|
700 |
signature GENERIC_DATA_ARGS =
|
wenzelm@18632
|
701 |
sig
|
wenzelm@18632
|
702 |
type T
|
wenzelm@18632
|
703 |
val empty: T
|
wenzelm@18632
|
704 |
val extend: T -> T
|
wenzelm@33517
|
705 |
val merge: T * T -> T
|
wenzelm@18632
|
706 |
end;
|
wenzelm@18632
|
707 |
|
wenzelm@18632
|
708 |
signature GENERIC_DATA =
|
wenzelm@18632
|
709 |
sig
|
wenzelm@18632
|
710 |
type T
|
wenzelm@18632
|
711 |
val get: Context.generic -> T
|
wenzelm@18632
|
712 |
val put: T -> Context.generic -> Context.generic
|
wenzelm@18632
|
713 |
val map: (T -> T) -> Context.generic -> Context.generic
|
wenzelm@18632
|
714 |
end;
|
wenzelm@18632
|
715 |
|
wenzelm@33517
|
716 |
functor Generic_Data(Data: GENERIC_DATA_ARGS): GENERIC_DATA =
|
wenzelm@18632
|
717 |
struct
|
wenzelm@18632
|
718 |
|
wenzelm@33517
|
719 |
structure Thy_Data = Theory_Data(Data);
|
wenzelm@33517
|
720 |
structure Prf_Data = Proof_Data(type T = Data.T val init = Thy_Data.get);
|
wenzelm@18632
|
721 |
|
wenzelm@18632
|
722 |
type T = Data.T;
|
wenzelm@18632
|
723 |
|
wenzelm@33033
|
724 |
fun get (Context.Theory thy) = Thy_Data.get thy
|
wenzelm@33033
|
725 |
| get (Context.Proof prf) = Prf_Data.get prf;
|
wenzelm@18632
|
726 |
|
wenzelm@33033
|
727 |
fun put x (Context.Theory thy) = Context.Theory (Thy_Data.put x thy)
|
wenzelm@33033
|
728 |
| put x (Context.Proof prf) = Context.Proof (Prf_Data.put x prf);
|
wenzelm@18632
|
729 |
|
wenzelm@18632
|
730 |
fun map f ctxt = put (f (get ctxt)) ctxt;
|
wenzelm@18632
|
731 |
|
wenzelm@18632
|
732 |
end;
|
wenzelm@18632
|
733 |
|
wenzelm@16533
|
734 |
(*hide private interface*)
|
wenzelm@16436
|
735 |
structure Context: CONTEXT = Context;
|
wenzelm@20297
|
736 |
|