src/Pure/Thy/thy_read.ML
changeset 559 00365d2e0c50
parent 476 836cad329311
child 586 201e115d8031
equal deleted inserted replaced
558:c4092ae47210 559:00365d2e0c50
     1 (*  Title:      Pure/Thy/thy_read.ML
     1 (*  Title:      Pure/Thy/thy_read.ML
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Sonia Mahjoub / Tobias Nipkow / L C Paulson / Carsten Clasohm
     3     Author:     Carsten Clasohm and Markus Wenzel and Sonia Mahjoub and
     4     Copyright   1994  TU Muenchen
     4                 Tobias Nipkow and L C Paulson
     5 
     5     Copyright   1994 TU Muenchen
       
     6 
       
     7 (* FIXME !? *)
     6 Reading and writing the theory definition files.
     8 Reading and writing the theory definition files.
     7 
     9 
       
    10 (* FIXME !? *)
     8 For theory XXX, the  input file is called XXX.thy
    11 For theory XXX, the  input file is called XXX.thy
     9                 the output file is called .XXX.thy.ML
    12                 the output file is called .XXX.thy.ML
    10                 and it then tries to read XXX.ML
    13                 and it then tries to read XXX.ML
    11 *)
    14 *)
    12 
    15 
    13 datatype thy_info = ThyInfo of {path: string,
    16 datatype thy_info = ThyInfo of {path: string,
    14                                 children: string list,
    17                                 children: string list,
    15                                 thy_time: string option,
    18                                 thy_time: string option,
    16                                 ml_time: string option,
    19                                 ml_time: string option,
    17                                 theory: Thm.theory option,
    20                                 theory: theory option,
    18                                 thms: thm Symtab.table};
    21                                 thms: thm Symtab.table};
    19 
    22 
    20 signature READTHY =
    23 signature READTHY =
    21 sig
    24 sig
    22   datatype basetype = Thy  of string
    25   datatype basetype = Thy  of string
    31   val time_use_thy   : string -> unit
    34   val time_use_thy   : string -> unit
    32   val unlink_thy     : string -> unit
    35   val unlink_thy     : string -> unit
    33   val base_on        : basetype list -> string -> bool -> theory
    36   val base_on        : basetype list -> string -> bool -> theory
    34   val store_theory   : theory * string -> unit
    37   val store_theory   : theory * string -> unit
    35 
    38 
    36   val store_thm      : thm * string -> thm
    39   val theory_of_sign: Sign.sg -> theory
    37   val qed            : string -> unit
    40   val theory_of_thm: thm -> theory
    38   val get_thm        : theory -> string -> thm
    41   val store_thm: string * thm -> thm
    39   val get_thms       : theory -> (string * thm) list
    42   val qed: string -> unit
       
    43   val get_thm: theory -> string -> thm
       
    44   val thms_of: theory -> (string * thm) list
    40 end;
    45 end;
    41 
    46 
    42 
    47 
    43 functor ReadthyFUN(structure ThySyn: THY_SYN): READTHY =
    48 functor ReadthyFUN(structure ThySyn: THY_SYN): READTHY =
    44 struct
    49 struct
    45 open Symtab;
       
    46 
    50 
    47 datatype basetype = Thy  of string
    51 datatype basetype = Thy  of string
    48                   | File of string;
    52                   | File of string;
    49 
    53 
    50 val loaded_thys = ref (make [("Pure", ThyInfo {path = "", children = [], 
    54 val loaded_thys = ref (Symtab.make [("Pure", ThyInfo {path = "", children = [],
    51                                        thy_time = Some "", ml_time = Some "", 
    55                                        thy_time = Some "", ml_time = Some "",
    52                                        theory = Some pure_thy,
    56                                        theory = Some pure_thy,
    53                                        thms = null})]);
    57                                        thms = Symtab.null})]);
    54 
    58 
    55 val loadpath = ref ["."];           (*default search path for theory files *)
    59 val loadpath = ref ["."];           (*default search path for theory files *)
    56 
    60 
    57 val delete_tmpfiles = ref true;         (*remove temporary files after use *)
    61 val delete_tmpfiles = ref true;         (*remove temporary files after use *)
    58 
    62 
    59 (*Make name of the output ML file for a theory *)
    63 (*Make name of the output ML file for a theory *)
    60 fun out_name tname = "." ^ tname ^ ".thy.ML";
    64 fun out_name tname = "." ^ tname ^ ".thy.ML";
    61 
    65 
    62 (*Read a file specified by thy_file containing theory thy *)
    66 (*Read a file specified by thy_file containing theory thy *)
    63 fun read_thy tname thy_file =
    67 fun read_thy tname thy_file =
    64   let 
    68   let
    65     val instream  = open_in thy_file;
    69     val instream  = open_in thy_file;
    66     val outstream = open_out (out_name tname);
    70     val outstream = open_out (out_name tname);
    67   in  
    71   in
    68     output (outstream, ThySyn.parse tname (input (instream, 999999)));
    72     output (outstream, ThySyn.parse tname (input (instream, 999999)));
    69     close_out outstream;
    73     close_out outstream;
    70     close_in instream
    74     close_in instream
    71   end;
    75   end;
    72 
    76 
    73 fun file_exists file =
    77 fun file_exists file =
    74   let val instream = open_in file in close_in instream; true end
    78   let val instream = open_in file in close_in instream; true end
    75     handle Io _ => false;
    79     handle Io _ => false;
    76 
    80 
    77 (*Get thy_info for a loaded theory *)
    81 (*Get thy_info for a loaded theory *)
    78 fun get_thyinfo tname = lookup (!loaded_thys, tname);
    82 fun get_thyinfo tname = Symtab.lookup (!loaded_thys, tname);
    79 
    83 
    80 (*Check if a theory was already loaded *)
    84 (*Check if a theory was already loaded *)
    81 fun already_loaded thy =
    85 fun already_loaded thy =
    82   let val t = get_thyinfo thy
    86   let val t = get_thyinfo thy
    83   in if is_none t then false
    87   in if is_none t then false
    84      else let val ThyInfo {thy_time, ml_time, ...} = the t
    88      else let val ThyInfo {thy_time, ml_time, ...} = the t
    85           in if is_none thy_time orelse is_none ml_time then false 
    89           in if is_none thy_time orelse is_none ml_time then false
    86              else true 
    90              else true
    87           end
    91           end
    88   end;
    92   end;
    89 
    93 
    90 (*Check if a theory file has changed since its last use.
    94 (*Check if a theory file has changed since its last use.
    91   Return a pair of boolean values for .thy and for .ML *)
    95   Return a pair of boolean values for .thy and for .ML *)
    92 fun thy_unchanged thy thy_file ml_file = 
    96 fun thy_unchanged thy thy_file ml_file =
    93   let val t = get_thyinfo thy
    97   let val t = get_thyinfo thy
    94   in if is_some t then
    98   in if is_some t then
    95        let val ThyInfo {thy_time, ml_time, ...} = the t
    99        let val ThyInfo {thy_time, ml_time, ...} = the t
    96            val tn = is_none thy_time;
   100            val tn = is_none thy_time;
    97            val mn = is_none ml_time
   101            val mn = is_none ml_time
    98        in if not tn andalso not mn then
   102        in if not tn andalso not mn then
    99               ((file_info thy_file = the thy_time), 
   103               ((file_info thy_file = the thy_time),
   100                (file_info ml_file = the ml_time))
   104                (file_info ml_file = the ml_time))
   101           else if not tn andalso mn then (true, false)
   105           else if not tn andalso mn then (true, false)
   102           else (false, false)
   106           else (false, false)
   103        end
   107        end
   104      else (false, false)
   108      else (false, false)
   110   specified.*)
   114   specified.*)
   111 fun find_file "" name =
   115 fun find_file "" name =
   112       let fun find_it (curr :: paths) =
   116       let fun find_it (curr :: paths) =
   113                 if file_exists (tack_on curr name) then
   117                 if file_exists (tack_on curr name) then
   114                     tack_on curr name
   118                     tack_on curr name
   115                 else 
   119                 else
   116                     find_it paths
   120                     find_it paths
   117            | find_it [] = ""
   121            | find_it [] = ""
   118       in find_it (!loadpath) end
   122       in find_it (!loadpath) end
   119   | find_file path name =
   123   | find_file path name =
   120       if file_exists (tack_on path name) then tack_on path name
   124       if file_exists (tack_on path name) then tack_on path name
   121                                          else "";
   125                                          else "";
   122 
   126 
   123 (*Get absolute pathnames for a new or already loaded theory *)
   127 (*Get absolute pathnames for a new or already loaded theory *)
   124 fun get_filenames path name =
   128 fun get_filenames path name =
   125   let fun make_absolute file =
   129   let fun make_absolute file =
   126         if file = "" then "" else 
   130         if file = "" then "" else
   127             if hd (explode file) = "/" then file else tack_on (pwd ()) file;
   131             if hd (explode file) = "/" then file else tack_on (pwd ()) file;
   128 
   132 
   129       fun new_filename () =
   133       fun new_filename () =
   130         let val found = find_file path (name ^ ".thy")
   134         let val found = find_file path (name ^ ".thy")
   131                         handle FILE_NOT_FOUND => "";
   135                         handle FILE_NOT_FOUND => "";
   141              error ("Could not find file \"" ^ name ^ ".thy\" or \""
   145              error ("Could not find file \"" ^ name ^ ".thy\" or \""
   142                     ^ name ^ ".ML\" for theory \"" ^ name ^ "\"\n"
   146                     ^ name ^ ".ML\" for theory \"" ^ name ^ "\"\n"
   143                     ^ "in the following directories: \"" ^
   147                     ^ "in the following directories: \"" ^
   144                     (space_implode "\", \"" searched_dirs) ^ "\"")
   148                     (space_implode "\", \"" searched_dirs) ^ "\"")
   145            else ();
   149            else ();
   146            (thy_file, ml_file) 
   150            (thy_file, ml_file)
   147         end;
   151         end;
   148 
   152 
   149       val tinfo = get_thyinfo name;
   153       val tinfo = get_thyinfo name;
   150   in if is_some tinfo andalso path = "" then
   154   in if is_some tinfo andalso path = "" then
   151        let val ThyInfo {path = abs_path, ...} = the tinfo;
   155        let val ThyInfo {path = abs_path, ...} = the tinfo;
   164   end;
   168   end;
   165 
   169 
   166 (*Remove theory from all child lists in loaded_thys *)
   170 (*Remove theory from all child lists in loaded_thys *)
   167 fun unlink_thy tname =
   171 fun unlink_thy tname =
   168   let fun remove (ThyInfo {path, children, thy_time, ml_time, theory, thms}) =
   172   let fun remove (ThyInfo {path, children, thy_time, ml_time, theory, thms}) =
   169         ThyInfo {path = path, children = children \ tname, 
   173         ThyInfo {path = path, children = children \ tname,
   170                  thy_time = thy_time, ml_time = ml_time,
   174                  thy_time = thy_time, ml_time = ml_time,
   171                  theory = theory, thms = thms}
   175                  theory = theory, thms = thms}
   172   in loaded_thys := mapst remove (!loaded_thys) end;
   176   in loaded_thys := Symtab.map remove (!loaded_thys) end;
   173 
   177 
   174 (*Remove a theory from loaded_thys *)
   178 (*Remove a theory from loaded_thys *)
   175 fun remove_thy tname =
   179 fun remove_thy tname =
   176   loaded_thys := make (filter_out (fn (id, _) => id = tname)
   180   loaded_thys := Symtab.make (filter_out (fn (id, _) => id = tname)
   177                  (alist_of (!loaded_thys)));
   181                  (Symtab.dest (!loaded_thys)));
   178 
   182 
   179 (*Change thy_time and ml_time for an existent item *)
   183 (*Change thy_time and ml_time for an existent item *)
   180 fun set_info thy_time ml_time tname =
   184 fun set_info thy_time ml_time tname =
   181   let val ThyInfo {path, children, theory, thms, ...} = 
   185   let val ThyInfo {path, children, theory, thms, ...} =
   182         the (lookup (!loaded_thys, tname));
   186         the (Symtab.lookup (!loaded_thys, tname));
   183   in loaded_thys := update ((tname, 
   187   in loaded_thys := Symtab.update ((tname,
   184        ThyInfo {path = path, children = children,
   188        ThyInfo {path = path, children = children,
   185                 thy_time = Some thy_time, ml_time = Some ml_time,
   189                 thy_time = Some thy_time, ml_time = Some ml_time,
   186                 theory = theory, thms = thms}), !loaded_thys)
   190                 theory = theory, thms = thms}), !loaded_thys)
   187   end;
   191   end;
   188 
   192 
   189 (*Mark theory as changed since last read if it has been completly read *)
   193 (*Mark theory as changed since last read if it has been completly read *)
   190 fun mark_outdated tname = 
   194 fun mark_outdated tname =
   191   if already_loaded tname then set_info "" "" tname else ();
   195   if already_loaded tname then set_info "" "" tname else ();
   192 
   196 
   193 (*Read .thy and .ML files that haven't been read yet or have changed since 
   197 (*Read .thy and .ML files that haven't been read yet or have changed since
   194   they were last read;
   198   they were last read;
   195   loaded_thys is a thy_info list ref containing all theories that have 
   199   loaded_thys is a thy_info list ref containing all theories that have
   196   completly been read by this and preceeding use_thy calls.
   200   completly been read by this and preceeding use_thy calls.
   197   If a theory changed since its last use its children are marked as changed *)
   201   If a theory changed since its last use its children are marked as changed *)
   198 fun use_thy name =
   202 fun use_thy name =
   199     let val (path, tname) = split_filename name;
   203     let val (path, tname) = split_filename name;
   200         val (thy_file, ml_file) = get_filenames path tname;
   204         val (thy_file, ml_file) = get_filenames path tname;
   201         val (abs_path, _) = if thy_file = "" then split_filename ml_file
   205         val (abs_path, _) = if thy_file = "" then split_filename ml_file
   202                             else split_filename thy_file;
   206                             else split_filename thy_file;
   203         val (thy_uptodate, ml_uptodate) = thy_unchanged tname 
   207         val (thy_uptodate, ml_uptodate) = thy_unchanged tname
   204                                                         thy_file ml_file;
   208                                                         thy_file ml_file;
   205 
   209 
   206          (*Set absolute path for loaded theory *)
   210          (*Set absolute path for loaded theory *)
   207          fun set_path () =
   211          fun set_path () =
   208            let val ThyInfo {children, thy_time, ml_time, theory, thms, ...} = 
   212            let val ThyInfo {children, thy_time, ml_time, theory, thms, ...} =
   209                  the (lookup (!loaded_thys, tname));
   213                  the (Symtab.lookup (!loaded_thys, tname));
   210            in loaded_thys := update ((tname, 
   214            in loaded_thys := Symtab.update ((tname,
   211                                ThyInfo {path = abs_path, children = children,
   215                                ThyInfo {path = abs_path, children = children,
   212                                         thy_time = thy_time, ml_time = ml_time,
   216                                         thy_time = thy_time, ml_time = ml_time,
   213                                         theory = theory, thms = thms}),
   217                                         theory = theory, thms = thms}),
   214                                !loaded_thys)
   218                                !loaded_thys)
   215            end;
   219            end;
   227               else ()
   231               else ()
   228            end;
   232            end;
   229 
   233 
   230         (*Remove all theorems associated with a theory*)
   234         (*Remove all theorems associated with a theory*)
   231         fun delete_thms () =
   235         fun delete_thms () =
   232           let val tinfo = case lookup (!loaded_thys, tname) of 
   236           let val tinfo = case Symtab.lookup (!loaded_thys, tname) of
   233              Some (ThyInfo {path, children, thy_time, ml_time, theory, ...}) =>
   237              Some (ThyInfo {path, children, thy_time, ml_time, theory, ...}) =>
   234                  ThyInfo {path = path, children = children,
   238                  ThyInfo {path = path, children = children,
   235                           thy_time = thy_time, ml_time = ml_time,
   239                           thy_time = thy_time, ml_time = ml_time,
   236                           theory = theory, thms = null}
   240                           theory = theory, thms = Symtab.null}
   237            | None => ThyInfo {path = "", children = [],
   241            | None => ThyInfo {path = "", children = [],
   238                               thy_time = None, ml_time = None,
   242                               thy_time = None, ml_time = None,
   239                               theory = None, thms = null};
   243                               theory = None, thms = Symtab.null};
   240          in loaded_thys := update ((tname, tinfo), !loaded_thys) end;
   244          in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys) end;
   241     in if thy_uptodate andalso ml_uptodate then ()
   245     in if thy_uptodate andalso ml_uptodate then ()
   242        else
   246        else
   243        (
   247        (
   244          delete_thms ();
   248          delete_thms ();
   245 
   249 
   247          else (writeln ("Reading \"" ^ name ^ ".thy\"");
   251          else (writeln ("Reading \"" ^ name ^ ".thy\"");
   248                read_thy tname thy_file;
   252                read_thy tname thy_file;
   249                use (out_name tname)
   253                use (out_name tname)
   250               );
   254               );
   251 
   255 
   252          if ml_file = "" then () 
   256          if ml_file = "" then ()
   253          else (writeln ("Reading \"" ^ name ^ ".ML\"");
   257          else (writeln ("Reading \"" ^ name ^ ".ML\"");
   254                use ml_file);
   258                use ml_file);
   255 
   259 
   256          use_string ["store_theory (" ^ tname ^ ".thy, " ^ quote tname ^ ");"];
   260          use_string ["store_theory (" ^ tname ^ ".thy, " ^ quote tname ^ ");"];
   257 
   261 
   261 
   265 
   262          (*Mark theories that have to be reloaded*)
   266          (*Mark theories that have to be reloaded*)
   263          mark_children tname;
   267          mark_children tname;
   264 
   268 
   265          (*Remove temporary files*)
   269          (*Remove temporary files*)
   266          if not (!delete_tmpfiles) orelse (thy_file = "") orelse thy_uptodate 
   270          if not (!delete_tmpfiles) orelse (thy_file = "") orelse thy_uptodate
   267            then ()
   271            then ()
   268          else delete_file (out_name tname)
   272          else delete_file (out_name tname)
   269         )
   273         )
   270     end;
   274     end;
   271 
   275 
   272 fun time_use_thy tname = timeit(fn()=>
   276 fun time_use_thy tname = timeit(fn()=>
   273    (writeln("\n**** Starting Theory " ^ tname ^ " ****");  
   277    (writeln("\n**** Starting Theory " ^ tname ^ " ****");
   274     use_thy tname;
   278     use_thy tname;
   275     writeln("\n**** Finished Theory " ^ tname ^ " ****"))
   279     writeln("\n**** Finished Theory " ^ tname ^ " ****"))
   276    );
   280    );
   277 
   281 
   278 (*Load all thy or ML files that have been changed and also
   282 (*Load all thy or ML files that have been changed and also
   287                              let val ThyInfo {children, ...} = the thy
   291                              let val ThyInfo {children, ...} = the thy
   288                              in children union (next_level ts) end
   292                              in children union (next_level ts) end
   289                          else next_level ts
   293                          else next_level ts
   290                       end
   294                       end
   291                   | next_level [] = [];
   295                   | next_level [] = [];
   292                   
   296 
   293                 val children = next_level thys;
   297                 val children = next_level thys;
   294             in load_order children ((result \\ children) @ children) end;
   298             in load_order children ((result \\ children) @ children) end;
   295 
   299 
   296       fun reload_changed (t :: ts) =
   300       fun reload_changed (t :: ts) =
   297             let val thy = get_thyinfo t;
   301             let val thy = get_thyinfo t;
   314        If there are still children in the deleted theory's list
   318        If there are still children in the deleted theory's list
   315        schedule them for reloading *)
   319        schedule them for reloading *)
   316      fun collect_garbage not_garbage =
   320      fun collect_garbage not_garbage =
   317        let fun collect ((tname, ThyInfo {children, ...}) :: ts) =
   321        let fun collect ((tname, ThyInfo {children, ...}) :: ts) =
   318                  if tname mem not_garbage then collect ts
   322                  if tname mem not_garbage then collect ts
   319                  else (writeln ("Theory \"" ^ tname 
   323                  else (writeln ("Theory \"" ^ tname
   320                          ^ "\" is no longer linked with Pure - removing it.");
   324                          ^ "\" is no longer linked with Pure - removing it.");
   321                        remove_thy tname;
   325                        remove_thy tname;
   322                        seq mark_outdated children)
   326                        seq mark_outdated children)
   323              | collect [] = ()
   327              | collect [] = ()
   324 
   328 
   325        in collect (alist_of (!loaded_thys)) end;
   329        in collect (Symtab.dest (!loaded_thys)) end;
   326   in collect_garbage ("Pure" :: (load_order ["Pure"] []));
   330   in collect_garbage ("Pure" :: (load_order ["Pure"] []));
   327      reload_changed (load_order ["Pure"] [])
   331      reload_changed (load_order ["Pure"] [])
   328   end;
   332   end;
   329 
   333 
   330 (*Merge theories to build a base for a new theory.
   334 (*Merge theories to build a base for a new theory.
   343 
   347 
   344           (*Show the cycle that would be created by add_child *)
   348           (*Show the cycle that would be created by add_child *)
   345           fun show_cycle base =
   349           fun show_cycle base =
   346             let fun find_it result curr =
   350             let fun find_it result curr =
   347                   let val tinfo = get_thyinfo curr
   351                   let val tinfo = get_thyinfo curr
   348                   in if base = curr then 
   352                   in if base = curr then
   349                        error ("Cyclic dependency of theories: "
   353                        error ("Cyclic dependency of theories: "
   350                               ^ child ^ "->" ^ base ^ result)
   354                               ^ child ^ "->" ^ base ^ result)
   351                      else if is_some tinfo then
   355                      else if is_some tinfo then
   352                        let val ThyInfo {children, ...} = the tinfo
   356                        let val ThyInfo {children, ...} = the tinfo
   353                        in seq (find_it ("->" ^ curr ^ result)) children
   357                        in seq (find_it ("->" ^ curr ^ result)) children
   354                        end
   358                        end
   355                      else ()
   359                      else ()
   356                   end
   360                   end
   357             in find_it "" child end;
   361             in find_it "" child end;
   358         
   362 
   359           (*Check if a cycle would be created by add_child *)
   363           (*Check if a cycle would be created by add_child *)
   360           fun find_cycle base =
   364           fun find_cycle base =
   361             if base mem (list_descendants [child]) then show_cycle base
   365             if base mem (list_descendants [child]) then show_cycle base
   362             else ();
   366             else ();
   363                    
   367 
   364           (*Add child to child list of base *)
   368           (*Add child to child list of base *)
   365           fun add_child base =
   369           fun add_child base =
   366             let val tinfo =
   370             let val tinfo =
   367                   case lookup (!loaded_thys, base) of
   371                   case Symtab.lookup (!loaded_thys, base) of
   368                       Some (ThyInfo {path, children, thy_time, ml_time, 
   372                       Some (ThyInfo {path, children, thy_time, ml_time,
   369                                      theory, thms}) =>
   373                                      theory, thms}) =>
   370                         ThyInfo {path = path, children = child ins children,
   374                         ThyInfo {path = path, children = child ins children,
   371                                  thy_time = thy_time, ml_time = ml_time,
   375                                  thy_time = thy_time, ml_time = ml_time,
   372                                  theory = theory, thms = thms}
   376                                  theory = theory, thms = thms}
   373                     | None => ThyInfo {path = "", children = [child],
   377                     | None => ThyInfo {path = "", children = [child],
   374                                        thy_time = None, ml_time = None, 
   378                                        thy_time = None, ml_time = None,
   375                                        theory = None, thms = null};
   379                                        theory = None, thms = Symtab.null};
   376             in loaded_thys := Symtab.update ((base, tinfo), !loaded_thys) end;
   380             in loaded_thys := Symtab.update ((base, tinfo), !loaded_thys) end;
   377 
   381 
   378           (*Load a base theory if not already done
   382           (*Load a base theory if not already done
   379             and no cycle would be created *)
   383             and no cycle would be created *)
   380           fun load base =
   384           fun load base =
   382                                            (*test this before child is added *)
   386                                            (*test this before child is added *)
   383               in
   387               in
   384                 if child = base then
   388                 if child = base then
   385                     error ("Cyclic dependency of theories: " ^ child
   389                     error ("Cyclic dependency of theories: " ^ child
   386                            ^ "->" ^ child)
   390                            ^ "->" ^ child)
   387                 else 
   391                 else
   388                   (find_cycle base;
   392                   (find_cycle base;
   389                    add_child base;
   393                    add_child base;
   390                    if thy_present then ()
   394                    if thy_present then ()
   391                    else (writeln ("Autoloading theory " ^ (quote base)
   395                    else (writeln ("Autoloading theory " ^ (quote base)
   392                                   ^ " (used by " ^ (quote child) ^ ")");
   396                                   ^ " (used by " ^ (quote child) ^ ")");
   393                          use_thy base)
   397                          use_thy base)
   394                   )
   398                   )
   395               end; 
   399               end;
   396 
   400 
   397           (*Load all needed files and make a list of all real theories *)
   401           (*Load all needed files and make a list of all real theories *)
   398           fun load_base (Thy b :: bs) =
   402           fun load_base (Thy b :: bs) =
   399                (load b;
   403                (load b;
   400                 b :: (load_base bs))
   404                 b :: (load_base bs))
   411           val mergelist = (unlink_thy child;
   415           val mergelist = (unlink_thy child;
   412                            load_base bases);
   416                            load_base bases);
   413      in writeln ("Loading theory " ^ (quote child));
   417      in writeln ("Loading theory " ^ (quote child));
   414         merge_thy_list mk_draft (map get_theory mergelist) end;
   418         merge_thy_list mk_draft (map get_theory mergelist) end;
   415 
   419 
   416 (*Change theory object for an existent item of loaded_thys 
   420 (*Change theory object for an existent item of loaded_thys
   417   or create a new item *)
   421   or create a new item *)
   418 fun store_theory (thy, tname) =
   422 fun store_theory (thy, tname) =
   419   let val tinfo = case lookup (!loaded_thys, tname) of 
   423   let val tinfo = case Symtab.lookup (!loaded_thys, tname) of
   420                Some (ThyInfo {path, children, thy_time, ml_time, thms, ...}) =>
   424                Some (ThyInfo {path, children, thy_time, ml_time, thms, ...}) =>
   421                  ThyInfo {path = path, children = children,
   425                  ThyInfo {path = path, children = children,
   422                           thy_time = thy_time, ml_time = ml_time,
   426                           thy_time = thy_time, ml_time = ml_time,
   423                           theory = Some thy, thms = thms}
   427                           theory = Some thy, thms = thms}
   424              | None => ThyInfo {path = "", children = [],
   428              | None => ThyInfo {path = "", children = [],
   425                                 thy_time = Some "", ml_time = Some "",
   429                                 thy_time = Some "", ml_time = Some "",
   426                                 theory = Some thy, thms = null};
   430                                 theory = Some thy, thms = Symtab.null};
   427   in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys) end;
   431   in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys) end;
   428 
   432 
   429 (*Store a theorem in the ThyInfo of the theory it is associated with*)
   433 
   430 fun store_thm (thm, tname) =
   434 
   431   let val thy_name = !(hd (stamps_of_thm thm));
   435 (** store and retrieve theorems **)
   432 
   436 
   433       val ThyInfo {path, children, thy_time, ml_time, theory, thms} =
   437 (* thyinfo_of_sign *)
   434         case get_thyinfo thy_name of
   438 
   435             Some tinfo => tinfo
   439 fun thyinfo_of_sign sg =
   436           | None => error ("store_thm: Theory \"" ^ thy_name 
   440   let
   437                            ^ "\" is not stored in loaded_thys");
   441     val ref xname = hd (#stamps (Sign.rep_sg sg));
   438   in loaded_thys := 
   442     val opt_info = get_thyinfo xname;
   439        Symtab.update ((thy_name, ThyInfo {path = path, children = children,
   443 
   440                                    thy_time = thy_time, ml_time = ml_time,
   444     fun eq_sg (ThyInfo {theory = None, ...}) = false
   441                                    theory = theory, 
   445       | eq_sg (ThyInfo {theory = Some thy, ...}) = Sign.eq_sg (sg, sign_of thy);
   442                                    thms = Symtab.update ((tname, thm), thms)}),
   446 
   443                       !loaded_thys);
   447     val show_sg = Pretty.str_of o Sign.pretty_sg;
   444      thm
   448   in
   445   end;
   449     if is_some opt_info andalso eq_sg (the opt_info) then
   446 
   450       (xname, the opt_info)
   447 (*Store theorem in loaded_thys and a ML variable*)
   451     else
   448 fun qed name = use_string ["val " ^ name ^ " = store_thm (result(), "
   452       (case Symtab.find_first (eq_sg o snd) (! loaded_thys) of
   449                            ^ quote name ^ ");"];
   453         Some name_info => name_info
   450 
   454       | None => error ("Theory " ^ show_sg sg ^ " not stored by loader"))
   451 fun name_of_thy thy = !(hd (stamps_of_thy thy));
   455   end;
   452 
   456 
   453 (*Retrieve a theorem specified by theory and name*)
   457 
   454 fun get_thm thy tname =
   458 (* theory_of_sign, theory_of_thm *)
   455   let val thy_name = name_of_thy thy;
   459 
   456 
   460 fun theory_of_sign sg =
   457       val ThyInfo {thms, ...} = 
   461   (case thyinfo_of_sign sg of
   458         case get_thyinfo thy_name of
   462     (_, ThyInfo {theory = Some thy, ...}) => thy
   459             Some tinfo => tinfo
   463   | _ => sys_error "theory_of_sign");
   460           | None => error ("get_thm: Theory \"" ^ thy_name
   464 
   461                            ^ "\" is not stored in loaded_thys");
   465 val theory_of_thm = theory_of_sign o #sign o rep_thm;
   462   in the (lookup (thms, tname)) end;
   466 
   463 
   467 
   464 (*Retrieve all theorems belonging to the specified theory*)
   468 (* store theorems *)
   465 fun get_thms thy =
   469 
   466   let val thy_name = name_of_thy thy;
   470 (*store a theorem in the thy_info of its theory*)
   467 
   471 fun store_thm (name, thm) =
   468       val ThyInfo {thms, ...} = 
   472   let
   469         case get_thyinfo thy_name of
   473     val (thy_name, ThyInfo {path, children, thy_time, ml_time, theory, thms}) =
   470             Some tinfo => tinfo
   474       thyinfo_of_sign (#sign (rep_thm thm));
   471           | None => error ("get_thms: Theory \"" ^ thy_name
   475     val thms' = Symtab.update_new ((name, thm), thms)
   472                            ^ "\" is not stored in loaded_thys");
   476       handle Symtab.DUPLICATE s => error ("Duplicate theorem name " ^ quote s);
   473   in alist_of thms end;
   477   in
       
   478     loaded_thys := Symtab.update
       
   479       ((thy_name, ThyInfo {path = path, children = children,
       
   480         thy_time = thy_time, ml_time = ml_time, theory = theory, thms = thms'}),
       
   481         ! loaded_thys);
       
   482     thm
       
   483   end;
       
   484 
       
   485 (*store result of proof in loaded_thys and as ML value*)
       
   486 fun qed name =
       
   487   use_string ["val " ^ name ^ " = store_thm (" ^ quote name ^ ", result ());"];
       
   488 
       
   489 
       
   490 (* retrieve theorems *)
       
   491 
       
   492 fun thmtab thy =
       
   493   let val (_, ThyInfo {thms, ...}) = thyinfo_of_sign (sign_of thy)
       
   494   in thms end;
       
   495 
       
   496 (*get a stored theorem specified by theory and name*)
       
   497 fun get_thm thy name =
       
   498   (case Symtab.lookup (thmtab thy, name) of
       
   499     Some thm => thm
       
   500   | None => raise THEORY ("get_thm: no theorem " ^ quote name, [thy]));
       
   501 
       
   502 (*get stored theorems of a theory*)
       
   503 val thms_of = Symtab.dest o thmtab;
       
   504 
       
   505 
   474 end;
   506 end;
       
   507