identify future results more carefully, to avoid odd duplication of error messages, notably from forked goals;
authorwenzelm
Wed, 16 Jan 2013 20:41:29 +0100
changeset 51929fe4714886d92
parent 51928 697e3bb60a3b
child 51930 12de8ea66f54
identify future results more carefully, to avoid odd duplication of error messages, notably from forked goals;
src/Pure/Concurrent/future.ML
src/Pure/Isar/runtime.ML
src/Pure/ML/ml_compiler.ML
src/Pure/ML/ml_compiler_polyml.ML
src/Pure/PIDE/command.ML
src/Pure/PIDE/markup.ML
src/Pure/goal.ML
     1.1 --- a/src/Pure/Concurrent/future.ML	Wed Jan 16 20:40:50 2013 +0100
     1.2 +++ b/src/Pure/Concurrent/future.ML	Wed Jan 16 20:41:29 2013 +0100
     1.3 @@ -55,6 +55,8 @@
     1.4    val interruptible_task: ('a -> 'b) -> 'a -> 'b
     1.5    val cancel_group: group -> unit
     1.6    val cancel: 'a future -> unit
     1.7 +  val error_msg: Position.T -> (serial * string) * string option -> unit
     1.8 +  val identify_result: Position.T -> 'a Exn.result -> 'a Exn.result
     1.9    type params = {name: string, group: group option, deps: task list, pri: int, interrupts: bool}
    1.10    val default_params: params
    1.11    val forks: params -> (unit -> 'a) list -> 'a future list
    1.12 @@ -433,14 +435,24 @@
    1.13  fun cancel x = cancel_group (Task_Queue.group_of_task (task_of x));
    1.14  
    1.15  
    1.16 -(* future jobs *)
    1.17 +(* results *)
    1.18  
    1.19 -fun assign_result group result raw_res =
    1.20 +fun error_msg pos ((serial, msg), exec_id) =
    1.21 +  if is_none exec_id orelse exec_id = Position.get_id pos
    1.22 +  then Output.error_msg' (serial, msg) else warning msg;
    1.23 +
    1.24 +fun identify_result pos res =
    1.25 +  (case res of
    1.26 +    Exn.Exn exn =>
    1.27 +      let val exec_id =
    1.28 +        (case Position.get_id pos of
    1.29 +          NONE => []
    1.30 +        | SOME id => [(Markup.exec_idN, id)])
    1.31 +      in Exn.Exn (Par_Exn.identify exec_id exn) end
    1.32 +  | _ => res);
    1.33 +
    1.34 +fun assign_result group result res =
    1.35    let
    1.36 -    val res =
    1.37 -      (case raw_res of
    1.38 -        Exn.Exn exn => Exn.Exn (Par_Exn.identify [] exn)
    1.39 -      | _ => raw_res);
    1.40      val _ = Single_Assignment.assign result res
    1.41        handle exn as Fail _ =>
    1.42          (case Single_Assignment.peek result of
    1.43 @@ -453,6 +465,9 @@
    1.44        | Exn.Res _ => true);
    1.45    in ok end;
    1.46  
    1.47 +
    1.48 +(* future jobs *)
    1.49 +
    1.50  fun future_job group interrupts (e: unit -> 'a) =
    1.51    let
    1.52      val result = Single_Assignment.var "future" : 'a result;
    1.53 @@ -467,7 +482,7 @@
    1.54                   then Multithreading.private_interrupts else Multithreading.no_interrupts)
    1.55                  (fn _ => Position.setmp_thread_data pos e ())) ()
    1.56            else Exn.interrupt_exn;
    1.57 -      in assign_result group result res end;
    1.58 +      in assign_result group result (identify_result pos res) end;
    1.59    in (result, job) end;
    1.60  
    1.61  
    1.62 @@ -563,7 +578,7 @@
    1.63      val task = Task_Queue.dummy_task;
    1.64      val group = Task_Queue.group_of_task task;
    1.65      val result = Single_Assignment.var "value" : 'a result;
    1.66 -    val _ = assign_result group result res;
    1.67 +    val _ = assign_result group result (identify_result (Position.thread_data ()) res);
    1.68    in Future {promised = false, task = task, result = result} end;
    1.69  
    1.70  fun value x = value_result (Exn.Res x);
    1.71 @@ -619,7 +634,9 @@
    1.72    else
    1.73      let
    1.74        val group = Task_Queue.group_of_task task;
    1.75 -      fun job ok = assign_result group result (if ok then res else Exn.interrupt_exn);
    1.76 +      val pos = Position.thread_data ();
    1.77 +      fun job ok =
    1.78 +        assign_result group result (if ok then identify_result pos res else Exn.interrupt_exn);
    1.79        val _ =
    1.80          Multithreading.with_attributes Multithreading.no_interrupts (fn _ =>
    1.81            let
     2.1 --- a/src/Pure/Isar/runtime.ML	Wed Jan 16 20:40:50 2013 +0100
     2.2 +++ b/src/Pure/Isar/runtime.ML	Wed Jan 16 20:41:29 2013 +0100
     2.3 @@ -12,6 +12,7 @@
     2.4    exception TOPLEVEL_ERROR
     2.5    val debug: bool Unsynchronized.ref
     2.6    val exn_context: Proof.context option -> exn -> exn
     2.7 +  val exn_messages_ids: (exn -> Position.T) -> exn -> ((serial * string) * string option) list
     2.8    val exn_messages: (exn -> Position.T) -> exn -> (serial * string) list
     2.9    val exn_message: (exn -> Position.T) -> exn -> string
    2.10    val debugging: ('a -> 'b) -> 'a -> 'b
    2.11 @@ -42,22 +43,28 @@
    2.12  
    2.13  (* exn_message *)
    2.14  
    2.15 +local
    2.16 +
    2.17  fun if_context NONE _ _ = []
    2.18    | if_context (SOME ctxt) f xs = map (f ctxt) xs;
    2.19  
    2.20 -fun exn_messages exn_position e =
    2.21 +fun identify exn =
    2.22    let
    2.23 -    fun identify exn =
    2.24 -      let val exn' = Par_Exn.identify [] exn
    2.25 -      in (Par_Exn.the_serial exn', exn') end;
    2.26 +    val exn' = Par_Exn.identify [] exn;
    2.27 +    val exec_id = Properties.get (Exn_Properties.get exn') Markup.exec_idN;
    2.28 +  in ((Par_Exn.the_serial exn', exn'), exec_id) end;
    2.29  
    2.30 -    fun flatten _ (CONTEXT (ctxt, exn)) = flatten (SOME ctxt) exn
    2.31 -      | flatten context (Exn.EXCEPTIONS exns) = maps (flatten context) exns
    2.32 -      | flatten context exn =
    2.33 -          (case Par_Exn.dest exn of
    2.34 -            SOME exns => maps (flatten context) exns
    2.35 -          | NONE => [(context, identify exn)]);
    2.36 +fun flatten _ (CONTEXT (ctxt, exn)) = flatten (SOME ctxt) exn
    2.37 +  | flatten context (Exn.EXCEPTIONS exns) = maps (flatten context) exns
    2.38 +  | flatten context exn =
    2.39 +      (case Par_Exn.dest exn of
    2.40 +        SOME exns => maps (flatten context) exns
    2.41 +      | NONE => [(context, identify exn)]);
    2.42  
    2.43 +in
    2.44 +
    2.45 +fun exn_messages_ids exn_position e =
    2.46 +  let
    2.47      fun raised exn name msgs =
    2.48        let val pos = Position.here (exn_position exn) in
    2.49          (case msgs of
    2.50 @@ -66,10 +73,10 @@
    2.51          | _ => cat_lines (("exception " ^ name ^ " raised" ^ pos ^ ":") :: msgs))
    2.52        end;
    2.53  
    2.54 -    fun exn_msgs (context, (i, exn)) =
    2.55 +    fun exn_msgs (context, ((i, exn), id)) =
    2.56        (case exn of
    2.57          EXCURSION_FAIL (exn, loc) =>
    2.58 -          map (apsnd (fn msg => msg ^ Markup.markup Markup.no_report ("\n" ^ loc)))
    2.59 +          map (fn ((i, msg), id) => ((i, msg ^ Markup.markup Markup.no_report ("\n" ^ loc)), id))
    2.60              (sorted_msgs context exn)
    2.61        | _ =>
    2.62          let
    2.63 @@ -94,12 +101,17 @@
    2.64                  raised exn ("THM " ^ string_of_int i)
    2.65                    (msg :: if_context context Display.string_of_thm thms)
    2.66              | _ => raised exn (General.exnMessage exn) []);
    2.67 -        in [(i, msg)] end)
    2.68 +        in [((i, msg), id)] end)
    2.69        and sorted_msgs context exn =
    2.70 -        sort_distinct (int_ord o pairself fst) (maps exn_msgs (flatten context exn));
    2.71 +        sort_distinct (int_ord o pairself (fst o fst)) (maps exn_msgs (flatten context exn));
    2.72  
    2.73    in sorted_msgs NONE e end;
    2.74  
    2.75 +end;
    2.76 +
    2.77 +fun exn_messages exn_position exn =
    2.78 +  map #1 (exn_messages_ids exn_position exn);
    2.79 +
    2.80  fun exn_message exn_position exn =
    2.81    (case exn_messages exn_position exn of
    2.82      [] => "Interrupt"
     3.1 --- a/src/Pure/ML/ml_compiler.ML	Wed Jan 16 20:40:50 2013 +0100
     3.2 +++ b/src/Pure/ML/ml_compiler.ML	Wed Jan 16 20:41:29 2013 +0100
     3.3 @@ -7,6 +7,7 @@
     3.4  signature ML_COMPILER =
     3.5  sig
     3.6    val exn_position: exn -> Position.T
     3.7 +  val exn_messages_ids: exn -> ((serial * string) * string option) list
     3.8    val exn_messages: exn -> (serial * string) list
     3.9    val exn_message: exn -> string
    3.10    val eval: bool -> Position.T -> ML_Lex.token list -> unit
    3.11 @@ -16,6 +17,7 @@
    3.12  struct
    3.13  
    3.14  fun exn_position _ = Position.none;
    3.15 +val exn_messages_ids = Runtime.exn_messages_ids exn_position;
    3.16  val exn_messages = Runtime.exn_messages exn_position;
    3.17  val exn_message = Runtime.exn_message exn_position;
    3.18  
     4.1 --- a/src/Pure/ML/ml_compiler_polyml.ML	Wed Jan 16 20:40:50 2013 +0100
     4.2 +++ b/src/Pure/ML/ml_compiler_polyml.ML	Wed Jan 16 20:41:29 2013 +0100
     4.3 @@ -22,6 +22,7 @@
     4.4      NONE => Position.none
     4.5    | SOME loc => position_of loc);
     4.6  
     4.7 +val exn_messages_ids = Runtime.exn_messages_ids exn_position;
     4.8  val exn_messages = Runtime.exn_messages exn_position;
     4.9  val exn_message = Runtime.exn_message exn_position;
    4.10  
     5.1 --- a/src/Pure/PIDE/command.ML	Wed Jan 16 20:40:50 2013 +0100
     5.2 +++ b/src/Pure/PIDE/command.ML	Wed Jan 16 20:41:29 2013 +0100
     5.3 @@ -64,15 +64,15 @@
     5.4  fun run int tr st =
     5.5    (case Toplevel.transition int tr st of
     5.6      SOME (st', NONE) => ([], SOME st')
     5.7 -  | SOME (_, SOME (exn, _)) => (ML_Compiler.exn_messages exn, NONE)
     5.8 -  | NONE => (ML_Compiler.exn_messages Runtime.TERMINATE, NONE));
     5.9 +  | SOME (_, SOME (exn, _)) => (ML_Compiler.exn_messages_ids exn, NONE)
    5.10 +  | NONE => (ML_Compiler.exn_messages_ids Runtime.TERMINATE, NONE));
    5.11  
    5.12  fun check_cmts tr cmts st =
    5.13    Toplevel.setmp_thread_position tr
    5.14      (fn () => cmts
    5.15        |> maps (fn cmt =>
    5.16          (Thy_Output.check_text (Token.source_position_of cmt) st; [])
    5.17 -          handle exn => ML_Compiler.exn_messages exn)) ();
    5.18 +          handle exn => ML_Compiler.exn_messages_ids exn)) ();
    5.19  
    5.20  fun timing tr t =
    5.21    if Timing.is_relevant t then Toplevel.status tr (Markup.timing t) else ();
    5.22 @@ -106,7 +106,7 @@
    5.23        val errs = errs1 @ errs2;
    5.24        val _ = timing tr (Timing.result start);
    5.25        val _ = Toplevel.status tr Markup.finished;
    5.26 -      val _ = List.app (Toplevel.error_msg tr) errs;
    5.27 +      val _ = List.app (Future.error_msg (Toplevel.pos_of tr)) errs;
    5.28      in
    5.29        (case result of
    5.30          NONE =>
     6.1 --- a/src/Pure/PIDE/markup.ML	Wed Jan 16 20:40:50 2013 +0100
     6.2 +++ b/src/Pure/PIDE/markup.ML	Wed Jan 16 20:41:29 2013 +0100
     6.3 @@ -107,6 +107,7 @@
     6.4    val finishedN: string val finished: T
     6.5    val failedN: string val failed: T
     6.6    val serialN: string
     6.7 +  val exec_idN: string
     6.8    val initN: string
     6.9    val statusN: string
    6.10    val resultN: string
    6.11 @@ -364,6 +365,7 @@
    6.12  (* messages *)
    6.13  
    6.14  val serialN = "serial";
    6.15 +val exec_idN = "exec_id";
    6.16  
    6.17  val initN = "init";
    6.18  val statusN = "status";
     7.1 --- a/src/Pure/goal.ML	Wed Jan 16 20:40:50 2013 +0100
     7.2 +++ b/src/Pure/goal.ML	Wed Jan 16 20:41:29 2013 +0100
     7.3 @@ -137,8 +137,10 @@
     7.4  fun fork_name name e =
     7.5    uninterruptible (fn _ => fn () =>
     7.6      let
     7.7 -      val id = the_default 0 (Position.parse_id (Position.thread_data ()));
     7.8 +      val pos = Position.thread_data ();
     7.9 +      val id = the_default 0 (Position.parse_id pos);
    7.10        val _ = count_forked 1;
    7.11 +
    7.12        val future =
    7.13          (singleton o Future.forks)
    7.14            {name = name, group = NONE, deps = [], pri = ~1, interrupts = false}
    7.15 @@ -146,7 +148,9 @@
    7.16              let
    7.17                val task = the (Future.worker_task ());
    7.18                val _ = status task [Markup.running];
    7.19 -              val result = Exn.capture (Future.interruptible_task e) ();
    7.20 +              val result =
    7.21 +                Exn.capture (Future.interruptible_task e) ()
    7.22 +                |> Future.identify_result pos;
    7.23                val _ = status task [Markup.finished, Markup.joined];
    7.24                val _ =
    7.25                  (case result of
    7.26 @@ -156,7 +160,7 @@
    7.27                      else
    7.28                        (status task [Markup.failed];
    7.29                         Output.report (Markup.markup_only Markup.bad);
    7.30 -                       Output.error_msg (ML_Compiler.exn_message exn)));
    7.31 +                       List.app (Future.error_msg pos) (ML_Compiler.exn_messages_ids exn)));
    7.32                val _ = count_forked ~1;
    7.33              in Exn.release result end);
    7.34        val _ = status (Future.task_of future) [Markup.forked];