464 |
464 |
465 fun check_theory full name node = |
465 fun check_theory full name node = |
466 is_some (loaded_theory name) orelse |
466 is_some (loaded_theory name) orelse |
467 can get_header node andalso (not full orelse is_some (get_result node)); |
467 can get_header node andalso (not full orelse is_some (get_result node)); |
468 |
468 |
469 fun last_common state node_required node0 node = |
469 fun last_common keywords state node_required node0 node = |
470 let |
470 let |
471 fun update_flags prev (visible, initial) = |
471 fun update_flags prev (visible, initial) = |
472 let |
472 let |
473 val visible' = visible andalso prev <> visible_last node; |
473 val visible' = visible andalso prev <> visible_last node; |
474 val initial' = initial andalso |
474 val initial' = initial andalso |
475 (case prev of |
475 (case prev of |
476 NONE => true |
476 NONE => true |
477 | SOME command_id => not (Keyword.is_theory_begin (the_command_name state command_id))); |
477 | SOME command_id => |
|
478 not (Keyword.is_theory_begin keywords (the_command_name state command_id))); |
478 in (visible', initial') end; |
479 in (visible', initial') end; |
479 |
480 |
480 fun get_common ((prev, command_id), opt_exec) (_, ok, flags, assign_update) = |
481 fun get_common ((prev, command_id), opt_exec) (_, ok, flags, assign_update) = |
481 if ok then |
482 if ok then |
482 let |
483 let |
493 let |
494 let |
494 val command_visible = visible_command node command_id; |
495 val command_visible = visible_command node command_id; |
495 val command_overlays = overlays node command_id; |
496 val command_overlays = overlays node command_id; |
496 val command_name = the_command_name state command_id; |
497 val command_name = the_command_name state command_id; |
497 in |
498 in |
498 (case Command.print command_visible command_overlays command_name eval prints of |
499 (case |
|
500 Command.print command_visible command_overlays keywords command_name eval prints |
|
501 of |
499 SOME prints' => assign_update_new (command_id, SOME (eval, prints')) |
502 SOME prints' => assign_update_new (command_id, SOME (eval, prints')) |
500 | NONE => I) |
503 | NONE => I) |
501 end |
504 end |
502 | NONE => I); |
505 | NONE => I); |
503 in SOME (prev, ok', flags', assign_update') end |
506 in SOME (prev, ok', flags', assign_update') end |
511 else (common, flags); |
514 else (common, flags); |
512 in (assign_update', common', flags') end; |
515 in (assign_update', common', flags') end; |
513 |
516 |
514 fun illegal_init _ = error "Illegal theory header after end of theory"; |
517 fun illegal_init _ = error "Illegal theory header after end of theory"; |
515 |
518 |
516 fun new_exec state node proper_init command_id' (assign_update, command_exec, init) = |
519 fun new_exec keywords state node proper_init command_id' (assign_update, command_exec, init) = |
517 if not proper_init andalso is_none init then NONE |
520 if not proper_init andalso is_none init then NONE |
518 else |
521 else |
519 let |
522 let |
520 val (_, (eval, _)) = command_exec; |
523 val (_, (eval, _)) = command_exec; |
521 |
524 |
524 val (command_name, blob_digests, span0) = the_command state command_id'; |
527 val (command_name, blob_digests, span0) = the_command state command_id'; |
525 val blobs = map (resolve_blob state) blob_digests; |
528 val blobs = map (resolve_blob state) blob_digests; |
526 val span = Lazy.force span0; |
529 val span = Lazy.force span0; |
527 |
530 |
528 val eval' = |
531 val eval' = |
529 Command.eval (fn () => the_default illegal_init init span) |
532 Command.eval keywords (master_directory node) |
530 (master_directory node) blobs span eval; |
533 (fn () => the_default illegal_init init span) blobs span eval; |
531 val prints' = perhaps (Command.print command_visible command_overlays command_name eval') []; |
534 val prints' = |
|
535 perhaps (Command.print command_visible command_overlays keywords command_name eval') []; |
532 val exec' = (eval', prints'); |
536 val exec' = (eval', prints'); |
533 |
537 |
534 val assign_update' = assign_update_new (command_id', SOME exec') assign_update; |
538 val assign_update' = assign_update_new (command_id', SOME exec') assign_update; |
535 val init' = if Keyword.is_theory_begin command_name then NONE else init; |
539 val init' = if Keyword.is_theory_begin keywords command_name then NONE else init; |
536 in SOME (assign_update', (command_id', (eval', prints')), init') end; |
540 in SOME (assign_update', (command_id', (eval', prints')), init') end; |
537 |
541 |
538 fun removed_execs node0 (command_id, exec_ids) = |
542 fun removed_execs node0 (command_id, exec_ids) = |
539 subtract (op =) exec_ids (Command.exec_ids (lookup_entry node0 command_id)); |
543 subtract (op =) exec_ids (Command.exec_ids (lookup_entry node0 command_id)); |
540 |
544 |
556 (singleton o Future.forks) |
560 (singleton o Future.forks) |
557 {name = "Document.update", group = NONE, |
561 {name = "Document.update", group = NONE, |
558 deps = map (Future.task_of o #2) deps, pri = 1, interrupts = false} |
562 deps = map (Future.task_of o #2) deps, pri = 1, interrupts = false} |
559 (fn () => timeit ("Document.update " ^ name) (fn () => |
563 (fn () => timeit ("Document.update " ^ name) (fn () => |
560 let |
564 let |
|
565 val keywords = Keyword.get_keywords (); |
561 val imports = map (apsnd Future.join) deps; |
566 val imports = map (apsnd Future.join) deps; |
562 val imports_result_changed = exists (#4 o #1 o #2) imports; |
567 val imports_result_changed = exists (#4 o #1 o #2) imports; |
563 val node_required = Symtab.defined required name; |
568 val node_required = Symtab.defined required name; |
564 in |
569 in |
565 if Symtab.defined edited name orelse visible_node node orelse |
570 if Symtab.defined edited name orelse visible_node node orelse |
572 check_theory false name node andalso |
577 check_theory false name node andalso |
573 forall (fn (name, (_, node)) => check_theory true name node) imports; |
578 forall (fn (name, (_, node)) => check_theory true name node) imports; |
574 |
579 |
575 val (print_execs, common, (still_visible, initial)) = |
580 val (print_execs, common, (still_visible, initial)) = |
576 if imports_result_changed then (assign_update_empty, NONE, (true, true)) |
581 if imports_result_changed then (assign_update_empty, NONE, (true, true)) |
577 else last_common state node_required node0 node; |
582 else last_common keywords state node_required node0 node; |
578 val common_command_exec = the_default_entry node common; |
583 val common_command_exec = the_default_entry node common; |
579 |
584 |
580 val (updated_execs, (command_id', (eval', _)), _) = |
585 val (updated_execs, (command_id', (eval', _)), _) = |
581 (print_execs, common_command_exec, if initial then SOME init else NONE) |
586 (print_execs, common_command_exec, if initial then SOME init else NONE) |
582 |> (still_visible orelse node_required) ? |
587 |> (still_visible orelse node_required) ? |
583 iterate_entries_after common |
588 iterate_entries_after common |
584 (fn ((prev, id), _) => fn res => |
589 (fn ((prev, id), _) => fn res => |
585 if not node_required andalso prev = visible_last node then NONE |
590 if not node_required andalso prev = visible_last node then NONE |
586 else new_exec state node proper_init id res) node; |
591 else new_exec keywords state node proper_init id res) node; |
587 |
592 |
588 val assigned_execs = |
593 val assigned_execs = |
589 (node0, updated_execs) |-> iterate_entries_after common |
594 (node0, updated_execs) |-> iterate_entries_after common |
590 (fn ((_, command_id0), exec0) => fn res => |
595 (fn ((_, command_id0), exec0) => fn res => |
591 if is_none exec0 then NONE |
596 if is_none exec0 then NONE |