src/Pure/Isar/toplevel.ML
changeset 31476 c5d2899b6de9
parent 31431 6b840c0b7fb6
child 32058 c76fd93b3b99
equal deleted inserted replaced
31475:85e864045497 31476:c5d2899b6de9
    30   val timing: bool ref
    30   val timing: bool ref
    31   val profiling: int ref
    31   val profiling: int ref
    32   val skip_proofs: bool ref
    32   val skip_proofs: bool ref
    33   exception TERMINATE
    33   exception TERMINATE
    34   exception TOPLEVEL_ERROR
    34   exception TOPLEVEL_ERROR
    35   exception CONTEXT of Proof.context * exn
       
    36   val exn_message: exn -> string
       
    37   val program: (unit -> 'a) -> 'a
    35   val program: (unit -> 'a) -> 'a
    38   type transition
    36   type transition
    39   val empty: transition
    37   val empty: transition
    40   val init_of: transition -> string option
    38   val init_of: transition -> string option
    41   val name_of: transition -> string
    39   val name_of: transition -> string
    96 structure Toplevel: TOPLEVEL =
    94 structure Toplevel: TOPLEVEL =
    97 struct
    95 struct
    98 
    96 
    99 (** toplevel state **)
    97 (** toplevel state **)
   100 
    98 
   101 exception UNDEF;
    99 exception UNDEF = Runtime.UNDEF;
   102 
   100 
   103 
   101 
   104 (* local theory wrappers *)
   102 (* local theory wrappers *)
   105 
   103 
   106 type generic_theory = Context.generic;    (*theory or local_theory*)
   104 type generic_theory = Context.generic;    (*theory or local_theory*)
   223 val interact = ref false;
   221 val interact = ref false;
   224 val timing = Output.timing;
   222 val timing = Output.timing;
   225 val profiling = ref 0;
   223 val profiling = ref 0;
   226 val skip_proofs = ref false;
   224 val skip_proofs = ref false;
   227 
   225 
   228 exception TERMINATE;
   226 exception TERMINATE = Runtime.TERMINATE;
   229 exception EXCURSION_FAIL of exn * string;
   227 exception EXCURSION_FAIL = Runtime.EXCURSION_FAIL;
   230 exception FAILURE of state * exn;
   228 exception TOPLEVEL_ERROR = Runtime.TOPLEVEL_ERROR;
   231 exception TOPLEVEL_ERROR;
       
   232 
       
   233 
       
   234 (* print exceptions *)
       
   235 
       
   236 exception CONTEXT of Proof.context * exn;
       
   237 
       
   238 fun exn_context NONE exn = exn
       
   239   | exn_context (SOME ctxt) exn = CONTEXT (ctxt, exn);
       
   240 
       
   241 local
       
   242 
       
   243 fun if_context NONE _ _ = []
       
   244   | if_context (SOME ctxt) f xs = map (f ctxt) xs;
       
   245 
       
   246 fun raised exn name msgs =
       
   247   let val pos = Position.str_of (ML_Compiler.exception_position exn) in
       
   248     (case msgs of
       
   249       [] => "exception " ^ name ^ " raised" ^ pos
       
   250     | [msg] => "exception " ^ name ^ " raised" ^ pos ^ ": " ^ msg
       
   251     | _ => cat_lines (("exception " ^ name ^ " raised" ^ pos ^ ":") :: msgs))
       
   252   end;
       
   253 
       
   254 in
       
   255 
       
   256 fun exn_message e =
       
   257   let
       
   258     val detailed = ! debug;
       
   259 
       
   260     fun exn_msg _ (CONTEXT (ctxt, exn)) = exn_msg (SOME ctxt) exn
       
   261       | exn_msg ctxt (Exn.EXCEPTIONS exns) = cat_lines (map (exn_msg ctxt) exns)
       
   262       | exn_msg ctxt (EXCURSION_FAIL (exn, loc)) =
       
   263           exn_msg ctxt exn ^ Markup.markup Markup.location ("\n" ^ loc)
       
   264       | exn_msg _ TERMINATE = "Exit."
       
   265       | exn_msg _ Exn.Interrupt = "Interrupt."
       
   266       | exn_msg _ TimeLimit.TimeOut = "Timeout."
       
   267       | exn_msg _ TOPLEVEL_ERROR = "Error."
       
   268       | exn_msg _ (SYS_ERROR msg) = "## SYSTEM ERROR ##\n" ^ msg
       
   269       | exn_msg _ (ERROR msg) = msg
       
   270       | exn_msg _ (exn as Fail msg) = raised exn "Fail" [msg]
       
   271       | exn_msg _ (exn as THEORY (msg, thys)) =
       
   272           raised exn "THEORY" (msg :: (if detailed then map Context.str_of_thy thys else []))
       
   273       | exn_msg _ (exn as Syntax.AST (msg, asts)) = raised exn "AST" (msg ::
       
   274             (if detailed then map (Pretty.string_of o Syntax.pretty_ast) asts else []))
       
   275       | exn_msg ctxt (exn as TYPE (msg, Ts, ts)) = raised exn "TYPE" (msg ::
       
   276             (if detailed then
       
   277               if_context ctxt Syntax.string_of_typ Ts @ if_context ctxt Syntax.string_of_term ts
       
   278              else []))
       
   279       | exn_msg ctxt (exn as TERM (msg, ts)) = raised exn "TERM" (msg ::
       
   280             (if detailed then if_context ctxt Syntax.string_of_term ts else []))
       
   281       | exn_msg ctxt (exn as THM (msg, i, thms)) = raised exn ("THM " ^ string_of_int i) (msg ::
       
   282             (if detailed then if_context ctxt ProofContext.string_of_thm thms else []))
       
   283       | exn_msg _ exn = raised exn (General.exnMessage exn) []
       
   284   in exn_msg NONE e end;
       
   285 
       
   286 end;
       
   287 
       
   288 
       
   289 (* controlled execution *)
       
   290 
       
   291 local
       
   292 
       
   293 fun debugging f x =
       
   294   if ! debug then
       
   295     Exn.release (exception_trace (fn () =>
       
   296       Exn.Result (f x) handle
       
   297         exn as UNDEF => Exn.Exn exn
       
   298       | exn as EXCURSION_FAIL _ => Exn.Exn exn))
       
   299   else f x;
       
   300 
       
   301 fun toplevel_error f x =
       
   302   let val ctxt = try ML_Context.the_local_context () in
       
   303     f x handle exn =>
       
   304       (Output.error_msg (exn_message (exn_context ctxt exn)); raise TOPLEVEL_ERROR)
       
   305   end;
       
   306 
       
   307 in
       
   308 
       
   309 fun controlled_execution f =
       
   310   f
       
   311   |> debugging
       
   312   |> Future.interruptible_task;
       
   313 
   229 
   314 fun program f =
   230 fun program f =
   315  (f
   231  (f
   316   |> controlled_execution
   232   |> Runtime.controlled_execution
   317   |> toplevel_error) ();
   233   |> Runtime.toplevel_error ML_Compiler.exn_message) ();
   318 
       
   319 end;
       
   320 
   234 
   321 
   235 
   322 (* node transactions -- maintaining stable checkpoints *)
   236 (* node transactions -- maintaining stable checkpoints *)
       
   237 
       
   238 exception FAILURE of state * exn;
   323 
   239 
   324 local
   240 local
   325 
   241 
   326 fun reset_presentation (Theory (gthy, _)) = Theory (gthy, NONE)
   242 fun reset_presentation (Theory (gthy, _)) = Theory (gthy, NONE)
   327   | reset_presentation node = node;
   243   | reset_presentation node = node;
   328 
   244 
   329 fun is_draft_theory (Theory (gthy, _)) = Context.is_draft (Context.theory_of gthy)
   245 fun is_draft_theory (Theory (gthy, _)) = Context.is_draft (Context.theory_of gthy)
   330   | is_draft_theory _ = false;
   246   | is_draft_theory _ = false;
   331 
   247 
   332 fun is_stale state = Context.is_stale (theory_of state) handle UNDEF => false;
   248 fun is_stale state = Context.is_stale (theory_of state) handle Runtime.UNDEF => false;
   333 
   249 
   334 fun stale_error NONE = SOME (ERROR "Stale theory encountered after successful execution!")
   250 fun stale_error NONE = SOME (ERROR "Stale theory encountered after successful execution!")
   335   | stale_error some = some;
   251   | stale_error some = some;
   336 
   252 
   337 fun map_theory f (Theory (gthy, ctxt)) =
   253 fun map_theory f (Theory (gthy, ctxt)) =
   347     val back_node = map_theory (Theory.checkpoint o Theory.copy) cont_node;
   263     val back_node = map_theory (Theory.checkpoint o Theory.copy) cont_node;
   348     fun state_error e nd = (State (SOME (nd, exit), SOME (node, exit)), e);
   264     fun state_error e nd = (State (SOME (nd, exit), SOME (node, exit)), e);
   349 
   265 
   350     val (result, err) =
   266     val (result, err) =
   351       cont_node
   267       cont_node
   352       |> controlled_execution f
   268       |> Runtime.controlled_execution f
   353       |> map_theory Theory.checkpoint
   269       |> map_theory Theory.checkpoint
   354       |> state_error NONE
   270       |> state_error NONE
   355       handle exn => state_error (SOME exn) cont_node;
   271       handle exn => state_error (SOME exn) cont_node;
   356 
   272 
   357     val (result', err') =
   273     val (result', err') =
   380 fun apply_tr int _ (Init (_, f, exit)) (State (NONE, _)) =
   296 fun apply_tr int _ (Init (_, f, exit)) (State (NONE, _)) =
   381       State (SOME (Theory (Context.Theory (Theory.checkpoint (f int)), NONE), exit), NONE)
   297       State (SOME (Theory (Context.Theory (Theory.checkpoint (f int)), NONE), exit), NONE)
   382   | apply_tr _ _ Exit (State (prev as SOME (Theory (Context.Theory _, _), _), _)) =
   298   | apply_tr _ _ Exit (State (prev as SOME (Theory (Context.Theory _, _), _), _)) =
   383       State (NONE, prev)
   299       State (NONE, prev)
   384   | apply_tr _ _ CommitExit (State (NONE, SOME (Theory (Context.Theory thy, _), exit))) =
   300   | apply_tr _ _ CommitExit (State (NONE, SOME (Theory (Context.Theory thy, _), exit))) =
   385       (controlled_execution exit thy; toplevel)
   301       (Runtime.controlled_execution exit thy; toplevel)
   386   | apply_tr int _ (Keep f) state =
   302   | apply_tr int _ (Keep f) state =
   387       controlled_execution (fn x => tap (f int) x) state
   303       Runtime.controlled_execution (fn x => tap (f int) x) state
   388   | apply_tr int pos (Transaction (f, g)) (State (SOME state, _)) =
   304   | apply_tr int pos (Transaction (f, g)) (State (SOME state, _)) =
   389       apply_transaction pos (fn x => f int x) g state
   305       apply_transaction pos (fn x => f int x) g state
   390   | apply_tr _ _ _ _ = raise UNDEF;
   306   | apply_tr _ _ _ _ = raise UNDEF;
   391 
   307 
   392 fun apply_union _ _ [] state = raise FAILURE (state, UNDEF)
   308 fun apply_union _ _ [] state = raise FAILURE (state, UNDEF)
   393   | apply_union int pos (tr :: trs) state =
   309   | apply_union int pos (tr :: trs) state =
   394       apply_union int pos trs state
   310       apply_union int pos trs state
   395         handle UNDEF => apply_tr int pos tr state
   311         handle Runtime.UNDEF => apply_tr int pos tr state
   396           | FAILURE (alt_state, UNDEF) => apply_tr int pos tr alt_state
   312           | FAILURE (alt_state, UNDEF) => apply_tr int pos tr alt_state
   397           | exn as FAILURE _ => raise exn
   313           | exn as FAILURE _ => raise exn
   398           | exn => raise FAILURE (state, exn);
   314           | exn => raise FAILURE (state, exn);
   399 
   315 
   400 in
   316 in
   626 
   542 
   627 fun status tr m =
   543 fun status tr m =
   628   setmp_thread_position tr (fn () => Output.status (Markup.markup m "")) ();
   544   setmp_thread_position tr (fn () => Output.status (Markup.markup m "")) ();
   629 
   545 
   630 fun error_msg tr exn_info =
   546 fun error_msg tr exn_info =
   631   setmp_thread_position tr (fn () => Output.error_msg (exn_message (EXCURSION_FAIL exn_info))) ();
   547   setmp_thread_position tr (fn () =>
       
   548     Output.error_msg (ML_Compiler.exn_message (EXCURSION_FAIL exn_info))) ();
   632 
   549 
   633 
   550 
   634 (* post-transition hooks *)
   551 (* post-transition hooks *)
   635 
   552 
   636 local val hooks = ref ([]: (transition -> state -> state -> unit) list) in
   553 local val hooks = ref ([]: (transition -> state -> state -> unit) list) in
   669     val ctxt = try context_of st;
   586     val ctxt = try context_of st;
   670     val res =
   587     val res =
   671       (case app int tr st of
   588       (case app int tr st of
   672         (_, SOME TERMINATE) => NONE
   589         (_, SOME TERMINATE) => NONE
   673       | (st', SOME (EXCURSION_FAIL exn_info)) => SOME (st', SOME exn_info)
   590       | (st', SOME (EXCURSION_FAIL exn_info)) => SOME (st', SOME exn_info)
   674       | (st', SOME exn) => SOME (st', SOME (exn_context ctxt exn, at_command tr))
   591       | (st', SOME exn) => SOME (st', SOME (Runtime.exn_context ctxt exn, at_command tr))
   675       | (st', NONE) => SOME (st', NONE));
   592       | (st', NONE) => SOME (st', NONE));
   676     val _ = (case res of SOME (st', NONE) => apply_hooks st' | _ => ());
   593     val _ = (case res of SOME (st', NONE) => apply_hooks st' | _ => ());
   677   in res end;
   594   in res end;
   678 
   595 
   679 end;
   596 end;