src/Pure/goal.ML
changeset 49061 7449b804073b
parent 49041 9edfd36a0355
child 49829 2bc5924b117f
--- a/src/Pure/goal.ML	Fri Aug 31 22:34:37 2012 +0200
+++ b/src/Pure/goal.ML	Sat Sep 01 19:27:28 2012 +0200
@@ -1,7 +1,7 @@
 (*  Title:      Pure/goal.ML
     Author:     Makarius
 
-Goals in tactical theorem proving.
+Goals in tactical theorem proving, with support for forked proofs.
 *)
 
 signature BASIC_GOAL =
@@ -26,6 +26,8 @@
   val norm_result: thm -> thm
   val fork_name: string -> (unit -> 'a) -> 'a future
   val fork: (unit -> 'a) -> 'a future
+  val peek_futures: serial -> unit future list
+  val cancel_futures: unit -> unit
   val future_enabled_level: int -> bool
   val future_enabled: unit -> bool
   val future_enabled_nested: int -> bool
@@ -109,25 +111,42 @@
 
 (* forked proofs *)
 
-val forked_proofs = Synchronized.var "forked_proofs" 0;
+local
 
-fun forked i =
-  Synchronized.change forked_proofs (fn m =>
+val forked_proofs =
+  Synchronized.var "forked_proofs"
+    (0, []: Future.group list, Inttab.empty: unit future list Inttab.table);
+
+fun count_forked i =
+  Synchronized.change forked_proofs (fn (m, groups, tab) =>
     let
       val n = m + i;
       val _ =
         Multithreading.tracing 2 (fn () =>
           ("PROOFS " ^ Time.toString (Time.now ()) ^ ": " ^ string_of_int n));
-    in n end);
+    in (n, groups, tab) end);
+
+fun register_forked id future =
+  Synchronized.change forked_proofs (fn (m, groups, tab) =>
+    let
+      val groups' = Task_Queue.group_of_task (Future.task_of future) :: groups;
+      val tab' = Inttab.cons_list (id, Future.map (K ()) future) tab;
+    in (m, groups', tab') end);
 
 fun status task markups =
   let val props = Markup.properties [(Isabelle_Markup.taskN, Task_Queue.str_of_task task)]
   in Output.status (implode (map (Markup.markup_only o props) markups)) end;
 
+in
+
 fun fork_name name e =
   uninterruptible (fn _ => fn () =>
     let
-      val _ = forked 1;
+      val id =
+        (case Position.get_id (Position.thread_data ()) of
+          NONE => 0
+        | SOME id => Markup.parse_int id);
+      val _ = count_forked 1;
       val future =
         (singleton o Future.forks)
           {name = name, group = NONE, deps = [], pri = ~1, interrupts = false}
@@ -144,12 +163,25 @@
                     (status task [Isabelle_Markup.failed];
                      Output.report (Markup.markup_only Isabelle_Markup.bad);
                      Output.error_msg (ML_Compiler.exn_message exn)));
+              val _ = count_forked ~1;
             in Exn.release result end);
       val _ = status (Future.task_of future) [Isabelle_Markup.forked];
+      val _ = register_forked id future;
     in future end) ();
 
 fun fork e = fork_name "Goal.fork" e;
 
+fun forked_count () = #1 (Synchronized.value forked_proofs);
+
+fun peek_futures id =
+  Inttab.lookup_list (#3 (Synchronized.value forked_proofs)) id;
+
+fun cancel_futures () =
+  Synchronized.change forked_proofs (fn (m, groups, tab) =>
+    (List.app Future.cancel_group groups; (0, [], Inttab.empty)));
+
+end;
+
 
 (* scheduling parameters *)
 
@@ -164,8 +196,7 @@
 
 fun future_enabled_nested n =
   future_enabled_level n andalso
-  Synchronized.value forked_proofs <
-    ! parallel_proofs_threshold * Multithreading.max_threads_value ();
+  forked_count () < ! parallel_proofs_threshold * Multithreading.max_threads_value ();
 
 
 (* future_result *)