src/Pure/Isar/toplevel.ML
changeset 26602 5534b6a6b810
parent 26491 c93ff30790fe
child 26621 78b3ad7af5d5
equal deleted inserted replaced
26601:d5ae46a8a716 26602:5534b6a6b810
     1 (*  Title:      Pure/Isar/toplevel.ML
     1 (*  Title:      Pure/Isar/toplevel.ML
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Markus Wenzel, TU Muenchen
     3     Author:     Markus Wenzel, TU Muenchen
     4 
     4 
     5 The Isabelle/Isar toplevel.
     5 Isabelle/Isar toplevel transactions.
     6 *)
     6 *)
     7 
     7 
     8 signature TOPLEVEL =
     8 signature TOPLEVEL =
     9 sig
     9 sig
    10   exception UNDEF
    10   exception UNDEF
    13   val theory_node: node -> generic_theory option
    13   val theory_node: node -> generic_theory option
    14   val proof_node: node -> ProofHistory.T option
    14   val proof_node: node -> ProofHistory.T option
    15   val cases_node: (generic_theory -> 'a) -> (Proof.state -> 'a) -> node -> 'a
    15   val cases_node: (generic_theory -> 'a) -> (Proof.state -> 'a) -> node -> 'a
    16   val presentation_context: node option -> xstring option -> Proof.context
    16   val presentation_context: node option -> xstring option -> Proof.context
    17   type state
    17   type state
       
    18   val toplevel: state
    18   val is_toplevel: state -> bool
    19   val is_toplevel: state -> bool
    19   val is_theory: state -> bool
    20   val is_theory: state -> bool
    20   val is_proof: state -> bool
    21   val is_proof: state -> bool
    21   val level: state -> int
    22   val level: state -> int
    22   val node_history_of: state -> node History.T
    23   val node_history_of: state -> node History.T
    34   val debug: bool ref
    35   val debug: bool ref
    35   val interact: bool ref
    36   val interact: bool ref
    36   val timing: bool ref
    37   val timing: bool ref
    37   val profiling: int ref
    38   val profiling: int ref
    38   val skip_proofs: bool ref
    39   val skip_proofs: bool ref
    39   val crashes: exn list ref
       
    40   exception TERMINATE
    40   exception TERMINATE
    41   exception RESTART
    41   exception RESTART
    42   exception CONTEXT of Proof.context * exn
    42   exception CONTEXT of Proof.context * exn
    43   exception TOPLEVEL_ERROR
    43   exception TOPLEVEL_ERROR
    44   val exn_message: exn -> string
    44   val exn_message: exn -> string
    90   val skip_proof: (int History.T -> int History.T) -> transition -> transition
    90   val skip_proof: (int History.T -> int History.T) -> transition -> transition
    91   val skip_proof_to_theory: (int -> bool) -> transition -> transition
    91   val skip_proof_to_theory: (int -> bool) -> transition -> transition
    92   val unknown_theory: transition -> transition
    92   val unknown_theory: transition -> transition
    93   val unknown_proof: transition -> transition
    93   val unknown_proof: transition -> transition
    94   val unknown_context: transition -> transition
    94   val unknown_context: transition -> transition
       
    95   val error_msg: transition -> exn * string -> unit
       
    96   val transition: bool -> transition -> state -> (state * (exn * string) option) option
    95   val present_excursion: (transition * (state -> state -> 'a -> 'a)) list -> 'a -> 'a
    97   val present_excursion: (transition * (state -> state -> 'a -> 'a)) list -> 'a -> 'a
    96   val excursion: transition list -> unit
    98   val excursion: transition list -> unit
    97   val set_state: state -> unit
       
    98   val get_state: unit -> state
       
    99   val exn: unit -> (exn * string) option
       
   100   val >> : transition -> bool
       
   101   val >>> : transition list -> unit
       
   102   val init_state: unit -> unit
       
   103   type 'a isar
       
   104   val loop: bool -> 'a isar -> unit
       
   105 end;
    99 end;
   106 
   100 
   107 structure Toplevel: TOPLEVEL =
   101 structure Toplevel: TOPLEVEL =
   108 struct
   102 struct
   109 
   103 
   238 val debug = Output.debugging;
   232 val debug = Output.debugging;
   239 val interact = ref false;
   233 val interact = ref false;
   240 val timing = Output.timing;
   234 val timing = Output.timing;
   241 val profiling = ref 0;
   235 val profiling = ref 0;
   242 val skip_proofs = ref false;
   236 val skip_proofs = ref false;
   243 val crashes = ref ([]: exn list);
       
   244 
   237 
   245 exception TERMINATE;
   238 exception TERMINATE;
   246 exception RESTART;
   239 exception RESTART;
   247 exception EXCURSION_FAIL of exn * string;
   240 exception EXCURSION_FAIL of exn * string;
   248 exception FAILURE of state * exn;
   241 exception FAILURE of state * exn;
   297       | exn_msg ctxt (THM (msg, i, thms)) = raised ("THM " ^ string_of_int i) (msg ::
   290       | exn_msg ctxt (THM (msg, i, thms)) = raised ("THM " ^ string_of_int i) (msg ::
   298             (if detailed then if_context ctxt ProofContext.string_of_thm thms else []))
   291             (if detailed then if_context ctxt ProofContext.string_of_thm thms else []))
   299       | exn_msg _ exn = raised (General.exnMessage exn) []
   292       | exn_msg _ exn = raised (General.exnMessage exn) []
   300   in exn_msg NONE e end;
   293   in exn_msg NONE e end;
   301 
   294 
   302 fun print_exn exn_info = Output.error_msg (exn_message (EXCURSION_FAIL exn_info));
       
   303 
       
   304 end;
   295 end;
   305 
   296 
   306 
   297 
   307 (* controlled execution *)
   298 (* controlled execution *)
   308 
   299 
   653 (* thread position *)
   644 (* thread position *)
   654 
   645 
   655 fun setmp_thread_position (Transition {pos, ...}) f x =
   646 fun setmp_thread_position (Transition {pos, ...}) f x =
   656   Position.setmp_thread_data pos f x;
   647   Position.setmp_thread_data pos f x;
   657 
   648 
       
   649 fun error_msg tr exn_info =
       
   650   setmp_thread_position tr (fn () => Output.error_msg (exn_message (EXCURSION_FAIL exn_info))) ();
       
   651 
   658 
   652 
   659 (* apply transitions *)
   653 (* apply transitions *)
   660 
   654 
   661 local
   655 local
   662 
   656 
   680 
   674 
   681     in (result, Option.map (fn UNDEF => type_error tr state | exn => exn) status) end);
   675     in (result, Option.map (fn UNDEF => type_error tr state | exn => exn) status) end);
   682 
   676 
   683 in
   677 in
   684 
   678 
   685 fun apply int tr st =
   679 fun transition int tr st =
   686   let val ctxt = try context_of st in
   680   let val ctxt = try context_of st in
   687     (case app int tr st of
   681     (case app int tr st of
   688       (_, SOME TERMINATE) => NONE
   682       (_, SOME TERMINATE) => NONE
   689     | (_, SOME RESTART) => SOME (toplevel, NONE)
   683     | (_, SOME RESTART) => SOME (toplevel, NONE)
   690     | (state', SOME (EXCURSION_FAIL exn_info)) => SOME (state', SOME exn_info)
   684     | (state', SOME (EXCURSION_FAIL exn_info)) => SOME (state', SOME exn_info)
   699 
   693 
   700 local
   694 local
   701 
   695 
   702 fun excur [] x = x
   696 fun excur [] x = x
   703   | excur ((tr, pr) :: trs) (st, res) =
   697   | excur ((tr, pr) :: trs) (st, res) =
   704       (case apply (! interact) tr st of
   698       (case transition (! interact) tr st of
   705         SOME (st', NONE) =>
   699         SOME (st', NONE) =>
   706           excur trs (st', pr st st' res handle exn =>
   700           excur trs (st', pr st st' res handle exn =>
   707             raise EXCURSION_FAIL (exn, "Presentation failed\n" ^ at_command tr))
   701             raise EXCURSION_FAIL (exn, "Presentation failed\n" ^ at_command tr))
   708       | SOME (st', SOME exn_info) => raise EXCURSION_FAIL exn_info
   702       | SOME (st', SOME exn_info) => raise EXCURSION_FAIL exn_info
   709       | NONE => raise EXCURSION_FAIL (TERMINATE, at_command tr));
   703       | NONE => raise EXCURSION_FAIL (TERMINATE, at_command tr));
   720 
   714 
   721 fun excursion trs = present_excursion (map (rpair no_pr) trs) ();
   715 fun excursion trs = present_excursion (map (rpair no_pr) trs) ();
   722 
   716 
   723 end;
   717 end;
   724 
   718 
   725 
   719 end;
   726 
       
   727 (** interactive transformations **)
       
   728 
       
   729 (* the global state reference *)
       
   730 
       
   731 val global_state = ref (toplevel, NONE: (exn * string) option);
       
   732 
       
   733 fun set_state state = global_state := (state, NONE);
       
   734 fun get_state () = fst (! global_state);
       
   735 fun exn () = snd (! global_state);
       
   736 
       
   737 
       
   738 (* apply transformers to global state --- NOT THREAD-SAFE! *)
       
   739 
       
   740 nonfix >> >>>;
       
   741 
       
   742 fun >> tr =
       
   743   (case apply true tr (get_state ()) of
       
   744     NONE => false
       
   745   | SOME (state', exn_info) =>
       
   746       (global_state := (state', exn_info);
       
   747         (case exn_info of
       
   748           NONE => ()
       
   749         | SOME err => setmp_thread_position tr print_exn err);
       
   750         true));
       
   751 
       
   752 fun >>> [] = ()
       
   753   | >>> (tr :: trs) = if >> tr then >>> trs else ();
       
   754 
       
   755 fun init_state () = (>> (init_empty (K true) (K ()) empty); ());
       
   756 
       
   757 
       
   758 (* the Isar source of transitions *)
       
   759 
       
   760 type 'a isar =
       
   761   (transition, (transition option,
       
   762     (OuterLex.token, (OuterLex.token option, (OuterLex.token, (OuterLex.token,
       
   763       Position.T * (Symbol.symbol, (string, 'a) Source.source) Source.source)
       
   764           Source.source) Source.source) Source.source) Source.source) Source.source) Source.source;
       
   765 
       
   766 local
       
   767 
       
   768 (*Spurious interrupts ahead!  Race condition?*)
       
   769 fun get_interrupt src = SOME (Source.get_single src) handle Interrupt => NONE;
       
   770 
       
   771 fun raw_loop secure src =
       
   772   let
       
   773     fun check_secure () =
       
   774       (if secure then warning "Secure loop -- cannot exit to ML" else (); secure);
       
   775   in
       
   776     (case get_interrupt (Source.set_prompt Source.default_prompt src) of
       
   777       NONE => (writeln "\nInterrupt."; raw_loop secure src)
       
   778     | SOME NONE => if secure then quit () else ()
       
   779     | SOME (SOME (tr, src')) => if >> tr orelse check_secure () then raw_loop secure src' else ())
       
   780     handle exn => (Output.error_msg (exn_message exn) handle crash =>
       
   781       (CRITICAL (fn () => change crashes (cons crash));
       
   782         warning "Recovering after Isar toplevel crash -- see also Toplevel.crashes");
       
   783       raw_loop secure src)
       
   784   end;
       
   785 
       
   786 in
       
   787 
       
   788 fun loop secure src = uninterruptible (fn _ => raw_loop secure) src;
       
   789 
       
   790 end;
       
   791 
       
   792 end;