src/Pure/PIDE/document.ML
changeset 47407 8da23ecc70cd
parent 47406 8818f54773cc
child 47415 c486ac962b89
equal deleted inserted replaced
47406:8818f54773cc 47407:8da23ecc70cd
    57 
    57 
    58 
    58 
    59 (** document structure **)
    59 (** document structure **)
    60 
    60 
    61 type node_header = (string * Thy_Header.header) Exn.result;
    61 type node_header = (string * Thy_Header.header) Exn.result;
    62 type perspective = (command_id -> bool) * command_id option; (*visible commands, last*)
    62 type perspective = (command_id -> bool) * command_id option;
    63 structure Entries = Linear_Set(type key = command_id val ord = int_ord);
    63 structure Entries = Linear_Set(type key = command_id val ord = int_ord);
    64 
    64 
    65 type exec = (Toplevel.state * unit lazy) Command.memo;  (*eval/print process*)
    65 type exec = (Toplevel.state * unit lazy) Command.memo;  (*eval/print process*)
    66 val no_exec = Command.memo_value (Toplevel.toplevel, Lazy.value ());
    66 val no_exec = Command.memo_value (Toplevel.toplevel, Lazy.value ());
    67 
    67 
    68 abstype node = Node of
    68 abstype node = Node of
    69  {header: node_header,
    69  {header: node_header,
    70   perspective: perspective,
    70   perspective: perspective,  (*visible commands, last*)
    71   entries: (exec_id * exec) option Entries.T,  (*command entries with excecutions*)
    71   entries: (exec_id * exec) option Entries.T,  (*command entries with excecutions*)
    72   result: exec}
    72   result: exec option}  (*result of last execution*)
    73 and version = Version of node Graph.T  (*development graph wrt. static imports*)
    73 and version = Version of node Graph.T  (*development graph wrt. static imports*)
    74 with
    74 with
    75 
    75 
    76 fun make_node (header, perspective, entries, result) =
    76 fun make_node (header, perspective, entries, result) =
    77   Node {header = header, perspective = perspective, entries = entries, result = result};
    77   Node {header = header, perspective = perspective, entries = entries, result = result};
    83   (Inttab.defined (Inttab.make (map (rpair ()) command_ids)), try List.last command_ids);
    83   (Inttab.defined (Inttab.make (map (rpair ()) command_ids)), try List.last command_ids);
    84 
    84 
    85 val no_header = Exn.Exn (ERROR "Bad theory header");
    85 val no_header = Exn.Exn (ERROR "Bad theory header");
    86 val no_perspective = make_perspective [];
    86 val no_perspective = make_perspective [];
    87 
    87 
    88 val empty_node = make_node (no_header, no_perspective, Entries.empty, no_exec);
    88 val empty_node = make_node (no_header, no_perspective, Entries.empty, NONE);
    89 val clear_node = map_node (fn (header, _, _, _) => (header, no_perspective, Entries.empty, no_exec));
    89 val clear_node = map_node (fn (header, _, _, _) => (header, no_perspective, Entries.empty, NONE));
    90 
    90 
    91 
    91 
    92 (* basic components *)
    92 (* basic components *)
    93 
    93 
    94 fun get_header (Node {header, ...}) = header;
    94 fun get_header (Node {header, ...}) = header;
   279 (* execute *)
   279 (* execute *)
   280 
   280 
   281 local
   281 local
   282 
   282 
   283 fun finished_theory node =
   283 fun finished_theory node =
   284   (case Exn.capture Command.memo_result (get_result node) of
   284   (case Exn.capture (Command.memo_result o the) (get_result node) of
   285     Exn.Res (st, _) => can (Toplevel.end_theory Position.none) st
   285     Exn.Res (st, _) => can (Toplevel.end_theory Position.none) st
   286   | _ => false);
   286   | _ => false);
   287 
   287 
   288 in
   288 in
   289 
   289 
   328 
   328 
   329 local
   329 local
   330 
   330 
   331 fun stable_finished_theory node =
   331 fun stable_finished_theory node =
   332   is_some (Exn.get_res (Exn.capture (fn () =>
   332   is_some (Exn.get_res (Exn.capture (fn () =>
   333     fst (Command.memo_result (get_result node))
   333     fst (Command.memo_result (the (get_result node)))
   334     |> Toplevel.end_theory Position.none
   334     |> Toplevel.end_theory Position.none
   335     |> Global_Theory.join_proofs) ()));
   335     |> Global_Theory.join_proofs) ()));
   336 
   336 
   337 fun stable_command exec =
   337 fun stable_command exec =
   338   (case Exn.capture Command.memo_result exec of
   338   (case Exn.capture Command.memo_result exec of
   363       (case Url.explode dir of
   363       (case Url.explode dir of
   364         Url.File path => path
   364         Url.File path => path
   365       | _ => Path.current);
   365       | _ => Path.current);
   366     val parents =
   366     val parents =
   367       #imports header |> map (fn import =>
   367       #imports header |> map (fn import =>
   368         (case Thy_Info.lookup_theory import of  (* FIXME more robust!? *)
   368         (case Thy_Info.lookup_theory import of
   369           SOME thy => thy
   369           SOME thy => thy
   370         | NONE =>
   370         | NONE =>
   371             Toplevel.end_theory (Position.file_only import)
   371             Toplevel.end_theory (Position.file_only import)
   372               (fst (Command.memo_result
   372               (fst
   373                 (get_result (snd (the (AList.lookup (op =) imports import))))))));
   373                 (Command.memo_result
       
   374                   (the_default no_exec
       
   375                     (get_result (snd (the (AList.lookup (op =) imports import)))))))));
   374   in Thy_Load.begin_theory master_dir header parents end;
   376   in Thy_Load.begin_theory master_dir header parents end;
   375 
   377 
   376 fun check_theory nodes name =
   378 fun check_theory full name node =
   377   is_some (Thy_Info.lookup_theory name) orelse  (* FIXME more robust!? *)
   379   is_some (Thy_Info.lookup_theory name) orelse
   378   is_some (Exn.get_res (get_header (get_node nodes name)));
   380   is_some (Exn.get_res (get_header node)) andalso (not full orelse is_some (get_result node));
   379 
   381 
   380 fun last_common state last_visible node0 node =
   382 fun last_common state last_visible node0 node =
   381   let
   383   let
   382     fun update_flags prev (visible, initial) =
   384     fun update_flags prev (visible, initial) =
   383       let
   385       let
   408       in (last, update_flags last flags) end
   410       in (last, update_flags last flags) end
   409   end;
   411   end;
   410 
   412 
   411 fun illegal_init () = error "Illegal theory header after end of theory";
   413 fun illegal_init () = error "Illegal theory header after end of theory";
   412 
   414 
   413 fun new_exec state bad_init command_id' (execs, command_exec, init) =
   415 fun new_exec state proper_init command_id' (execs, command_exec, init) =
   414   if bad_init andalso is_none init then NONE
   416   if not proper_init andalso is_none init then NONE
   415   else
   417   else
   416     let
   418     let
   417       val (name, span) = the_command state command_id' ||> Lazy.force;
   419       val (name, span) = the_command state command_id' ||> Lazy.force;
   418       val (modify_init, init') =
   420       val (modify_init, init') =
   419         if Keyword.is_theory_begin name then
   421         if Keyword.is_theory_begin name then
   461                   required andalso not (stable_finished_theory node)
   463                   required andalso not (stable_finished_theory node)
   462                 then
   464                 then
   463                   let
   465                   let
   464                     val node0 = node_of old_version name;
   466                     val node0 = node_of old_version name;
   465                     fun init () = init_theory imports node;
   467                     fun init () = init_theory imports node;
   466                     val bad_init =
   468                     val proper_init =
   467                       not (check_theory nodes name andalso forall (check_theory nodes o #1) imports);
   469                       check_theory false name node andalso
       
   470                       forall (fn (name, (_, node)) => check_theory true name node) imports;
   468 
   471 
   469                     val last_visible = visible_last node;
   472                     val last_visible = visible_last node;
   470                     val (common, (visible, initial)) =
   473                     val (common, (visible, initial)) =
   471                       if updated_imports then (NONE, (true, true))
   474                       if updated_imports then (NONE, (true, true))
   472                       else last_common state last_visible node0 node;
   475                       else last_common state last_visible node0 node;
   476                       ([], common_command_exec, if initial then SOME init else NONE) |>
   479                       ([], common_command_exec, if initial then SOME init else NONE) |>
   477                       (visible orelse required) ?
   480                       (visible orelse required) ?
   478                         iterate_entries_after common
   481                         iterate_entries_after common
   479                           (fn ((prev, id), _) => fn res =>
   482                           (fn ((prev, id), _) => fn res =>
   480                             if not required andalso prev = last_visible then NONE
   483                             if not required andalso prev = last_visible then NONE
   481                             else new_exec state bad_init id res) node;
   484                             else new_exec state proper_init id res) node;
   482 
   485 
   483                     val no_execs =
   486                     val no_execs =
   484                       iterate_entries_after common
   487                       iterate_entries_after common
   485                         (fn ((_, id0), exec0) => fn res =>
   488                         (fn ((_, id0), exec0) => fn res =>
   486                           if is_none exec0 then NONE
   489                           if is_none exec0 then NONE
   487                           else if exists (fn (_, (id, _)) => id0 = id) new_execs then SOME res
   490                           else if exists (fn (_, (id, _)) => id0 = id) new_execs then SOME res
   488                           else SOME (id0 :: res)) node0 [];
   491                           else SOME (id0 :: res)) node0 [];
   489 
   492 
   490                     val last_exec = if command_id' = no_id then NONE else SOME command_id';
   493                     val last_exec = if command_id' = no_id then NONE else SOME command_id';
   491                     val result =
   494                     val result =
   492                       if is_some (after_entry node last_exec) then no_exec
   495                       if is_some (after_entry node last_exec) then NONE
   493                       else exec';
   496                       else SOME exec';
   494 
   497 
   495                     val node' = node
   498                     val node' = node
   496                       |> fold reset_entry no_execs
   499                       |> fold reset_entry no_execs
   497                       |> fold (fn (id, exec) => update_entry id (SOME exec)) new_execs
   500                       |> fold (fn (id, exec) => update_entry id (SOME exec)) new_execs
   498                       |> set_result result;
   501                       |> set_result result;