src/Pure/Isar/toplevel.ML
changeset 20128 8f0e07d7cf92
parent 19996 a4332e71c1de
child 20363 f34c5dbe74d5
equal deleted inserted replaced
20127:4ddbf46ef9bd 20128:8f0e07d7cf92
    42   val timing: bool ref
    42   val timing: bool ref
    43   val profiling: int ref
    43   val profiling: int ref
    44   val skip_proofs: bool ref
    44   val skip_proofs: bool ref
    45   exception TERMINATE
    45   exception TERMINATE
    46   exception RESTART
    46   exception RESTART
       
    47   val exn_message: exn -> string
       
    48   val program: (unit -> 'a) -> 'a
    47   val checkpoint: state -> state
    49   val checkpoint: state -> state
    48   val copy: state -> state
    50   val copy: state -> state
    49   type transition
    51   type transition
    50   val undo_limit: bool -> int option
    52   val undo_limit: bool -> int option
    51   val empty: transition
    53   val empty: transition
    62   val no_timing: transition -> transition
    64   val no_timing: transition -> transition
    63   val reset: transition -> transition
    65   val reset: transition -> transition
    64   val init: (bool -> node) -> (node -> unit) -> (node -> unit) -> transition -> transition
    66   val init: (bool -> node) -> (node -> unit) -> (node -> unit) -> transition -> transition
    65   val exit: transition -> transition
    67   val exit: transition -> transition
    66   val kill: transition -> transition
    68   val kill: transition -> transition
       
    69   val history: (node History.T -> node History.T) -> transition -> transition
    67   val keep: (state -> unit) -> transition -> transition
    70   val keep: (state -> unit) -> transition -> transition
    68   val keep': (bool -> state -> unit) -> transition -> transition
    71   val keep': (bool -> state -> unit) -> transition -> transition
    69   val history: (node History.T -> node History.T) -> transition -> transition
       
    70   val imperative: (unit -> unit) -> transition -> transition
    72   val imperative: (unit -> unit) -> transition -> transition
    71   val init_theory: (bool -> theory) -> (theory -> unit) -> (theory -> unit)
    73   val init_theory: (bool -> theory) -> (theory -> unit) -> (theory -> unit)
    72     -> transition -> transition
    74     -> transition -> transition
    73   val theory: (theory -> theory) -> transition -> transition
    75   val theory: (theory -> theory) -> transition -> transition
    74   val theory': (bool -> theory -> theory) -> transition -> transition
    76   val theory': (bool -> theory -> theory) -> transition -> transition
    91   val present_local_theory: xstring option -> (bool -> node -> unit) -> transition -> transition
    93   val present_local_theory: xstring option -> (bool -> node -> unit) -> transition -> transition
    92   val present_proof: (bool -> node -> unit) -> transition -> transition
    94   val present_proof: (bool -> node -> unit) -> transition -> transition
    93   val unknown_theory: transition -> transition
    95   val unknown_theory: transition -> transition
    94   val unknown_proof: transition -> transition
    96   val unknown_proof: transition -> transition
    95   val unknown_context: transition -> transition
    97   val unknown_context: transition -> transition
    96   val exn_message: exn -> string
       
    97   val apply: bool -> transition -> state -> (state * (exn * string) option) option
    98   val apply: bool -> transition -> state -> (state * (exn * string) option) option
    98   val present_excursion: (transition * (state -> state -> 'a -> 'a)) list -> 'a -> 'a
    99   val present_excursion: (transition * (state -> state -> 'a -> 'a)) list -> 'a -> 'a
    99   val excursion: transition list -> unit
   100   val excursion: transition list -> unit
   100   val program: (unit -> 'a) -> 'a
       
   101   val set_state: state -> unit
   101   val set_state: state -> unit
   102   val get_state: unit -> state
   102   val get_state: unit -> state
   103   val exn: unit -> (exn * string) option
   103   val exn: unit -> (exn * string) option
   104   val >> : transition -> bool
   104   val >> : transition -> bool
   105   val >>> : transition list -> unit
   105   val >>> : transition list -> unit
   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 =
   644 fun excursion trs = present_excursion (map (rpair no_pr) trs) ();
   661 fun excursion trs = present_excursion (map (rpair no_pr) trs) ();
   645 
   662 
   646 end;
   663 end;
   647 
   664 
   648 
   665 
   649 (* toplevel program: independent of state *)
       
   650 
       
   651 fun program f =
       
   652   Output.ML_errors (fn () => debugging f () handle exn => error (exn_message exn)) ();
       
   653 
       
   654 
       
   655 
   666 
   656 (** interactive transformations **)
   667 (** interactive transformations **)
   657 
   668 
   658 (* the global state reference *)
   669 (* the global state reference *)
   659 
   670