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