src/Pure/Thy/thy_info.ML
changeset 42003 6e45dc518ebb
parent 41955 703ea96b13c6
child 42129 c17508a61f49
equal deleted inserted replaced
42002:ac7097bd8611 42003:6e45dc518ebb
   230     val _ = Output.urgent_message ("Loading theory " ^ quote name ^ required_by " " initiators);
   230     val _ = Output.urgent_message ("Loading theory " ^ quote name ^ required_by " " initiators);
   231 
   231 
   232     val {master = (thy_path, _), imports} = deps;
   232     val {master = (thy_path, _), imports} = deps;
   233     val dir = Path.dir thy_path;
   233     val dir = Path.dir thy_path;
   234     val pos = Path.position thy_path;
   234     val pos = Path.position thy_path;
   235     val uses = map (apfst Path.explode) (#3 (Thy_Header.read pos text));
   235     val (_, _, uses) = Thy_Header.read pos text;
   236     fun init _ =
   236     fun init _ =
   237       Thy_Load.begin_theory dir name imports parent_thys uses
   237       Thy_Load.begin_theory dir name imports parent_thys uses
   238       |> Present.begin_theory update_time dir uses;
   238       |> Present.begin_theory update_time dir uses;
   239 
   239 
   240     val (after_load, theory) = Outer_Syntax.load_thy name init pos text;
   240     val (after_load, theory) = Outer_Syntax.load_thy name init pos text;
   249 
   249 
   250   in (theory, after_load') end;
   250   in (theory, after_load') end;
   251 
   251 
   252 fun check_deps dir name =
   252 fun check_deps dir name =
   253   (case lookup_deps name of
   253   (case lookup_deps name of
   254     SOME NONE => (true, NONE, get_parents name, NONE)
   254     SOME NONE => (true, NONE, get_parents name)
   255   | NONE =>
   255   | NONE =>
   256       let val {master, text, imports, ...} = Thy_Load.deps_thy dir name
   256       let val {master, text, imports, ...} = Thy_Load.check_thy dir name
   257       in (false, SOME (make_deps master imports), imports, SOME text) end
   257       in (false, SOME (make_deps master imports, text), imports) end
   258   | SOME (SOME {master, imports}) =>
   258   | SOME (SOME {master, imports}) =>
   259       let val master' = Thy_Load.check_thy dir name in
   259       let
   260         if #2 master <> #2 master' then
   260         val {master = master', text = text', imports = imports', ...} = Thy_Load.check_thy dir name;
   261           let val {text = text', imports = imports', ...} = Thy_Load.deps_thy dir name;
   261         val deps' = SOME (make_deps master' imports', text');
   262           in (false, SOME (make_deps master' imports'), imports', SOME text') end
   262         val current =
   263         else
   263           #2 master = #2 master' andalso
   264           let
   264             (case lookup_theory name of
   265             val current =
   265               NONE => false
   266               (case lookup_theory name of
   266             | SOME theory => Thy_Load.all_current theory);
   267                 NONE => false
   267       in (current, deps', imports') end);
   268               | SOME theory => Thy_Load.all_current theory);
       
   269             val deps' = SOME (make_deps master' imports);
       
   270           in (current, deps', imports, NONE) end
       
   271       end);
       
   272 
   268 
   273 in
   269 in
   274 
   270 
   275 fun require_thys initiators dir strs tasks =
   271 fun require_thys initiators dir strs tasks =
   276       fold_map (require_thy initiators dir) strs tasks |>> forall I
   272       fold_map (require_thy initiators dir) strs tasks |>> forall I
   283   in
   279   in
   284     (case try (Graph.get_node tasks) name of
   280     (case try (Graph.get_node tasks) name of
   285       SOME task => (task_finished task, tasks)
   281       SOME task => (task_finished task, tasks)
   286     | NONE =>
   282     | NONE =>
   287         let
   283         let
   288           val (current, deps, imports, opt_text) = check_deps dir' name
   284           val (current, deps, imports) = check_deps dir' name
   289             handle ERROR msg => cat_error msg
   285             handle ERROR msg => cat_error msg
   290               (loader_msg "the error(s) above occurred while examining theory" [name] ^
   286               (loader_msg "the error(s) above occurred while examining theory" [name] ^
   291                 required_by "\n" initiators);
   287                 required_by "\n" initiators);
   292 
   288 
   293           val parents = map base_name imports;
   289           val parents = map base_name imports;
   294           val (parents_current, tasks') =
   290           val (parents_current, tasks') =
   295             require_thys (name :: initiators) (Path.append dir (master_dir deps)) imports tasks;
   291             require_thys (name :: initiators)
       
   292               (Path.append dir (master_dir (Option.map #1 deps))) imports tasks;
   296 
   293 
   297           val all_current = current andalso parents_current;
   294           val all_current = current andalso parents_current;
   298           val task =
   295           val task =
   299             if all_current then Finished (get_theory name)
   296             if all_current then Finished (get_theory name)
   300             else
   297             else
   301               (case deps of
   298               (case deps of
   302                 NONE => raise Fail "Malformed deps"
   299                 NONE => raise Fail "Malformed deps"
   303               | SOME (dep as {master = (thy_path, _), ...}) =>
   300               | SOME (dep, text) =>
   304                   let
   301                   let val update_time = serial ()
   305                     val text = (case opt_text of SOME text => text | NONE => File.read thy_path);
       
   306                     val update_time = serial ();
       
   307                   in Task (parents, load_thy initiators update_time dep text name) end);
   302                   in Task (parents, load_thy initiators update_time dep text name) end);
   308         in (all_current, new_entry name parents task tasks') end)
   303         in (all_current, new_entry name parents task tasks') end)
   309   end;
   304   end;
   310 
   305 
   311 end;
   306 end;
   334 (* register theory *)
   329 (* register theory *)
   335 
   330 
   336 fun register_thy theory =
   331 fun register_thy theory =
   337   let
   332   let
   338     val name = Context.theory_name theory;
   333     val name = Context.theory_name theory;
   339     val master = Thy_Load.check_thy (Thy_Load.master_directory theory) name;
   334     val {master, ...} = Thy_Load.check_thy (Thy_Load.master_directory theory) name;
   340     val parents = map Context.theory_name (Theory.parents_of theory);
   335     val parents = map Context.theory_name (Theory.parents_of theory);
   341     val imports = Thy_Load.imports_of theory;
   336     val imports = Thy_Load.imports_of theory;
   342     val deps = make_deps master imports;
   337     val deps = make_deps master imports;
   343   in
   338   in
   344     NAMED_CRITICAL "Thy_Info" (fn () =>
   339     NAMED_CRITICAL "Thy_Info" (fn () =>