129 fun rep_theory_id (Theory_Id args) = args; |
142 fun rep_theory_id (Theory_Id args) = args; |
130 val make_theory_id = Theory_Id; |
143 val make_theory_id = Theory_Id; |
131 |
144 |
132 end; |
145 end; |
133 |
146 |
|
147 |
|
148 (* theory *) |
|
149 |
134 datatype theory = |
150 datatype theory = |
135 Theory of |
151 Theory of |
|
152 (*allocation state*) |
|
153 state * |
136 (*identity*) |
154 (*identity*) |
137 {theory_id: theory_id, |
155 {theory_id: theory_id, |
138 token: Position.T Unsynchronized.ref} * |
156 token: Position.T Unsynchronized.ref} * |
139 (*allocation state*) |
|
140 {next_stage: unit -> int} * |
|
141 (*ancestry*) |
157 (*ancestry*) |
142 {parents: theory list, (*immediate predecessors*) |
158 {parents: theory list, (*immediate predecessors*) |
143 ancestors: theory list} * (*all predecessors -- canonical reverse order*) |
159 ancestors: theory list} * (*all predecessors -- canonical reverse order*) |
144 (*data*) |
160 (*data*) |
145 Any.T Datatab.table; (*body content*) |
161 Any.T Datatab.table; (*body content*) |
146 |
162 |
147 exception THEORY of string * theory list; |
163 exception THEORY of string * theory list; |
148 |
164 |
149 fun rep_theory (Theory args) = args; |
165 fun rep_theory (Theory args) = args; |
150 |
166 |
151 val theory_identity = #1 o rep_theory; |
167 val state_of = #1 o rep_theory; |
|
168 val theory_identity = #2 o rep_theory; |
152 val theory_id = #theory_id o theory_identity; |
169 val theory_id = #theory_id o theory_identity; |
153 val identity_of = rep_theory_id o theory_id; |
170 val identity_of = rep_theory_id o theory_id; |
154 val state_of = #2 o rep_theory; |
|
155 val ancestry_of = #3 o rep_theory; |
171 val ancestry_of = #3 o rep_theory; |
156 val data_of = #4 o rep_theory; |
172 val data_of = #4 o rep_theory; |
157 |
|
158 fun make_state () = {next_stage = Counter.make ()}; |
|
159 fun next_stage {next_stage: unit -> int} = next_stage (); |
|
160 |
173 |
161 fun make_ancestry parents ancestors = {parents = parents, ancestors = ancestors}; |
174 fun make_ancestry parents ancestors = {parents = parents, ancestors = ancestors}; |
162 |
175 |
163 fun stage_final stage = stage = 0; |
176 fun stage_final stage = stage = 0; |
164 |
177 |
261 local |
273 local |
262 |
274 |
263 type kind = |
275 type kind = |
264 {pos: Position.T, |
276 {pos: Position.T, |
265 empty: Any.T, |
277 empty: Any.T, |
266 merge: theory * theory -> Any.T * Any.T -> Any.T}; |
278 merge: (theory * Any.T) list -> Any.T}; |
267 |
279 |
268 val kinds = Synchronized.var "Theory_Data" (Datatab.empty: kind Datatab.table); |
280 val kinds = Synchronized.var "Theory_Data" (Datatab.empty: kind Datatab.table); |
269 |
281 |
270 fun invoke name f k x = |
282 fun the_kind k = |
271 (case Datatab.lookup (Synchronized.value kinds) k of |
283 (case Datatab.lookup (Synchronized.value kinds) k of |
272 SOME kind => |
284 SOME kind => kind |
273 if ! timing andalso name <> "" then |
|
274 Timing.cond_timeit true ("Theory_Data." ^ name ^ Position.here (#pos kind)) |
|
275 (fn () => f kind x) |
|
276 else f kind x |
|
277 | NONE => raise Fail "Invalid theory data identifier"); |
285 | NONE => raise Fail "Invalid theory data identifier"); |
278 |
286 |
279 in |
287 in |
280 |
288 |
281 fun invoke_pos k = invoke "" (K o #pos) k (); |
289 val invoke_pos = #pos o the_kind; |
282 fun invoke_empty k = invoke "" (K o #empty) k (); |
290 val invoke_empty = #empty o the_kind; |
283 fun invoke_merge thys = invoke "merge" (fn kind => #merge kind thys); |
291 |
|
292 fun invoke_merge kind args = |
|
293 if ! timing then |
|
294 Timing.cond_timeit true ("Theory_Data.merge" ^ Position.here (#pos kind)) |
|
295 (fn () => #merge kind args) |
|
296 else #merge kind args; |
284 |
297 |
285 fun declare_data pos empty merge = |
298 fun declare_data pos empty merge = |
286 let |
299 let |
287 val k = serial (); |
300 val k = serial (); |
288 val kind = {pos = pos, empty = empty, merge = merge}; |
301 val kind = {pos = pos, empty = empty, merge = merge}; |
289 val _ = Synchronized.change kinds (Datatab.update (k, kind)); |
302 val _ = Synchronized.change kinds (Datatab.update (k, kind)); |
290 in k end; |
303 in k end; |
291 |
304 |
|
305 fun lookup_data k thy = Datatab.lookup (data_of thy) k; |
|
306 |
292 fun get_data k thy = |
307 fun get_data k thy = |
293 (case Datatab.lookup (data_of thy) k of |
308 (case lookup_data k thy of |
294 SOME x => x |
309 SOME x => x |
295 | NONE => invoke_empty k); |
310 | NONE => invoke_empty k); |
296 |
311 |
297 fun merge_data thys = Datatab.join (invoke_merge thys); |
312 fun merge_data [] = Datatab.empty |
|
313 | merge_data [thy] = data_of thy |
|
314 | merge_data thys = |
|
315 let |
|
316 fun merge (k, kind) data = |
|
317 (case map_filter (fn thy => lookup_data k thy |> Option.map (pair thy)) thys of |
|
318 [] => data |
|
319 | [(_, x)] => Datatab.default (k, x) data |
|
320 | args => Datatab.update (k, invoke_merge kind args) data); |
|
321 in Datatab.fold merge (Synchronized.value kinds) (data_of (hd thys)) end; |
298 |
322 |
299 end; |
323 end; |
300 |
324 |
301 |
325 |
302 |
326 |
334 {active_positions = active_positions, |
358 {active_positions = active_positions, |
335 active = length active_positions, |
359 active = length active_positions, |
336 total = length trace} |
360 total = length trace} |
337 end; |
361 end; |
338 |
362 |
339 fun create_thy ids name stage state ancestry data = |
363 fun create_thy state ids name stage ancestry data = |
340 let |
364 let |
341 val theory_id = make_theory_id {id = serial (), ids = ids, name = name, stage = stage}; |
365 val theory_id = make_theory_id {id = serial (), ids = ids, name = name, stage = stage}; |
342 val token = make_token (); |
366 val identity = {theory_id = theory_id, token = make_token ()}; |
343 in Theory ({theory_id = theory_id, token = token}, state, ancestry, data) end; |
367 in Theory (state, identity, ancestry, data) end; |
344 |
368 |
345 end; |
369 end; |
346 |
370 |
347 |
371 |
348 (* primitives *) |
372 (* primitives *) |
349 |
373 |
350 val pre_pure_thy = |
374 val pre_pure_thy = |
351 let |
375 let |
352 val state = make_state (); |
376 val state = make_state (); |
353 val stage = next_stage state; |
377 val stage = next_stage state; |
354 in create_thy Intset.empty PureN stage state (make_ancestry [] []) Datatab.empty end; |
378 in create_thy state Intset.empty PureN stage (make_ancestry [] []) Datatab.empty end; |
355 |
379 |
356 local |
380 local |
357 |
381 |
358 fun change_thy finish f thy = |
382 fun change_thy finish f thy = |
359 let |
383 let |
360 val {id, ids, name, stage} = identity_of thy; |
384 val {name, stage, ...} = identity_of thy; |
361 val Theory (_, state, ancestry, data) = thy; |
385 val Theory (state, _, ancestry, data) = thy; |
362 val ancestry' = |
386 val ancestry' = |
363 if stage_final stage |
387 if stage_final stage |
364 then make_ancestry [thy] (extend_ancestors thy (ancestors_of thy)) |
388 then make_ancestry [thy] (extend_ancestors thy (ancestors_of thy)) |
365 else ancestry; |
389 else ancestry; |
366 val ids' = Intset.insert id ids; |
390 val ids' = merge_ids [thy]; |
367 val stage' = if finish then 0 else next_stage state; |
391 val stage' = if finish then 0 else next_stage state; |
368 val data' = f data; |
392 val data' = f data; |
369 in create_thy ids' name stage' state ancestry' data' end; |
393 in create_thy state ids' name stage' ancestry' data' end; |
370 |
394 |
371 in |
395 in |
372 |
396 |
373 val update_thy = change_thy false; |
397 val update_thy = change_thy false; |
374 val extend_thy = change_thy false I; |
|
375 val finish_thy = change_thy true I; |
398 val finish_thy = change_thy true I; |
376 |
399 |
377 end; |
400 end; |
378 |
401 |
379 |
402 |
380 (* join: anonymous theory nodes *) |
403 (* join: unfinished theory nodes *) |
381 |
404 |
382 local |
405 fun join_thys [] = raise List.Empty |
383 |
406 | join_thys thys = |
384 fun bad_join (thy1, thy2) = raise THEORY ("Cannot join theories", [thy1, thy2]); |
407 let |
385 |
408 val thy0 = hd thys; |
386 fun join_stage (thy1, thy2) = |
409 val name0 = theory_long_name thy0; |
387 apply2 identity_of (thy1, thy2) |> |
410 val state0 = state_of thy0; |
388 (fn ({name, stage, ...}, {name = name', stage = stage', ...}) => |
411 |
389 if name <> name' orelse stage_final stage orelse stage_final stage' |
412 fun ok thy = |
390 then bad_join (thy1, thy2) |
413 not (theory_id_final (theory_id thy)) andalso |
391 else |
414 theory_long_name thy = name0 andalso |
392 let val state = state_of thy1 |
415 eq_ancestry (thy0, thy); |
393 in {name = name, stage = next_stage state, state = state} end) |
416 val _ = |
394 |
417 (case filter_out ok thys of |
395 fun join_ancestry thys = |
418 [] => () |
396 apply2 ancestry_of thys |> |
419 | bad => raise THEORY ("Cannot join theories", bad)); |
397 (fn (ancestry as {parents, ancestors}, {parents = parents', ancestors = ancestors'}) => |
420 |
398 if eq_list eq_thy (parents, parents') andalso eq_list eq_thy (ancestors, ancestors') |
421 val stage = next_stage state0; |
399 then ancestry else bad_join thys); |
422 val ids = merge_ids thys; |
400 |
423 val data = merge_data thys; |
401 in |
424 in create_thy state0 ids name0 stage (ancestry_of thy0) data end; |
402 |
425 |
403 fun join_thys thys = |
426 |
404 let |
427 (* merge: finished theory nodes *) |
405 val ids = merge_ids thys; |
428 |
406 val {name, stage, state} = join_stage thys; |
429 fun make_parents thys = |
407 val ancestry = join_ancestry thys; |
430 let val thys' = distinct eq_thy thys |
408 val data = merge_data thys (apply2 data_of thys); |
431 in thys' |> filter_out (fn thy => exists (fn thy' => proper_subthy (thy, thy')) thys') end; |
409 in create_thy ids name stage state ancestry data end; |
|
410 |
|
411 end; |
|
412 |
|
413 |
|
414 (* merge: named theory nodes *) |
|
415 |
|
416 local |
|
417 |
|
418 fun merge_thys thys = |
|
419 let |
|
420 val ids = merge_ids thys; |
|
421 val state = state_of (#1 thys); |
|
422 val ancestry = make_ancestry [] []; |
|
423 val data = merge_data thys (apply2 data_of thys); |
|
424 in create_thy ids "" 0 state ancestry data end; |
|
425 |
|
426 fun maximal_thys thys = |
|
427 thys |> filter_out (fn thy => exists (fn thy' => proper_subthy (thy, thy')) thys); |
|
428 |
|
429 in |
|
430 |
432 |
431 fun begin_thy name imports = |
433 fun begin_thy name imports = |
432 if name = "" then error ("Bad theory name: " ^ quote name) |
434 if name = "" then error ("Bad theory name: " ^ quote name) |
|
435 else if null imports then error "Missing theory imports" |
433 else |
436 else |
434 let |
437 let |
435 val parents = maximal_thys (distinct eq_thy imports); |
438 val parents = make_parents imports; |
436 val ancestors = |
439 val ancestors = |
437 Library.foldl merge_ancestors ([], map ancestors_of parents) |
440 Library.foldl1 merge_ancestors (map ancestors_of parents) |
438 |> fold extend_ancestors parents; |
441 |> fold extend_ancestors parents; |
439 |
442 val ancestry = make_ancestry parents ancestors; |
440 val thy0 = |
|
441 (case parents of |
|
442 [] => error "Missing theory imports" |
|
443 | [thy] => extend_thy thy |
|
444 | thy :: thys => Library.foldl merge_thys (thy, thys)); |
|
445 val ids = #ids (identity_of thy0); |
|
446 |
443 |
447 val state = make_state (); |
444 val state = make_state (); |
448 val stage = next_stage state; |
445 val stage = next_stage state; |
449 val ancestry = make_ancestry parents ancestors; |
446 val ids = merge_ids parents; |
450 in create_thy ids name stage state ancestry (data_of thy0) |> tap finish_thy end; |
447 val data = merge_data parents; |
451 |
448 in create_thy state ids name stage ancestry data |> tap finish_thy end; |
452 end; |
|
453 |
449 |
454 |
450 |
455 (* theory data *) |
451 (* theory data *) |
456 |
452 |
457 structure Theory_Data = |
453 structure Theory_Data = |