| author | nipkow | 
| Fri, 16 Jul 2004 17:32:34 +0200 | |
| changeset 15055 | aed573241bea | 
| parent 14981 | e73f8140af78 | 
| child 15065 | 9feac0b7f935 | 
| permissions | -rw-r--r-- | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 1 | (* Title: Pure/Thy/thy_info.ML | 
| 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 2 | ID: $Id$ | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 3 | Author: Markus Wenzel, TU Muenchen | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 4 | |
| 6362 | 5 | Theory loader database, including theory and file dependencies. | 
| 3976 | 6 | *) | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 7 | |
| 5209 | 8 | signature BASIC_THY_INFO = | 
| 9 | sig | |
| 10 | val theory: string -> theory | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 11 | val theory_of_sign: Sign.sg -> theory | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 12 | val theory_of_thm: thm -> theory | 
| 6241 | 13 | (*val use: string -> unit*) (*exported later*) | 
| 14 | val time_use: string -> unit | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 15 | val touch_thy: string -> unit | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 16 | val use_thy: string -> unit | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 17 | val update_thy: string -> unit | 
| 6666 | 18 | val remove_thy: string -> unit | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 19 | val time_use_thy: string -> unit | 
| 6527 | 20 | val use_thy_only: string -> unit | 
| 7099 | 21 | val update_thy_only: string -> unit | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 22 | end; | 
| 5209 | 23 | |
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 24 | signature THY_INFO = | 
| 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 25 | sig | 
| 5209 | 26 | include BASIC_THY_INFO | 
| 7099 | 27 | datatype action = Update | Outdate | Remove | 
| 28 | val str_of_action: action -> string | |
| 29 | val add_hook: (action -> string -> unit) -> unit | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 30 | val names: unit -> string list | 
| 7910 | 31 | val known_thy: string -> bool | 
| 7935 | 32 | val check_known_thy: string -> bool | 
| 33 | val if_known_thy: (string -> unit) -> string -> unit | |
| 7288 | 34 | val lookup_theory: string -> theory option | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 35 | val get_theory: string -> theory | 
| 6654 | 36 | val get_preds: string -> string list | 
| 7935 | 37 | val loaded_files: string -> Path.T list | 
| 7910 | 38 | val touch_child_thys: string -> unit | 
| 7099 | 39 | val touch_all_thys: unit -> unit | 
| 7941 | 40 | val load_file: bool -> Path.T -> unit | 
| 6241 | 41 | val use: string -> unit | 
| 7952 | 42 | val quiet_update_thy: bool -> string -> unit | 
| 9822 | 43 | val pretend_use_thy_only: string -> unit | 
| 8805 | 44 | val begin_theory: (string -> string list -> (Path.T * bool) list -> theory -> theory) -> | 
| 45 | bool -> string -> string list -> (Path.T * bool) list -> theory | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 46 | val end_theory: theory -> theory | 
| 6666 | 47 | val finish: unit -> unit | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 48 | val register_theory: theory -> unit | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 49 | end; | 
| 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 50 | |
| 6362 | 51 | structure ThyInfo: THY_INFO = | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 52 | struct | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 53 | |
| 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 54 | |
| 7099 | 55 | (** theory loader actions and hooks **) | 
| 56 | ||
| 57 | datatype action = Update | Outdate | Remove; | |
| 58 | val str_of_action = fn Update => "Update" | Outdate => "Outdate" | Remove => "Remove"; | |
| 59 | ||
| 60 | local | |
| 61 | val hooks = ref ([]: (action -> string -> unit) list); | |
| 62 | in | |
| 63 | fun add_hook f = hooks := f :: ! hooks; | |
| 7191 | 64 | fun perform action name = seq (fn f => (try (fn () => f action name) (); ())) (! hooks); | 
| 7099 | 65 | end; | 
| 66 | ||
| 67 | ||
| 68 | ||
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 69 | (** thy database **) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 70 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 71 | (* messages *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 72 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 73 | fun gen_msg txt [] = txt | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 74 | | gen_msg txt names = txt ^ " " ^ commas_quote names; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 75 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 76 | fun loader_msg txt names = gen_msg ("Theory loader: " ^ txt) names;
 | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 77 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 78 | val show_path = space_implode " via " o map quote; | 
| 9332 | 79 | fun cycle_msg names = loader_msg ("cyclic dependency of " ^ show_path names) [];
 | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 80 | |
| 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 81 | |
| 6666 | 82 | (* derived graph operations *) | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 83 | |
| 9327 | 84 | fun add_deps name parents G = Graph.add_deps_acyclic (name, parents) G | 
| 9332 | 85 | handle Graph.CYCLES namess => error (cat_lines (map cycle_msg namess)); | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 86 | |
| 7952 | 87 | fun upd_deps name entry G = | 
| 88 | foldl (fn (H, parent) => Graph.del_edge (parent, name) H) (G, Graph.imm_preds G name) | |
| 89 | |> Graph.map_node name (K entry); | |
| 3976 | 90 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 91 | fun update_node name parents entry G = | 
| 7952 | 92 | (if can (Graph.get_node G) name then upd_deps name entry G else Graph.new_node (name, entry) G) | 
| 93 | |> add_deps name parents; | |
| 94 | ||
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 95 | |
| 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 96 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 97 | (* thy database *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 98 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 99 | type deps = | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 100 |   {present: bool, outdated: bool,
 | 
| 7941 | 101 | master: ThyLoad.master option, files: (Path.T * (Path.T * File.info) option) list}; | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 102 | |
| 6241 | 103 | fun make_deps present outdated master files = | 
| 104 |   {present = present, outdated = outdated, master = master, files = files}: deps;
 | |
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 105 | |
| 7211 | 106 | fun init_deps master files = Some (make_deps false true master (map (rpair None) files)); | 
| 107 | ||
| 108 | ||
| 6362 | 109 | type thy = deps option * theory option; | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 110 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 111 | local | 
| 6362 | 112 | val database = ref (Graph.empty: thy Graph.T); | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 113 | in | 
| 6362 | 114 | fun get_thys () = ! database; | 
| 9137 | 115 | val change_thys = Library.change database; | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 116 | end; | 
| 5209 | 117 | |
| 118 | ||
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 119 | (* access thy graph *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 120 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 121 | fun thy_graph f x = f (get_thys ()) x; | 
| 9417 | 122 | |
| 123 | (*theory names in topological order*) | |
| 124 | fun get_names () = | |
| 125 | let val G = get_thys () | |
| 14774 | 126 | in Graph.all_succs G (Graph.minimals G) end; | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 127 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 128 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 129 | (* access thy *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 130 | |
| 7935 | 131 | fun lookup_thy name = | 
| 9327 | 132 | Some (thy_graph Graph.get_node name) handle Graph.UNDEF _ => None; | 
| 7935 | 133 | |
| 7910 | 134 | val known_thy = is_some o lookup_thy; | 
| 7935 | 135 | fun check_known_thy name = known_thy name orelse (warning ("Unknown theory " ^ quote name); false);
 | 
| 136 | fun if_known_thy f name = if check_known_thy name then f name else (); | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 137 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 138 | fun get_thy name = | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 139 | (case lookup_thy name of | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 140 | Some thy => thy | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 141 | | None => error (loader_msg "nothing known about theory" [name])); | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 142 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 143 | fun change_thy name f = (get_thy name; change_thys (Graph.map_node name f)); | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 144 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 145 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 146 | (* access deps *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 147 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 148 | val lookup_deps = apsome #1 o lookup_thy; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 149 | val get_deps = #1 o get_thy; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 150 | fun change_deps name f = change_thy name (fn (deps, x) => (f deps, x)); | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 151 | |
| 6666 | 152 | fun is_finished name = is_none (get_deps name); | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 153 | fun get_files name = (case get_deps name of Some {files, ...} => files | _ => []);
 | 
| 7191 | 154 | |
| 155 | fun loaded_files name = | |
| 156 | (case get_deps name of | |
| 7935 | 157 | None => [] | 
| 7910 | 158 |   | Some {master, files, ...} =>
 | 
| 7935 | 159 | (case master of Some m => [#1 (ThyLoad.get_thy m)] | None => []) @ | 
| 7941 | 160 | (mapfilter (apsome #1 o #2) files)); | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 161 | |
| 6654 | 162 | fun get_preds name = | 
| 9327 | 163 | (thy_graph Graph.imm_preds name) handle Graph.UNDEF _ => | 
| 6654 | 164 | error (loader_msg "nothing known about theory" [name]); | 
| 165 | ||
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 166 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 167 | (* access theory *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 168 | |
| 7687 | 169 | fun lookup_theory name = | 
| 170 | (case lookup_thy name of | |
| 171 | Some (_, Some thy) => Some thy | |
| 172 | | _ => None); | |
| 7288 | 173 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 174 | fun get_theory name = | 
| 7288 | 175 | (case lookup_theory name of | 
| 176 | (Some theory) => theory | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 177 | | _ => error (loader_msg "undefined theory entry for" [name])); | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 178 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 179 | val theory_of_sign = get_theory o Sign.name_of; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 180 | val theory_of_thm = theory_of_sign o Thm.sign_of_thm; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 181 | |
| 7099 | 182 | fun put_theory name theory = change_thy name (fn (deps, _) => (deps, Some theory)); | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 183 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 184 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 185 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 186 | (** thy operations **) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 187 | |
| 6241 | 188 | (* maintain 'outdated' flag *) | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 189 | |
| 7099 | 190 | local | 
| 191 | ||
| 6241 | 192 | fun is_outdated name = | 
| 193 | (case lookup_deps name of | |
| 194 |     Some (Some {outdated, ...}) => outdated
 | |
| 195 | | _ => false); | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 196 | |
| 6241 | 197 | fun outdate_thy name = | 
| 7099 | 198 | if is_finished name orelse is_outdated name then () | 
| 199 |   else (change_deps name (apsome (fn {present, outdated = _, master, files} =>
 | |
| 200 | make_deps present true master files)); perform Outdate name); | |
| 201 | ||
| 7910 | 202 | fun check_unfinished name = | 
| 203 | if is_finished name then (warning (loader_msg "tried to touch finished theory" [name]); None) | |
| 204 | else Some name; | |
| 205 | ||
| 7099 | 206 | in | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 207 | |
| 7910 | 208 | fun touch_thys names = | 
| 209 | seq outdate_thy (thy_graph Graph.all_succs (mapfilter check_unfinished names)); | |
| 210 | ||
| 211 | fun touch_thy name = touch_thys [name]; | |
| 212 | fun touch_child_thys name = touch_thys (thy_graph Graph.imm_succs name); | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 213 | |
| 7099 | 214 | fun touch_all_thys () = seq outdate_thy (get_names ()); | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 215 | |
| 7099 | 216 | end; | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 217 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 218 | |
| 7244 | 219 | (* check 'finished' state *) | 
| 220 | ||
| 221 | fun check_unfinished fail name = | |
| 7910 | 222 | if known_thy name andalso is_finished name then | 
| 7288 | 223 | fail (loader_msg "cannot update finished theory" [name]) | 
| 7244 | 224 | else (); | 
| 225 | ||
| 226 | ||
| 7941 | 227 | (* load_file *) | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 228 | |
| 7191 | 229 | local | 
| 230 | ||
| 7941 | 231 | fun provide path name info (deps as Some {present, outdated, master, files}) =
 | 
| 232 | (if exists (equal path o #1) files then () | |
| 233 | else warning (loader_msg "undeclared dependency of theory" [name] ^ | |
| 234 | " on file: " ^ quote (Path.pack path)); | |
| 235 | Some (make_deps present outdated master (overwrite (files, (path, Some info))))) | |
| 236 | | provide _ _ _ None = None; | |
| 237 | ||
| 238 | fun run_file path = | |
| 239 | (case apsome PureThy.get_name (Context.get_context ()) of | |
| 240 | None => (ThyLoad.load_file path; ()) | |
| 241 | | Some name => | |
| 242 | if known_thy name then change_deps name (provide path name (ThyLoad.load_file path)) | |
| 243 | else (ThyLoad.load_file path; ())); | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 244 | |
| 7191 | 245 | in | 
| 246 | ||
| 7941 | 247 | fun load_file time path = | 
| 248 | if time then | |
| 7244 | 249 | let val name = Path.pack path in | 
| 250 | timeit (fn () => | |
| 9778 | 251 |        (priority ("\n**** Starting file " ^ quote name ^ " ****");
 | 
| 9036 | 252 | run_file path; | 
| 9778 | 253 |         priority ("**** Finished file " ^ quote name ^ " ****\n")))
 | 
| 7244 | 254 | end | 
| 7941 | 255 | else run_file path; | 
| 256 | ||
| 257 | val use = load_file false o Path.unpack; | |
| 258 | val time_use = load_file true o Path.unpack; | |
| 7191 | 259 | |
| 260 | end; | |
| 6233 | 261 | |
| 262 | ||
| 7099 | 263 | (* load_thy *) | 
| 264 | ||
| 9490 | 265 | fun required_by _ [] = "" | 
| 266 | | required_by s initiators = s ^ "(required by " ^ show_path (rev initiators) ^ ")"; | |
| 7099 | 267 | |
| 9822 | 268 | fun load_thy really ml time initiators dir name parents = | 
| 7099 | 269 | let | 
| 9822 | 270 | val _ = | 
| 271 |       if really then priority ("Loading theory " ^ quote name ^ required_by " " initiators)
 | |
| 272 |       else priority ("Registering theory " ^ quote name);
 | |
| 7099 | 273 | |
| 274 | val _ = touch_thy name; | |
| 9822 | 275 | val master = | 
| 276 | if really then ThyLoad.load_thy dir name ml time | |
| 277 | else #1 (ThyLoad.deps_thy dir name ml); | |
| 7099 | 278 | |
| 279 | val files = get_files name; | |
| 280 | val missing_files = mapfilter (fn (path, None) => Some (Path.pack path) | _ => None) files; | |
| 281 | in | |
| 282 | if null missing_files then () | |
| 283 | else warning (loader_msg "unresolved dependencies of theory" [name] ^ | |
| 7223 | 284 | " on file(s): " ^ commas_quote missing_files); | 
| 7191 | 285 | change_deps name (fn _ => Some (make_deps true false (Some master) files)); | 
| 7099 | 286 | perform Update name | 
| 287 | end; | |
| 288 | ||
| 289 | ||
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 290 | (* require_thy *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 291 | |
| 7211 | 292 | local | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 293 | |
| 7941 | 294 | fun load_deps ml dir name = | 
| 295 | let val (master, (parents, files)) = ThyLoad.deps_thy dir name ml | |
| 7191 | 296 | in (Some (init_deps (Some master) files), parents) end; | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 297 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 298 | fun file_current (_, None) = false | 
| 7941 | 299 | | file_current (path, info) = (info = ThyLoad.check_file path); | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 300 | |
| 7941 | 301 | fun current_deps ml strict dir name = | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 302 | (case lookup_deps name of | 
| 7941 | 303 | None => (false, load_deps ml dir name) | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 304 | | Some deps => | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 305 | let val same_deps = (None, thy_graph Graph.imm_preds name) in | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 306 | (case deps of | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 307 | None => (true, same_deps) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 308 |         | Some {present, outdated, master, files} =>
 | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 309 | if present andalso not strict then (true, same_deps) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 310 | else | 
| 7941 | 311 | let val master' = Some (ThyLoad.check_thy dir name ml) in | 
| 312 | if master <> master' then (false, load_deps ml dir name) | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 313 | else (not outdated andalso forall file_current files, same_deps) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 314 | end) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 315 | end); | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 316 | |
| 9822 | 317 | fun require_thy really ml time strict keep_strict initiators prfx (visited, str) = | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 318 | let | 
| 7066 | 319 | val path = Path.expand (Path.unpack str); | 
| 6484 
3f098b0ec683
use_thy etc.: may specify path prefix, which is temporarily used as load path;
 wenzelm parents: 
6389diff
changeset | 320 | val name = Path.pack (Path.base path); | 
| 7066 | 321 | in | 
| 9332 | 322 | if name mem_string initiators then error (cycle_msg initiators) else (); | 
| 7952 | 323 | if known_thy name andalso is_finished name orelse name mem_string visited then | 
| 324 | (visited, (true, name)) | |
| 7066 | 325 | else | 
| 326 | let | |
| 327 | val dir = Path.append prfx (Path.dir path); | |
| 9822 | 328 | val req_parent = require_thy true true time (strict andalso keep_strict) keep_strict | 
| 329 | (name :: initiators) dir; | |
| 6484 
3f098b0ec683
use_thy etc.: may specify path prefix, which is temporarily used as load path;
 wenzelm parents: 
6389diff
changeset | 330 | |
| 7941 | 331 | val (current, (new_deps, parents)) = current_deps ml strict dir name handle ERROR => | 
| 7099 | 332 | error (loader_msg "the error(s) above occurred while examining theory" [name] ^ | 
| 9490 | 333 | (if null initiators then "" else required_by "\n" initiators)); | 
| 7066 | 334 | val (visited', parent_results) = foldl_map req_parent (name :: visited, parents); | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 335 | |
| 9822 | 336 | val thy = if not really then Some (get_theory name) else None; | 
| 7066 | 337 | val result = | 
| 338 | if current andalso forall #1 parent_results then true | |
| 339 | else | |
| 340 | ((case new_deps of | |
| 9822 | 341 | Some deps => change_thys (update_node name parents (deps, thy)) | 
| 7066 | 342 | | None => ()); | 
| 14825 | 343 | load_thy really ml (time orelse ! Output.timing) initiators dir name parents; | 
| 7099 | 344 | false); | 
| 7066 | 345 | in (visited', (result, name)) end | 
| 346 | end; | |
| 6484 
3f098b0ec683
use_thy etc.: may specify path prefix, which is temporarily used as load path;
 wenzelm parents: 
6389diff
changeset | 347 | |
| 7066 | 348 | fun gen_use_thy req s = | 
| 349 | let val (_, (_, name)) = req [] Path.current ([], s) | |
| 350 | in Context.context (get_theory name) end; | |
| 6241 | 351 | |
| 7244 | 352 | fun warn_finished f name = (check_unfinished warning name; f name); | 
| 353 | ||
| 7211 | 354 | in | 
| 355 | ||
| 9822 | 356 | val weak_use_thy = gen_use_thy (require_thy true true false false false); | 
| 357 | fun quiet_update_thy ml = gen_use_thy (require_thy true ml false true true); | |
| 7244 | 358 | |
| 9822 | 359 | val use_thy = warn_finished (gen_use_thy (require_thy true true false true false)); | 
| 360 | val time_use_thy = warn_finished (gen_use_thy (require_thy true true true true false)); | |
| 361 | val use_thy_only = warn_finished (gen_use_thy (require_thy true false false true false)); | |
| 362 | val update_thy = warn_finished (gen_use_thy (require_thy true true false true true)); | |
| 363 | val update_thy_only = warn_finished (gen_use_thy (require_thy true false false true true)); | |
| 364 | val pretend_use_thy_only = warn_finished (gen_use_thy (require_thy false false false true false)); | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 365 | |
| 7211 | 366 | end; | 
| 367 | ||
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 368 | |
| 6666 | 369 | (* remove_thy *) | 
| 370 | ||
| 371 | fun remove_thy name = | |
| 7910 | 372 | if is_finished name then error (loader_msg "cannot remove finished theory" [name]) | 
| 6666 | 373 | else | 
| 374 | let val succs = thy_graph Graph.all_succs [name] in | |
| 9778 | 375 | priority (loader_msg "removing" succs); | 
| 7191 | 376 | seq (perform Remove) succs; | 
| 377 | change_thys (Graph.del_nodes succs) | |
| 6666 | 378 | end; | 
| 379 | ||
| 380 | ||
| 7066 | 381 | (* begin / end theory *) | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 382 | |
| 8805 | 383 | fun begin_theory present upd name parents paths = | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 384 | let | 
| 8805 | 385 | val assert_thy = if upd then quiet_update_thy true else weak_use_thy; | 
| 7244 | 386 | val _ = check_unfinished error name; | 
| 7941 | 387 | val _ = (map Path.basic parents; seq assert_thy parents); | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 388 | val theory = PureThy.begin_theory name (map get_theory parents); | 
| 7952 | 389 | val deps = | 
| 390 | if known_thy name then get_deps name | |
| 391 | else (init_deps None (map #1 paths)); (*records additional ML files only!*) | |
| 6329 | 392 | val use_paths = mapfilter (fn (x, true) => Some x | _ => None) paths; | 
| 9451 | 393 | |
| 394 | val _ = change_thys (update_node name parents (deps, Some (Theory.copy theory))); | |
| 8805 | 395 | val theory' = theory |> present name parents paths; | 
| 9451 | 396 | val _ = put_theory name (Theory.copy theory'); | 
| 8805 | 397 | val ((), theory'') = Context.pass_theory theory' (seq (load_file false)) use_paths; | 
| 9451 | 398 | val _ = put_theory name (Theory.copy theory''); | 
| 8805 | 399 | in theory'' end; | 
| 7244 | 400 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 401 | fun end_theory theory = | 
| 7099 | 402 | let | 
| 403 | val theory' = PureThy.end_theory theory; | |
| 404 | val name = PureThy.get_name theory; | |
| 405 | in put_theory name theory'; theory' end; | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 406 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 407 | |
| 6666 | 408 | (* finish all theories *) | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 409 | |
| 6666 | 410 | fun finish () = change_thys (Graph.map_nodes (fn (_, entry) => (None, entry))); | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 411 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 412 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 413 | (* register existing theories *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 414 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 415 | fun register_theory theory = | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 416 | let | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 417 | val name = PureThy.get_name theory; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 418 | val parents = Theory.parents_of theory; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 419 | val parent_names = map PureThy.get_name parents; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 420 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 421 | fun err txt bads = | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 422 | error (loader_msg txt bads ^ "\n" ^ gen_msg "cannot register theory" [name]); | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 423 | |
| 6666 | 424 | val nonfinished = filter_out is_finished parent_names; | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 425 | fun get_variant (x, y_name) = | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 426 | if Theory.eq_thy (x, get_theory y_name) then None | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 427 | else Some y_name; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 428 | val variants = mapfilter get_variant (parents ~~ parent_names); | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 429 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 430 | fun register G = | 
| 6362 | 431 | (Graph.new_node (name, (None, Some theory)) G | 
| 9327 | 432 | handle Graph.DUP _ => err "duplicate theory entry" []) | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 433 | |> add_deps name parent_names; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 434 | in | 
| 6666 | 435 | if not (null nonfinished) then err "non-finished parent theories" nonfinished | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 436 | else if not (null variants) then err "different versions of parent theories" variants | 
| 7099 | 437 | else (change_thys register; perform Update name) | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 438 | end; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 439 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 440 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 441 | (*final declarations of this structure*) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 442 | val theory = get_theory; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 443 | val names = get_names; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 444 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 445 | end; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 446 | |
| 5209 | 447 | structure BasicThyInfo: BASIC_THY_INFO = ThyInfo; | 
| 448 | open BasicThyInfo; |