245 exception TERMINATE; |
245 exception TERMINATE; |
246 exception RESTART; |
246 exception RESTART; |
247 exception EXCURSION_FAIL of exn * string; |
247 exception EXCURSION_FAIL of exn * string; |
248 exception FAILURE of state * exn; |
248 exception FAILURE of state * exn; |
249 |
249 |
250 fun debugging f x = |
|
251 if ! debug then |
|
252 setmp Library.do_transform_failure false |
|
253 exception_trace (fn () => f x) |
|
254 else f x; |
|
255 |
|
256 |
|
257 (* node transactions and recovery from stale theories *) |
|
258 |
|
259 (*NB: proof commands should be non-destructive!*) |
|
260 |
|
261 local |
|
262 |
|
263 fun is_stale state = Context.is_stale (theory_of state) handle UNDEF => false; |
|
264 |
|
265 val stale_theory = ERROR "Stale theory encountered after succesful execution!"; |
|
266 |
|
267 fun checkpoint_node (Theory (thy, _)) = Theory (Theory.checkpoint thy, NONE) |
|
268 | checkpoint_node node = node; |
|
269 |
|
270 fun copy_node (Theory (thy, _)) = Theory (Theory.copy thy, NONE) |
|
271 | copy_node node = node; |
|
272 |
|
273 fun return (result, NONE) = result |
|
274 | return (result, SOME exn) = raise FAILURE (result, exn); |
|
275 |
|
276 fun interruptible f x = |
|
277 let val y = ref x |
|
278 in raise_interrupt (fn () => y := f x) (); ! y end; |
|
279 |
|
280 in |
|
281 |
|
282 fun transaction _ _ (State NONE) = raise UNDEF |
|
283 | transaction hist f (State (SOME (node, term))) = |
|
284 let |
|
285 val cont_node = History.map checkpoint_node node; |
|
286 val back_node = History.map copy_node cont_node; |
|
287 fun state nd = State (SOME (nd, term)); |
|
288 fun normal_state nd = (state nd, NONE); |
|
289 fun error_state nd exn = (state nd, SOME exn); |
|
290 |
|
291 val (result, err) = |
|
292 cont_node |
|
293 |> (f |
|
294 |> (if hist then History.apply_copy copy_node else History.map) |
|
295 |> debugging |
|
296 |> interruptible |
|
297 |> setmp Output.do_toplevel_errors false) |
|
298 |> normal_state |
|
299 handle exn => error_state cont_node exn; |
|
300 in |
|
301 if is_stale result |
|
302 then return (error_state back_node (the_default stale_theory err)) |
|
303 else return (result, err) |
|
304 end; |
|
305 |
|
306 fun mapping f (State (SOME (node, term))) = State (SOME (History.map f node, term)) |
|
307 | mapping _ state = state; |
|
308 |
|
309 val checkpoint = mapping checkpoint_node; |
|
310 val copy = mapping copy_node; |
|
311 |
|
312 end; |
|
313 |
|
314 |
|
315 (* primitive transitions *) |
|
316 |
|
317 (*Note: Recovery from stale theories is provided only for theory-level |
|
318 operations via Transaction. Other node or state operations should |
|
319 not touch theories at all. Interrupts are enabled only for Keep and |
|
320 Transaction.*) |
|
321 |
|
322 datatype trans = |
|
323 Reset | (*empty toplevel*) |
|
324 Init of (bool -> node) * ((node -> unit) * (node -> unit)) | |
|
325 (*init node; with exit/kill operation*) |
|
326 Exit | (*conclude node*) |
|
327 Kill | (*abort node*) |
|
328 Keep of bool -> state -> unit | (*peek at state*) |
|
329 History of node History.T -> node History.T | (*history operation (undo etc.)*) |
|
330 Transaction of bool * (bool -> node -> node); (*node transaction*) |
|
331 |
|
332 fun undo_limit int = if int then NONE else SOME 0; |
|
333 |
|
334 local |
|
335 |
|
336 fun apply_tr _ Reset _ = toplevel |
|
337 | apply_tr int (Init (f, term)) (State NONE) = |
|
338 State (SOME (History.init (undo_limit int) (f int), term)) |
|
339 | apply_tr _ (Init _ ) (State (SOME _)) = raise UNDEF |
|
340 | apply_tr _ Exit (State NONE) = raise UNDEF |
|
341 | apply_tr _ Exit (State (SOME (node, (exit, _)))) = |
|
342 (exit (History.current node); State NONE) |
|
343 | apply_tr _ Kill (State NONE) = raise UNDEF |
|
344 | apply_tr _ Kill (State (SOME (node, (_, kill)))) = |
|
345 (kill (History.current node); State NONE) |
|
346 | apply_tr int (Keep f) state = |
|
347 (setmp Output.do_toplevel_errors false (raise_interrupt (f int)) state; state) |
|
348 | apply_tr _ (History _) (State NONE) = raise UNDEF |
|
349 | apply_tr _ (History f) (State (SOME (node, term))) = State (SOME (f node, term)) |
|
350 | apply_tr int (Transaction (hist, f)) state = transaction hist (fn x => f int x) state; |
|
351 |
|
352 fun apply_union _ [] state = raise FAILURE (state, UNDEF) |
|
353 | apply_union int (tr :: trs) state = |
|
354 apply_tr int tr state |
|
355 handle UNDEF => apply_union int trs state |
|
356 | FAILURE (alt_state, UNDEF) => apply_union int trs alt_state |
|
357 | exn as FAILURE _ => raise exn |
|
358 | exn => raise FAILURE (state, exn); |
|
359 |
|
360 in |
|
361 |
|
362 fun apply_trans int trs state = (apply_union int trs state, NONE) |
|
363 handle FAILURE (alt_state, exn) => (alt_state, SOME exn) | exn => (state, SOME exn); |
|
364 |
|
365 end; |
|
366 |
|
367 |
|
368 (* datatype transition *) |
|
369 |
|
370 datatype transition = Transition of |
|
371 {name: string, (*command name*) |
|
372 pos: Position.T, (*source position*) |
|
373 source: OuterLex.token list option, (*source text*) |
|
374 int_only: bool, (*interactive-only*) |
|
375 print: string list, (*print modes (union)*) |
|
376 no_timing: bool, (*suppress timing*) |
|
377 trans: trans list}; (*primitive transitions (union)*) |
|
378 |
|
379 fun make_transition (name, pos, source, int_only, print, no_timing, trans) = |
|
380 Transition {name = name, pos = pos, source = source, |
|
381 int_only = int_only, print = print, no_timing = no_timing, trans = trans}; |
|
382 |
|
383 fun map_transition f (Transition {name, pos, source, int_only, print, no_timing, trans}) = |
|
384 make_transition (f (name, pos, source, int_only, print, no_timing, trans)); |
|
385 |
|
386 val empty = make_transition ("<unknown>", Position.none, NONE, false, [], false, []); |
|
387 |
|
388 fun name_of (Transition {name, ...}) = name; |
|
389 fun source_of (Transition {source, ...}) = source; |
|
390 |
|
391 |
|
392 (* diagnostics *) |
|
393 |
|
394 fun str_of_transition (Transition {name, pos, ...}) = quote name ^ Position.str_of pos; |
|
395 |
|
396 fun command_msg msg tr = msg ^ "command " ^ str_of_transition tr; |
|
397 fun at_command tr = command_msg "At " tr ^ "."; |
|
398 |
|
399 fun type_error tr state = |
|
400 ERROR (command_msg "Illegal application of " tr ^ " " ^ str_of_state state); |
|
401 |
|
402 |
|
403 (* modify transitions *) |
|
404 |
|
405 fun name nm = map_transition (fn (_, pos, source, int_only, print, no_timing, trans) => |
|
406 (nm, pos, source, int_only, print, no_timing, trans)); |
|
407 |
|
408 fun position pos = map_transition (fn (name, _, source, int_only, print, no_timing, trans) => |
|
409 (name, pos, source, int_only, print, no_timing, trans)); |
|
410 |
|
411 fun source src = map_transition (fn (name, pos, _, int_only, print, no_timing, trans) => |
|
412 (name, pos, SOME src, int_only, print, no_timing, trans)); |
|
413 |
|
414 fun interactive int_only = map_transition (fn (name, pos, source, _, print, no_timing, trans) => |
|
415 (name, pos, source, int_only, print, no_timing, trans)); |
|
416 |
|
417 val no_timing = map_transition (fn (name, pos, source, int_only, print, _, trans) => |
|
418 (name, pos, source, int_only, print, true, trans)); |
|
419 |
|
420 fun add_trans tr = map_transition (fn (name, pos, source, int_only, print, no_timing, trans) => |
|
421 (name, pos, source, int_only, print, no_timing, trans @ [tr])); |
|
422 |
|
423 fun print' mode = map_transition (fn (name, pos, source, int_only, print, no_timing, trans) => |
|
424 (name, pos, source, int_only, insert (op =) mode print, no_timing, trans)); |
|
425 |
|
426 val print = print' ""; |
|
427 |
|
428 val three_buffersN = "three_buffers"; |
|
429 val print3 = print' three_buffersN; |
|
430 |
|
431 |
|
432 (* build transitions *) |
|
433 |
|
434 val reset = add_trans Reset; |
|
435 fun init f exit kill = add_trans (Init (f, (exit, kill))); |
|
436 val exit = add_trans Exit; |
|
437 val kill = add_trans Kill; |
|
438 val keep' = add_trans o Keep; |
|
439 val history = add_trans o History; |
|
440 fun map_current f = add_trans (Transaction (false, f)); |
|
441 fun app_current f = add_trans (Transaction (true, f)); |
|
442 |
|
443 fun keep f = add_trans (Keep (fn _ => f)); |
|
444 fun imperative f = keep (fn _ => f ()); |
|
445 |
|
446 fun init_theory f exit kill = |
|
447 init (fn int => Theory (f int, NONE)) |
|
448 (fn Theory (thy, _) => exit thy | _ => raise UNDEF) |
|
449 (fn Theory (thy, _) => kill thy | _ => raise UNDEF); |
|
450 |
|
451 |
|
452 (* typed transitions *) |
|
453 |
|
454 fun theory f = app_current |
|
455 (K (fn Theory (thy, _) => Theory (f thy, NONE) | _ => raise UNDEF)); |
|
456 |
|
457 fun theory' f = app_current (fn int => |
|
458 (fn Theory (thy, _) => Theory (f int thy, NONE) | _ => raise UNDEF)); |
|
459 |
|
460 fun theory_context f = app_current |
|
461 (K (fn Theory (thy, _) => Theory (swap (apfst SOME (f thy))) | _ => raise UNDEF)); |
|
462 |
|
463 fun local_theory loc f = theory_context (LocalTheory.mapping loc f); |
|
464 |
|
465 fun theory_to_proof f = app_current (fn int => |
|
466 (fn Theory (thy, _) => |
|
467 let |
|
468 val prf = f thy; |
|
469 val schematic = Proof.schematic_goal prf; |
|
470 in |
|
471 if ! skip_proofs andalso schematic then |
|
472 warning "Cannot skip proof of schematic goal statement" |
|
473 else (); |
|
474 if ! skip_proofs andalso not schematic then |
|
475 SkipProof ((History.init (undo_limit int) 0, #2 (Proof.global_skip_proof int prf)), thy) |
|
476 else Proof (ProofHistory.init (undo_limit int) prf, thy) |
|
477 end |
|
478 | _ => raise UNDEF)); |
|
479 |
|
480 fun proofs' f = map_current (fn int => |
|
481 (fn Proof (prf, orig_thy) => Proof (ProofHistory.applys (f int) prf, orig_thy) |
|
482 | SkipProof ((h, thy), orig_thy) => SkipProof ((History.apply I h, thy), orig_thy) |
|
483 | _ => raise UNDEF)); |
|
484 |
|
485 fun proof' f = proofs' (Seq.single oo f); |
|
486 val proofs = proofs' o K; |
|
487 val proof = proof' o K; |
|
488 |
|
489 fun actual_proof f = map_current (fn _ => |
|
490 (fn Proof (prf, orig_thy) => Proof (f prf, orig_thy) | _ => raise UNDEF)); |
|
491 |
|
492 fun skip_proof f = map_current (fn _ => |
|
493 (fn SkipProof ((h, thy), orig_thy) => SkipProof ((f h, thy), orig_thy) | _ => raise UNDEF)); |
|
494 |
|
495 fun end_proof f = map_current (fn int => |
|
496 (fn Proof (prf, _) => Theory (f int (ProofHistory.current prf)) |
|
497 | SkipProof ((h, thy), _) => if History.current h = 0 then Theory (thy, NONE) else raise UNDEF |
|
498 | _ => raise UNDEF)); |
|
499 |
|
500 val forget_proof = map_current (fn _ => |
|
501 (fn Proof (_, orig_thy) => Theory (orig_thy, NONE) |
|
502 | SkipProof (_, orig_thy) => Theory (orig_thy, NONE) |
|
503 | _ => raise UNDEF)); |
|
504 |
|
505 fun proof_to_theory' f = end_proof (rpair NONE oo f); |
|
506 fun proof_to_theory f = proof_to_theory' (K f); |
|
507 fun proof_to_theory_context f = end_proof ((swap o apfst SOME) oo f); |
|
508 |
|
509 fun skip_proof_to_theory p = map_current (fn _ => |
|
510 (fn SkipProof ((h, thy), _) => |
|
511 if p (History.current h) then Theory (thy, NONE) |
|
512 else raise UNDEF |
|
513 | _ => raise UNDEF)); |
|
514 |
|
515 fun present_local_theory loc f = app_current (fn int => |
|
516 (fn Theory (thy, _) => Theory (swap (apfst SOME (LocalTheory.mapping loc I thy))) |
|
517 | _ => raise UNDEF) #> tap (f int)); |
|
518 |
|
519 fun present_proof f = map_current (fn int => |
|
520 (fn node as Proof _ => node | _ => raise UNDEF) #> tap (f int)); |
|
521 |
|
522 val unknown_theory = imperative (fn () => warning "Unknown theory context"); |
|
523 val unknown_proof = imperative (fn () => warning "Unknown proof context"); |
|
524 val unknown_context = imperative (fn () => warning "Unknown context"); |
|
525 |
|
526 |
|
527 |
|
528 (** toplevel transactions **) |
|
529 |
250 |
530 (* print exceptions *) |
251 (* print exceptions *) |
531 |
252 |
532 local |
253 local |
533 |
254 |
582 | print_exn (SOME (exn, s)) = Output.error_msg (cat_lines [exn_message exn, s]); |
303 | print_exn (SOME (exn, s)) = Output.error_msg (cat_lines [exn_message exn, s]); |
583 |
304 |
584 end; |
305 end; |
585 |
306 |
586 |
307 |
|
308 (* controlled execution *) |
|
309 |
|
310 local |
|
311 |
|
312 fun debugging f x = |
|
313 if ! debug then |
|
314 setmp Library.do_transform_failure false |
|
315 exception_trace (fn () => f x) |
|
316 else f x; |
|
317 |
|
318 fun interruptible f x = |
|
319 let val y = ref x |
|
320 in raise_interrupt (fn () => y := f x) (); ! y end; |
|
321 |
|
322 in |
|
323 |
|
324 fun controlled_execution f = |
|
325 f |
|
326 |> debugging |
|
327 |> interruptible |
|
328 |> setmp Output.do_toplevel_errors false; |
|
329 |
|
330 fun program f = |
|
331 Output.ML_errors (fn () => debugging f () handle exn => error (exn_message exn)) (); |
|
332 |
|
333 end; |
|
334 |
|
335 |
|
336 (* node transactions and recovery from stale theories *) |
|
337 |
|
338 (*NB: proof commands should be non-destructive!*) |
|
339 |
|
340 local |
|
341 |
|
342 fun is_stale state = Context.is_stale (theory_of state) handle UNDEF => false; |
|
343 |
|
344 val stale_theory = ERROR "Stale theory encountered after succesful execution!"; |
|
345 |
|
346 fun checkpoint_node (Theory (thy, _)) = Theory (Theory.checkpoint thy, NONE) |
|
347 | checkpoint_node node = node; |
|
348 |
|
349 fun copy_node (Theory (thy, _)) = Theory (Theory.copy thy, NONE) |
|
350 | copy_node node = node; |
|
351 |
|
352 fun return (result, NONE) = result |
|
353 | return (result, SOME exn) = raise FAILURE (result, exn); |
|
354 |
|
355 in |
|
356 |
|
357 fun transaction hist f (node, term) = |
|
358 let |
|
359 val cont_node = History.map checkpoint_node node; |
|
360 val back_node = History.map copy_node cont_node; |
|
361 fun state nd = State (SOME (nd, term)); |
|
362 fun normal_state nd = (state nd, NONE); |
|
363 fun error_state nd exn = (state nd, SOME exn); |
|
364 |
|
365 val (result, err) = |
|
366 cont_node |
|
367 |> (f |
|
368 |> (if hist then History.apply_copy copy_node else History.map) |
|
369 |> controlled_execution) |
|
370 |> normal_state |
|
371 handle exn => error_state cont_node exn; |
|
372 in |
|
373 if is_stale result |
|
374 then return (error_state back_node (the_default stale_theory err)) |
|
375 else return (result, err) |
|
376 end; |
|
377 |
|
378 fun mapping f (State (SOME (node, term))) = State (SOME (History.map f node, term)) |
|
379 | mapping _ state = state; |
|
380 |
|
381 val checkpoint = mapping checkpoint_node; |
|
382 val copy = mapping copy_node; |
|
383 |
|
384 end; |
|
385 |
|
386 |
|
387 (* primitive transitions *) |
|
388 |
|
389 (*Note: Recovery from stale theories is provided only for theory-level |
|
390 operations via Transaction. Other node or state operations should |
|
391 not touch theories at all. Interrupts are enabled only for Keep and |
|
392 Transaction.*) |
|
393 |
|
394 datatype trans = |
|
395 Reset | (*empty toplevel*) |
|
396 Init of (bool -> node) * ((node -> unit) * (node -> unit)) | |
|
397 (*init node; with exit/kill operation*) |
|
398 Exit | (*conclude node*) |
|
399 Kill | (*abort node*) |
|
400 History of node History.T -> node History.T | (*history operation (undo etc.)*) |
|
401 Keep of bool -> state -> unit | (*peek at state*) |
|
402 Transaction of bool * (bool -> node -> node); (*node transaction*) |
|
403 |
|
404 fun undo_limit int = if int then NONE else SOME 0; |
|
405 |
|
406 local |
|
407 |
|
408 fun apply_tr _ Reset _ = toplevel |
|
409 | apply_tr int (Init (f, term)) (State NONE) = |
|
410 State (SOME (History.init (undo_limit int) (f int), term)) |
|
411 | apply_tr _ (Init _ ) (State (SOME _)) = raise UNDEF |
|
412 | apply_tr _ Exit (State NONE) = raise UNDEF |
|
413 | apply_tr _ Exit (State (SOME (node, (exit, _)))) = |
|
414 (exit (History.current node); State NONE) |
|
415 | apply_tr _ Kill (State NONE) = raise UNDEF |
|
416 | apply_tr _ Kill (State (SOME (node, (_, kill)))) = |
|
417 (kill (History.current node); State NONE) |
|
418 | apply_tr _ (History _) (State NONE) = raise UNDEF |
|
419 | apply_tr _ (History f) (State (SOME (node, term))) = State (SOME (f node, term)) |
|
420 | apply_tr int (Keep f) state = |
|
421 controlled_execution (fn x => tap (f int) x) state |
|
422 | apply_tr _ (Transaction _) (State NONE) = raise UNDEF |
|
423 | apply_tr int (Transaction (hist, f)) (State (SOME state)) = |
|
424 transaction hist (fn x => f int x) state; |
|
425 |
|
426 fun apply_union _ [] state = raise FAILURE (state, UNDEF) |
|
427 | apply_union int (tr :: trs) state = |
|
428 apply_tr int tr state |
|
429 handle UNDEF => apply_union int trs state |
|
430 | FAILURE (alt_state, UNDEF) => apply_union int trs alt_state |
|
431 | exn as FAILURE _ => raise exn |
|
432 | exn => raise FAILURE (state, exn); |
|
433 |
|
434 in |
|
435 |
|
436 fun apply_trans int trs state = (apply_union int trs state, NONE) |
|
437 handle FAILURE (alt_state, exn) => (alt_state, SOME exn) | exn => (state, SOME exn); |
|
438 |
|
439 end; |
|
440 |
|
441 |
|
442 (* datatype transition *) |
|
443 |
|
444 datatype transition = Transition of |
|
445 {name: string, (*command name*) |
|
446 pos: Position.T, (*source position*) |
|
447 source: OuterLex.token list option, (*source text*) |
|
448 int_only: bool, (*interactive-only*) |
|
449 print: string list, (*print modes (union)*) |
|
450 no_timing: bool, (*suppress timing*) |
|
451 trans: trans list}; (*primitive transitions (union)*) |
|
452 |
|
453 fun make_transition (name, pos, source, int_only, print, no_timing, trans) = |
|
454 Transition {name = name, pos = pos, source = source, |
|
455 int_only = int_only, print = print, no_timing = no_timing, trans = trans}; |
|
456 |
|
457 fun map_transition f (Transition {name, pos, source, int_only, print, no_timing, trans}) = |
|
458 make_transition (f (name, pos, source, int_only, print, no_timing, trans)); |
|
459 |
|
460 val empty = make_transition ("<unknown>", Position.none, NONE, false, [], false, []); |
|
461 |
|
462 fun name_of (Transition {name, ...}) = name; |
|
463 fun source_of (Transition {source, ...}) = source; |
|
464 |
|
465 |
|
466 (* diagnostics *) |
|
467 |
|
468 fun str_of_transition (Transition {name, pos, ...}) = quote name ^ Position.str_of pos; |
|
469 |
|
470 fun command_msg msg tr = msg ^ "command " ^ str_of_transition tr; |
|
471 fun at_command tr = command_msg "At " tr ^ "."; |
|
472 |
|
473 fun type_error tr state = |
|
474 ERROR (command_msg "Illegal application of " tr ^ " " ^ str_of_state state); |
|
475 |
|
476 |
|
477 (* modify transitions *) |
|
478 |
|
479 fun name nm = map_transition (fn (_, pos, source, int_only, print, no_timing, trans) => |
|
480 (nm, pos, source, int_only, print, no_timing, trans)); |
|
481 |
|
482 fun position pos = map_transition (fn (name, _, source, int_only, print, no_timing, trans) => |
|
483 (name, pos, source, int_only, print, no_timing, trans)); |
|
484 |
|
485 fun source src = map_transition (fn (name, pos, _, int_only, print, no_timing, trans) => |
|
486 (name, pos, SOME src, int_only, print, no_timing, trans)); |
|
487 |
|
488 fun interactive int_only = map_transition (fn (name, pos, source, _, print, no_timing, trans) => |
|
489 (name, pos, source, int_only, print, no_timing, trans)); |
|
490 |
|
491 val no_timing = map_transition (fn (name, pos, source, int_only, print, _, trans) => |
|
492 (name, pos, source, int_only, print, true, trans)); |
|
493 |
|
494 fun add_trans tr = map_transition (fn (name, pos, source, int_only, print, no_timing, trans) => |
|
495 (name, pos, source, int_only, print, no_timing, trans @ [tr])); |
|
496 |
|
497 fun print' mode = map_transition (fn (name, pos, source, int_only, print, no_timing, trans) => |
|
498 (name, pos, source, int_only, insert (op =) mode print, no_timing, trans)); |
|
499 |
|
500 val print = print' ""; |
|
501 |
|
502 val three_buffersN = "three_buffers"; |
|
503 val print3 = print' three_buffersN; |
|
504 |
|
505 |
|
506 (* build transitions *) |
|
507 |
|
508 val reset = add_trans Reset; |
|
509 fun init f exit kill = add_trans (Init (f, (exit, kill))); |
|
510 val exit = add_trans Exit; |
|
511 val kill = add_trans Kill; |
|
512 val history = add_trans o History; |
|
513 val keep' = add_trans o Keep; |
|
514 fun map_current f = add_trans (Transaction (false, f)); |
|
515 fun app_current f = add_trans (Transaction (true, f)); |
|
516 |
|
517 fun keep f = add_trans (Keep (fn _ => f)); |
|
518 fun imperative f = keep (fn _ => f ()); |
|
519 |
|
520 fun init_theory f exit kill = |
|
521 init (fn int => Theory (f int, NONE)) |
|
522 (fn Theory (thy, _) => exit thy | _ => raise UNDEF) |
|
523 (fn Theory (thy, _) => kill thy | _ => raise UNDEF); |
|
524 |
|
525 |
|
526 (* typed transitions *) |
|
527 |
|
528 fun theory f = app_current |
|
529 (K (fn Theory (thy, _) => Theory (f thy, NONE) | _ => raise UNDEF)); |
|
530 |
|
531 fun theory' f = app_current (fn int => |
|
532 (fn Theory (thy, _) => Theory (f int thy, NONE) | _ => raise UNDEF)); |
|
533 |
|
534 fun theory_context f = app_current |
|
535 (K (fn Theory (thy, _) => Theory (swap (apfst SOME (f thy))) | _ => raise UNDEF)); |
|
536 |
|
537 fun local_theory loc f = theory_context (LocalTheory.mapping loc f); |
|
538 |
|
539 fun theory_to_proof f = app_current (fn int => |
|
540 (fn Theory (thy, _) => |
|
541 let |
|
542 val prf = f thy; |
|
543 val schematic = Proof.schematic_goal prf; |
|
544 in |
|
545 if ! skip_proofs andalso schematic then |
|
546 warning "Cannot skip proof of schematic goal statement" |
|
547 else (); |
|
548 if ! skip_proofs andalso not schematic then |
|
549 SkipProof ((History.init (undo_limit int) 0, #2 (Proof.global_skip_proof int prf)), thy) |
|
550 else Proof (ProofHistory.init (undo_limit int) prf, thy) |
|
551 end |
|
552 | _ => raise UNDEF)); |
|
553 |
|
554 fun proofs' f = map_current (fn int => |
|
555 (fn Proof (prf, orig_thy) => Proof (ProofHistory.applys (f int) prf, orig_thy) |
|
556 | SkipProof ((h, thy), orig_thy) => SkipProof ((History.apply I h, thy), orig_thy) |
|
557 | _ => raise UNDEF)); |
|
558 |
|
559 fun proof' f = proofs' (Seq.single oo f); |
|
560 val proofs = proofs' o K; |
|
561 val proof = proof' o K; |
|
562 |
|
563 fun actual_proof f = map_current (fn _ => |
|
564 (fn Proof (prf, orig_thy) => Proof (f prf, orig_thy) | _ => raise UNDEF)); |
|
565 |
|
566 fun skip_proof f = map_current (fn _ => |
|
567 (fn SkipProof ((h, thy), orig_thy) => SkipProof ((f h, thy), orig_thy) | _ => raise UNDEF)); |
|
568 |
|
569 fun end_proof f = map_current (fn int => |
|
570 (fn Proof (prf, _) => Theory (f int (ProofHistory.current prf)) |
|
571 | SkipProof ((h, thy), _) => if History.current h = 0 then Theory (thy, NONE) else raise UNDEF |
|
572 | _ => raise UNDEF)); |
|
573 |
|
574 val forget_proof = map_current (fn _ => |
|
575 (fn Proof (_, orig_thy) => Theory (orig_thy, NONE) |
|
576 | SkipProof (_, orig_thy) => Theory (orig_thy, NONE) |
|
577 | _ => raise UNDEF)); |
|
578 |
|
579 fun proof_to_theory' f = end_proof (rpair NONE oo f); |
|
580 fun proof_to_theory f = proof_to_theory' (K f); |
|
581 fun proof_to_theory_context f = end_proof ((swap o apfst SOME) oo f); |
|
582 |
|
583 fun skip_proof_to_theory p = map_current (fn _ => |
|
584 (fn SkipProof ((h, thy), _) => |
|
585 if p (History.current h) then Theory (thy, NONE) |
|
586 else raise UNDEF |
|
587 | _ => raise UNDEF)); |
|
588 |
|
589 fun present_local_theory loc f = app_current (fn int => |
|
590 (fn Theory (thy, _) => Theory (swap (apfst SOME (LocalTheory.mapping loc I thy))) |
|
591 | _ => raise UNDEF) #> tap (f int)); |
|
592 |
|
593 fun present_proof f = map_current (fn int => |
|
594 (fn node as Proof _ => node | _ => raise UNDEF) #> tap (f int)); |
|
595 |
|
596 val unknown_theory = imperative (fn () => warning "Unknown theory context"); |
|
597 val unknown_proof = imperative (fn () => warning "Unknown proof context"); |
|
598 val unknown_context = imperative (fn () => warning "Unknown context"); |
|
599 |
|
600 |
|
601 |
|
602 (** toplevel transactions **) |
|
603 |
587 (* apply transitions *) |
604 (* apply transitions *) |
588 |
605 |
589 local |
606 local |
590 |
607 |
591 fun app int (tr as Transition {trans, int_only, print, no_timing, ...}) state = |
608 fun app int (tr as Transition {trans, int_only, print, no_timing, ...}) state = |