src/Pure/PIDE/document.ML
changeset 52532 c81d76f7f63d
parent 52530 99dd8b4ef3fe
child 52533 a95440dcd59c
equal deleted inserted replaced
52531:21f8e0e151f5 52532:c81d76f7f63d
    29 end;
    29 end;
    30 
    30 
    31 structure Document: DOCUMENT =
    31 structure Document: DOCUMENT =
    32 struct
    32 struct
    33 
    33 
    34 (* command execution *)
       
    35 
       
    36 type exec = Document_ID.exec * (Command.eval * Command.print list);  (*eval/print process*)
       
    37 val no_exec: exec = (Document_ID.none, (Command.no_eval, []));
       
    38 
       
    39 fun exec_ids_of ((exec_id, (_, prints)): exec) = exec_id :: map #exec_id prints;
       
    40 
       
    41 fun exec_result ((_, (eval, _)): exec) = Command.memo_result eval;
       
    42 
       
    43 fun exec_run ((_, (eval, prints)): exec) =
       
    44  (Command.memo_eval eval;
       
    45   prints |> List.app (fn {name, pri, print, ...} =>
       
    46     Command.memo_fork {name = name, group = NONE, deps = [], pri = pri, interrupts = true} print));
       
    47 
       
    48 
       
    49 
       
    50 (** document structure **)
    34 (** document structure **)
    51 
    35 
    52 fun err_dup kind id = error ("Duplicate " ^ kind ^ ": " ^ Document_ID.print id);
    36 fun err_dup kind id = error ("Duplicate " ^ kind ^ ": " ^ Document_ID.print id);
    53 fun err_undef kind id = error ("Undefined " ^ kind ^ ": " ^ Document_ID.print id);
    37 fun err_undef kind id = error ("Undefined " ^ kind ^ ": " ^ Document_ID.print id);
    54 
    38 
    57 structure Entries = Linear_Set(type key = Document_ID.command val ord = int_ord);
    41 structure Entries = Linear_Set(type key = Document_ID.command val ord = int_ord);
    58 
    42 
    59 abstype node = Node of
    43 abstype node = Node of
    60  {header: node_header,  (*master directory, theory header, errors*)
    44  {header: node_header,  (*master directory, theory header, errors*)
    61   perspective: perspective,  (*visible commands, last visible command*)
    45   perspective: perspective,  (*visible commands, last visible command*)
    62   entries: exec option Entries.T * bool,  (*command entries with excecutions, stable*)
    46   entries: Command.exec option Entries.T * bool,  (*command entries with excecutions, stable*)
    63   result: Command.eval option}  (*result of last execution*)
    47   result: Command.eval option}  (*result of last execution*)
    64 and version = Version of node String_Graph.T  (*development graph wrt. static imports*)
    48 and version = Version of node String_Graph.T  (*development graph wrt. static imports*)
    65 with
    49 with
    66 
    50 
    67 fun make_node (header, perspective, entries, result) =
    51 fun make_node (header, perspective, entries, result) =
   150 fun the_entry node id =
   134 fun the_entry node id =
   151   (case Entries.lookup (get_entries node) id of
   135   (case Entries.lookup (get_entries node) id of
   152     NONE => err_undef "command entry" id
   136     NONE => err_undef "command entry" id
   153   | SOME (exec, _) => exec);
   137   | SOME (exec, _) => exec);
   154 
   138 
   155 fun the_default_entry node (SOME id) = (id, the_default no_exec (the_entry node id))
   139 fun the_default_entry node (SOME id) = (id, the_default Command.no_exec (the_entry node id))
   156   | the_default_entry _ NONE = (Document_ID.none, no_exec);
   140   | the_default_entry _ NONE = (Document_ID.none, Command.no_exec);
   157 
   141 
   158 fun update_entry id exec =
   142 fun update_entry id exec =
   159   map_entries (Entries.update (id, exec));
   143   map_entries (Entries.update (id, exec));
   160 
   144 
   161 fun reset_entry id node =
   145 fun reset_entry id node =
   289             iterate_entries (fn ((_, id), _) =>
   273             iterate_entries (fn ((_, id), _) =>
   290               SOME o Inttab.insert (K true) (id, the_command state id))));
   274               SOME o Inttab.insert (K true) (id, the_command state id))));
   291   in (versions', commands', execution) end);
   275   in (versions', commands', execution) end);
   292 
   276 
   293 
   277 
   294 (* consolidated states *)
       
   295 
       
   296 fun stable_goals exec_id =
       
   297   not (Par_Exn.is_interrupted (Future.join_results (Goal.peek_futures exec_id)));
       
   298 
       
   299 fun stable_eval ((exec_id, (eval, _)): exec) =
       
   300   stable_goals exec_id andalso Command.memo_stable eval;
       
   301 
       
   302 fun stable_print ({exec_id, print, ...}: Command.print) =
       
   303   stable_goals exec_id andalso Command.memo_stable print;
       
   304 
       
   305 fun finished_theory node =
   278 fun finished_theory node =
   306   (case Exn.capture (Command.memo_result o the) (get_result node) of
   279   (case Exn.capture (Command.memo_result o the) (get_result node) of
   307     Exn.Res {state = st, ...} => can (Toplevel.end_theory Position.none) st
   280     Exn.Res {state = st, ...} => can (Toplevel.end_theory Position.none) st
   308   | _ => false);
   281   | _ => false);
   309 
   282 
   332                   {name = "theory:" ^ name, group = SOME (Future.new_group (SOME group)),
   305                   {name = "theory:" ^ name, group = SOME (Future.new_group (SOME group)),
   333                     deps = map (Future.task_of o #2) deps, pri = ~2, interrupts = false}
   306                     deps = map (Future.task_of o #2) deps, pri = ~2, interrupts = false}
   334                   (fn () =>
   307                   (fn () =>
   335                     iterate_entries (fn (_, opt_exec) => fn () =>
   308                     iterate_entries (fn (_, opt_exec) => fn () =>
   336                       (case opt_exec of
   309                       (case opt_exec of
   337                         SOME exec => if ! running then SOME (exec_run exec) else NONE
   310                         SOME exec => if ! running then SOME (Command.exec_run exec) else NONE
   338                       | NONE => NONE)) node ()))));
   311                       | NONE => NONE)) node ()))));
   339   in () end;
   312   in () end;
   340 
   313 
   341 
   314 
   342 
   315 
   404             (case opt_exec of
   377             (case opt_exec of
   405               NONE => false
   378               NONE => false
   406             | SOME (exec_id, exec) =>
   379             | SOME (exec_id, exec) =>
   407                 (case lookup_entry node0 id of
   380                 (case lookup_entry node0 id of
   408                   NONE => false
   381                   NONE => false
   409                 | SOME (exec_id0, _) => exec_id = exec_id0 andalso stable_eval (exec_id, exec)));
   382                 | SOME (exec_id0, _) =>
       
   383                     exec_id = exec_id0 andalso Command.stable_eval (exec_id, exec)));
   410         in SOME (same', (prev, flags')) end
   384         in SOME (same', (prev, flags')) end
   411       else NONE;
   385       else NONE;
   412     val (same, (common, flags)) =
   386     val (same, (common, flags)) =
   413       iterate_entries get_common node (true, (NONE, (true, true)));
   387       iterate_entries get_common node (true, (NONE, (true, true)));
   414   in
   388   in
   432 
   406 
   433       val exec_id' = Document_ID.make ();
   407       val exec_id' = Document_ID.make ();
   434       val eval' =
   408       val eval' =
   435         Command.memo (fn () =>
   409         Command.memo (fn () =>
   436           let
   410           let
   437             val eval_state = exec_result (snd command_exec);
   411             val eval_state = Command.exec_result (snd command_exec);
   438             val tr =
   412             val tr =
   439               Position.setmp_thread_data (Position.id_only (Document_ID.print exec_id'))
   413               Position.setmp_thread_data (Position.id_only (Document_ID.print exec_id'))
   440                 (fn () =>
   414                 (fn () =>
   441                   Command.read span
   415                   Command.read span
   442                   |> modify_init
   416                   |> modify_init
   453         val (command_name, _) = the_command state command_id;
   427         val (command_name, _) = the_command state command_id;
   454         val new_prints = Command.print command_name eval;
   428         val new_prints = Command.print command_name eval;
   455         val prints' =
   429         val prints' =
   456           new_prints |> map (fn new_print =>
   430           new_prints |> map (fn new_print =>
   457             (case find_first (fn {name, ...} => name = #name new_print) prints of
   431             (case find_first (fn {name, ...} => name = #name new_print) prints of
   458               SOME print => if stable_print print then print else new_print
   432               SOME print => if Command.stable_print print then print else new_print
   459             | NONE => new_print));
   433             | NONE => new_print));
   460       in
   434       in
   461         if eq_list (op = o pairself #exec_id) (prints, prints') then NONE
   435         if eq_list (op = o pairself #exec_id) (prints, prints') then NONE
   462         else SOME (command_id, (exec_id, (eval, prints')))
   436         else SOME (command_id, (exec_id, (eval, prints')))
   463       end
   437       end
   546               end))
   520               end))
   547       |> Future.joins |> map #1);
   521       |> Future.joins |> map #1);
   548 
   522 
   549     val command_execs =
   523     val command_execs =
   550       map (rpair []) (maps #1 updated) @
   524       map (rpair []) (maps #1 updated) @
   551       map (fn (command_id, exec) => (command_id, exec_ids_of exec)) (maps #2 updated);
   525       map (fn (command_id, exec) => (command_id, Command.exec_ids exec)) (maps #2 updated);
   552     val updated_nodes = map_filter #3 updated;
   526     val updated_nodes = map_filter #3 updated;
   553 
   527 
   554     val state' = state
   528     val state' = state
   555       |> define_version new_id (fold put_node updated_nodes new_version);
   529       |> define_version new_id (fold put_node updated_nodes new_version);
   556   in (command_execs, state') end;
   530   in (command_execs, state') end;