src/Pure/Thy/thy_read.ML
changeset 1262 8f40ff1299d8
parent 1244 3d408455d69f
child 1291 e173be970d27
equal deleted inserted replaced
1261:af4107a03150 1262:8f40ff1299d8
    13                                 children: string list,
    13                                 children: string list,
    14                                 thy_time: string option,
    14                                 thy_time: string option,
    15                                 ml_time: string option,
    15                                 ml_time: string option,
    16                                 theory: theory option,
    16                                 theory: theory option,
    17                                 thms: thm Symtab.table,
    17                                 thms: thm Symtab.table,
    18                                 thy_simps: thm list, ml_simps: thm list};
    18                                 thy_ss: Simplifier.simpset option,
       
    19                                 simpset: Simplifier.simpset option};
    19       (*meaning of special values:
    20       (*meaning of special values:
    20         thy_time, ml_time = None     theory file has not been read yet
    21         thy_time, ml_time = None     theory file has not been read yet
    21                           = Some ""  theory was read but has either been marked
    22                           = Some ""  theory was read but has either been marked
    22                                      as outdated or there is no such file for
    23                                      as outdated or there is no such file for
    23                                      this theory (see e.g. 'virtual' theories
    24                                      this theory (see e.g. 'virtual' theories
    50   val qed_goal: string -> theory -> string -> (thm list -> tactic list) -> unit
    51   val qed_goal: string -> theory -> string -> (thm list -> tactic list) -> unit
    51   val qed_goalw: string -> theory->thm list->string->(thm list->tactic list)
    52   val qed_goalw: string -> theory->thm list->string->(thm list->tactic list)
    52                  -> unit
    53                  -> unit
    53   val get_thm: theory -> string -> thm
    54   val get_thm: theory -> string -> thm
    54   val thms_of: theory -> (string * thm) list
    55   val thms_of: theory -> (string * thm) list
       
    56   val simpset_of: string -> Simplifier.simpset
    55   val print_theory: theory -> unit
    57   val print_theory: theory -> unit
    56 end;
    58 end;
    57 
    59 
    58 
    60 
    59 functor ReadthyFUN(structure ThySyn: THY_SYN and ThmDB: THMDB
    61 functor ReadthyFun(structure ThySyn: THY_SYN and ThmDB: THMDB): READTHY =
    60                    and Simplifier: SIMPLIFIER): READTHY =
       
    61 struct
    62 struct
    62 
    63 
    63 open ThmDB Simplifier;
    64 open ThmDB Simplifier;
    64 
    65 
    65 datatype basetype = Thy  of string
    66 datatype basetype = Thy  of string
    69                                      ThyInfo {path = "",
    70                                      ThyInfo {path = "",
    70                                        children = ["Pure", "CPure"],
    71                                        children = ["Pure", "CPure"],
    71                                        thy_time = Some "", ml_time = Some "",
    72                                        thy_time = Some "", ml_time = Some "",
    72                                        theory = Some proto_pure_thy,
    73                                        theory = Some proto_pure_thy,
    73                                        thms = Symtab.null,
    74                                        thms = Symtab.null,
    74                                        thy_simps = [], ml_simps = []}),
    75                                        thy_ss = None, simpset = None}),
    75                                     ("Pure", ThyInfo {path = "", children = [],
    76                                     ("Pure", ThyInfo {path = "", children = [],
    76                                        thy_time = Some "", ml_time = Some "",
    77                                        thy_time = Some "", ml_time = Some "",
    77                                        theory = Some pure_thy,
    78                                        theory = Some pure_thy,
    78                                        thms = Symtab.null,
    79                                        thms = Symtab.null,
    79                                        thy_simps = [], ml_simps = []}),
    80                                        thy_ss = None, simpset = None}),
    80                                     ("CPure", ThyInfo {path = "",
    81                                     ("CPure", ThyInfo {path = "",
    81                                        children = [],
    82                                        children = [],
    82                                        thy_time = Some "", ml_time = Some "",
    83                                        thy_time = Some "", ml_time = Some "",
    83                                        theory = Some cpure_thy,
    84                                        theory = Some cpure_thy,
    84                                        thms = Symtab.null,
    85                                        thms = Symtab.null,
    85                                        thy_simps = [], ml_simps = []})]);
    86                                        thy_ss = None, simpset = None})
       
    87                                    ]);
    86 
    88 
    87 val loadpath = ref ["."];           (*default search path for theory files *)
    89 val loadpath = ref ["."];           (*default search path for theory files *)
    88 
    90 
    89 val delete_tmpfiles = ref true;         (*remove temporary files after use *)
    91 val delete_tmpfiles = ref true;         (*remove temporary files after use *)
    90 
    92 
   132           else
   134           else
   133             (false, false)
   135             (false, false)
   134        end
   136        end
   135     | None => (false, false)
   137     | None => (false, false)
   136 
   138 
   137 (*Get list of simplifiers defined in .thy and .ML file*)
       
   138 fun get_simps tname =
       
   139   case get_thyinfo tname of
       
   140       Some (ThyInfo {thy_simps, ml_simps, ...}) => (thy_simps, ml_simps)
       
   141     | None => ([], []);
       
   142 
       
   143 (*Get all direct ancestors of a theory*)
   139 (*Get all direct ancestors of a theory*)
   144 fun get_parents child =
   140 fun get_parents child =
   145   let fun has_child (tname, ThyInfo {children, theory, ...}) = 
   141   let fun has_child (tname, ThyInfo {children, theory, ...}) = 
   146         if child mem children then Some tname else None;
   142         if child mem children then Some tname else None;
   147   in mapfilter has_child (Symtab.dest (!loaded_thys)) end;
   143   in mapfilter has_child (Symtab.dest (!loaded_thys)) end;
       
   144 
       
   145 (*Get all descendants of a theory list *)
       
   146 fun get_descendants [] = []
       
   147   | get_descendants (t :: ts) =
       
   148       let val tinfo = get_thyinfo t
       
   149       in if is_some tinfo then
       
   150            let val ThyInfo {children, ...} = the tinfo
       
   151            in children union (get_descendants (children union ts))
       
   152            end
       
   153          else []
       
   154       end;
   148 
   155 
   149 (*Get theory object for a loaded theory *)
   156 (*Get theory object for a loaded theory *)
   150 fun get_theory name =
   157 fun get_theory name =
   151   let val ThyInfo {theory, ...} = the (get_thyinfo name)
   158   let val ThyInfo {theory, ...} = the (get_thyinfo name)
   152   in the theory end;
   159   in the theory end;
   211   end;
   218   end;
   212 
   219 
   213 (*Remove theory from all child lists in loaded_thys *)
   220 (*Remove theory from all child lists in loaded_thys *)
   214 fun unlink_thy tname =
   221 fun unlink_thy tname =
   215   let fun remove (ThyInfo {path, children, thy_time, ml_time, theory, thms,
   222   let fun remove (ThyInfo {path, children, thy_time, ml_time, theory, thms,
   216                            thy_simps, ml_simps}) =
   223                            thy_ss, simpset}) =
   217         ThyInfo {path = path, children = children \ tname,
   224         ThyInfo {path = path, children = children \ tname,
   218                  thy_time = thy_time, ml_time = ml_time, theory = theory, 
   225                  thy_time = thy_time, ml_time = ml_time, theory = theory, 
   219                  thms = thms, thy_simps = thy_simps, ml_simps = ml_simps}
   226                  thms = thms, thy_ss = thy_ss, simpset = simpset}
   220   in loaded_thys := Symtab.map remove (!loaded_thys) end;
   227   in loaded_thys := Symtab.map remove (!loaded_thys) end;
   221 
   228 
   222 (*Remove a theory from loaded_thys *)
   229 (*Remove a theory from loaded_thys *)
   223 fun remove_thy tname =
   230 fun remove_thy tname =
   224   loaded_thys := Symtab.make (filter_out (fn (id, _) => id = tname)
   231   loaded_thys := Symtab.make (filter_out (fn (id, _) => id = tname)
   225                  (Symtab.dest (!loaded_thys)));
   232                  (Symtab.dest (!loaded_thys)));
   226 
   233 
   227 (*Change thy_time and ml_time for an existent item *)
   234 (*Change thy_time and ml_time for an existent item *)
   228 fun set_info thy_time ml_time tname =
   235 fun set_info tname thy_time ml_time =
   229   let val ThyInfo {path, children, theory, thms, thy_simps, ml_simps, ...} =
   236   let val tinfo = case Symtab.lookup (!loaded_thys, tname) of
   230         the (Symtab.lookup (!loaded_thys, tname));
   237           Some (ThyInfo {path, children, theory, thms, thy_ss, simpset,...}) =>
   231   in loaded_thys := Symtab.update
   238             ThyInfo {path = path, children = children,
   232        ((tname,
   239                      thy_time = thy_time, ml_time = ml_time,
   233          ThyInfo {path = path, children = children, thy_time = thy_time,
   240                      theory = theory, thms = thms,
   234                   ml_time = ml_time, theory = theory, thms = thms,
   241                      thy_ss = thy_ss, simpset = simpset}
   235                   thy_simps = thy_simps, ml_simps = ml_simps}),
   242         | None => ThyInfo {path = "", children = [],
   236         !loaded_thys)
   243                            thy_time = thy_time, ml_time = ml_time,
       
   244                            theory = None, thms = Symtab.null,
       
   245                            thy_ss = None, simpset = None};
       
   246   in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys)
   237   end;
   247   end;
   238 
   248 
   239 (*Mark theory as changed since last read if it has been completly read *)
   249 (*Mark theory as changed since last read if it has been completly read *)
   240 fun mark_outdated tname =
   250 fun mark_outdated tname =
   241   let val t = get_thyinfo tname;
   251   let val t = get_thyinfo tname;
   242   in if is_none t then ()
   252   in if is_none t then ()
   243      else let val ThyInfo {thy_time, ml_time, ...} = the t
   253      else let val ThyInfo {thy_time, ml_time, ...} = the t
   244           in set_info (if is_none thy_time then None else Some "")
   254           in set_info tname
       
   255                       (if is_none thy_time then None else Some "")
   245                       (if is_none ml_time then None else Some "")
   256                       (if is_none ml_time then None else Some "")
   246                       tname
   257                       
   247           end
   258           end
   248   end;
   259   end;
   249 
   260 
   250 (*Read .thy and .ML files that haven't been read yet or have changed since
   261 (*Read .thy and .ML files that haven't been read yet or have changed since
   251   they were last read;
   262   they were last read;
   257     val (path, tname) = split_filename name;
   268     val (path, tname) = split_filename name;
   258     val (thy_file, ml_file) = get_filenames path tname;
   269     val (thy_file, ml_file) = get_filenames path tname;
   259     val (abs_path, _) = if thy_file = "" then split_filename ml_file
   270     val (abs_path, _) = if thy_file = "" then split_filename ml_file
   260                         else split_filename thy_file;
   271                         else split_filename thy_file;
   261     val (thy_uptodate, ml_uptodate) = thy_unchanged tname thy_file ml_file;
   272     val (thy_uptodate, ml_uptodate) = thy_unchanged tname thy_file ml_file;
   262     val (thy_simps, ml_simps) = get_simps tname;
       
   263     val old_simps = ref [];
       
   264 
   273 
   265     (*Set absolute path for loaded theory *)
   274     (*Set absolute path for loaded theory *)
   266     fun set_path () =
   275     fun set_path () =
   267       let val ThyInfo {children, thy_time, ml_time, theory, thms,
   276       let val ThyInfo {children, thy_time, ml_time, theory, thms, thy_ss,
   268                        thy_simps, ml_simps, ...} =
   277                        simpset, ...} =
   269             the (Symtab.lookup (!loaded_thys, tname));
   278             the (Symtab.lookup (!loaded_thys, tname));
   270       in loaded_thys := Symtab.update ((tname,
   279       in loaded_thys := Symtab.update ((tname,
   271                           ThyInfo {path = abs_path, children = children,
   280                           ThyInfo {path = abs_path, children = children,
   272                                    thy_time = thy_time, ml_time = ml_time,
   281                                    thy_time = thy_time, ml_time = ml_time,
   273                                    theory = theory, thms = thms,
   282                                    theory = theory, thms = thms,
   274                                    thy_simps = thy_simps,
   283                                    thy_ss = thy_ss, simpset = simpset}),
   275                                    ml_simps = ml_simps}),
       
   276                           !loaded_thys)
   284                           !loaded_thys)
   277       end;
   285       end;
   278 
   286 
   279     (*Mark all direct descendants of a theory as changed *)
   287     (*Mark all direct descendants of a theory as changed *)
   280     fun mark_children thy =
   288     fun mark_children thy =
   291 
   299 
   292     (*Remove theorems associated with a theory*)
   300     (*Remove theorems associated with a theory*)
   293     fun delete_thms () =
   301     fun delete_thms () =
   294       let
   302       let
   295         val tinfo = case get_thyinfo tname of
   303         val tinfo = case get_thyinfo tname of
   296             Some (ThyInfo {path, children, thy_time, ml_time, theory,
   304             Some (ThyInfo {path, children, thy_time, ml_time, theory, thy_ss,
   297                            thy_simps, ml_simps, ...}) =>
   305                            simpset, ...}) =>
   298                 ThyInfo {path = path, children = children,
   306               ThyInfo {path = path, children = children,
   299                          thy_time = thy_time, ml_time = ml_time,
   307                        thy_time = thy_time, ml_time = ml_time,
   300                          theory = theory, thms = Symtab.null,
   308                        theory = theory, thms = Symtab.null,
   301                          thy_simps = thy_simps, ml_simps = ml_simps}
   309                        thy_ss = thy_ss, simpset = simpset}
   302           | None => ThyInfo {path = "", children = [],
   310           | None => ThyInfo {path = "", children = [],
   303                              thy_time = None, ml_time = None,
   311                              thy_time = None, ml_time = None,
   304                              theory = None, thms = Symtab.null,
   312                              theory = None, thms = Symtab.null,
   305                              thy_simps = [], ml_simps = []};
   313                              thy_ss = None, simpset = None};
   306       in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys) end;
   314 
   307 
   315         val ThyInfo {theory, ...} = tinfo;
   308     fun update_simps (new_thy_simps, new_ml_simps) =
   316       in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys);
       
   317          case theory of
       
   318              Some t => delete_thm_db t
       
   319            | None => ()
       
   320       end;
       
   321 
       
   322     fun save_thy_ss () =
   309       let val ThyInfo {path, children, thy_time, ml_time, theory, thms,
   323       let val ThyInfo {path, children, thy_time, ml_time, theory, thms,
   310                        thy_simps, ml_simps} = the (get_thyinfo tname);
   324                        simpset, ...} = the (get_thyinfo tname);
   311 
   325       in loaded_thys := Symtab.update
   312           val (thy_simps',  ml_simps') =
   326            ((tname, ThyInfo {path = path, children = children,
   313             (if is_none new_thy_simps then thy_simps else the new_thy_simps,
   327                              thy_time = thy_time, ml_time = ml_time,
   314              if is_none new_ml_simps then ml_simps else the new_ml_simps);
   328                              theory = theory, thms = thms,
   315       in loaded_thys := Symtab.update ((tname,
   329                              thy_ss = Some (!Simplifier.simpset),
   316            ThyInfo {path = path, children = children,
   330                              simpset = simpset}),
   317                     thy_time = thy_time, ml_time = ml_time, theory = theory,
   331             !loaded_thys)
   318                     thms = thms, thy_simps = thy_simps',
   332       end;
   319                     ml_simps = ml_simps'}), !loaded_thys)
   333 
       
   334     fun save_simpset () =
       
   335       let val ThyInfo {path, children, thy_time, ml_time, theory, thms,
       
   336                        thy_ss, ...} = the (get_thyinfo tname);
       
   337       in loaded_thys := Symtab.update
       
   338            ((tname, ThyInfo {path = path, children = children,
       
   339                              thy_time = thy_time, ml_time = ml_time,
       
   340                              theory = theory, thms = thms,
       
   341                              thy_ss = thy_ss,
       
   342                              simpset = Some (!Simplifier.simpset)}),
       
   343             !loaded_thys)
   320       end;
   344       end;
   321 
   345 
   322   in if thy_uptodate andalso ml_uptodate then ()
   346   in if thy_uptodate andalso ml_uptodate then ()
   323      else
   347      else
   324      (
   348      (
   325        delete_thms ();
   349        if thy_file = "" then ()
   326 
   350        else if thy_uptodate then
   327        if thy_uptodate orelse thy_file = "" then
   351          simpset := let val ThyInfo {thy_ss, ...} = the (get_thyinfo tname);
   328          (Delsimps ml_simps;
   352                     in the thy_ss end
   329           old_simps := #simps(rep_ss (!simpset));
       
   330           update_simps (None, Some []))
       
   331        else
   353        else
   332          (writeln ("Reading \"" ^ name ^ ".thy\"");
   354          (writeln ("Reading \"" ^ name ^ ".thy\"");
   333           Delsimps (thy_simps @ ml_simps);
   355           delete_thms ();
   334           old_simps := #simps(rep_ss (!simpset));
       
   335           update_simps (Some [], Some []);  (*clear simp lists in case use_thy
       
   336                                               encounters an EROR exception*)
       
   337           read_thy tname thy_file;
   356           read_thy tname thy_file;
   338           use (out_name tname);
   357           use (out_name tname);
       
   358           save_thy_ss ();
   339 
   359 
   340           if not (!delete_tmpfiles) then ()
   360           if not (!delete_tmpfiles) then ()
   341           else delete_file (out_name tname);
   361           else delete_file (out_name tname)
   342 
       
   343           update_simps
       
   344             (Some (gen_rems same_thm (#simps(rep_ss (!simpset)), !old_simps)),
       
   345              None);
       
   346           old_simps := #simps(rep_ss (!simpset))
       
   347          );
   362          );
   348 
   363 
   349        set_info (Some (file_info thy_file)) None tname;
   364        set_info tname (Some (file_info thy_file)) None;
   350                                        (*mark thy_file as successfully loaded*)
   365                                        (*mark thy_file as successfully loaded*)
   351 
   366 
   352        if ml_file = "" then ()
   367        if ml_file = "" then ()
   353        else
   368        else (writeln ("Reading \"" ^ name ^ ".ML\"");
   354          (writeln ("Reading \"" ^ name ^ ".ML\"");
   369              use ml_file);
   355           use ml_file;
   370        save_simpset ();
   356 
   371 
   357           update_simps (None,
   372        (*Store theory again because it could have been redefined*)
   358             Some (gen_rems same_thm (#simps(rep_ss (!simpset)), !old_simps)))
   373        use_string
   359          );
   374          ["val _ = store_theory (" ^ tname ^ ".thy, " ^ quote tname ^ ");"];
   360 
   375 
   361          use_string
   376        (*Store axioms of theory
   362            ["val _ = (store_theory (" ^ tname ^ ".thy, " ^ quote tname ^ ");\
   377          (but only if it's not a copy of an older theory)*)
   363             \map store_thm_db (axioms_of " ^ tname ^ ".thy));"];
   378        let val parents = get_parents tname;
   364                     (*Store theory again because it could have been redefined*)
   379            val fst_thy = get_theory (hd parents);
       
   380            val this_thy = get_theory tname;
       
   381            val axioms =
       
   382              if length parents = 1
       
   383                 andalso Sign.eq_sg (sign_of fst_thy, sign_of this_thy) then []
       
   384              else axioms_of this_thy;
       
   385        in map store_thm_db axioms end;
   365 
   386 
   366        (*Now set the correct info*)
   387        (*Now set the correct info*)
   367        set_info (Some (file_info thy_file)) (Some (file_info ml_file)) tname;
   388        set_info tname (Some (file_info thy_file)) (Some (file_info ml_file));
   368        set_path ();
   389        set_path ();
   369 
   390 
   370        (*Mark theories that have to be reloaded*)
   391        (*Mark theories that have to be reloaded*)
   371        mark_children tname
   392        mark_children tname
   372       )
   393       )
   414         | reload_changed [] = ();
   435         | reload_changed [] = ();
   415 
   436 
   416      (*Remove all theories that are no descendants of ProtoPure.
   437      (*Remove all theories that are no descendants of ProtoPure.
   417        If there are still children in the deleted theory's list
   438        If there are still children in the deleted theory's list
   418        schedule them for reloading *)
   439        schedule them for reloading *)
   419      fun collect_garbage not_garbage =
   440      fun collect_garbage no_garbage =
   420        let fun collect ((tname, ThyInfo {children, ...}) :: ts) =
   441        let fun collect ((tname, ThyInfo {children, ...}) :: ts) =
   421                  if tname mem not_garbage then collect ts
   442                  if tname mem no_garbage then collect ts
   422                  else (writeln ("Theory \"" ^ tname ^
   443                  else (writeln ("Theory \"" ^ tname ^
   423                        "\" is no longer linked with ProtoPure - removing it.");
   444                        "\" is no longer linked with ProtoPure - removing it.");
   424                        remove_thy tname;
   445                        remove_thy tname;
   425                        seq mark_outdated children)
   446                        seq mark_outdated children)
   426              | collect [] = ()
   447              | collect [] = ()
   427 
       
   428        in collect (Symtab.dest (!loaded_thys)) end;
   448        in collect (Symtab.dest (!loaded_thys)) end;
   429   in collect_garbage ("ProtoPure" :: (load_order ["ProtoPure"] []));
   449   in collect_garbage ("ProtoPure" :: (load_order ["ProtoPure"] []));
   430      reload_changed (load_order ["Pure", "CPure"] [])
   450      reload_changed (load_order ["Pure", "CPure"] [])
   431   end;
   451   end;
   432 
   452 
   433 (*Merge theories to build a base for a new theory.
   453 (*Merge theories to build a base for a new theory.
   434   Base members are only loaded if they are missing. *)
   454   Base members are only loaded if they are missing.*)
   435 fun mk_base bases child mk_draft =
   455 fun mk_base bases child mk_draft =
   436       let (*List all descendants of a theory list *)
   456   let (*Show the cycle that would be created by add_child *)
   437           fun list_descendants (t :: ts) =
   457       fun show_cycle base =
   438                 let val tinfo = get_thyinfo t
   458         let fun find_it result curr =
   439                 in if is_some tinfo then
   459               let val tinfo = get_thyinfo curr
   440                      let val ThyInfo {children, ...} = the tinfo
   460               in if base = curr then
   441                      in children union (list_descendants (ts union children))
   461                    error ("Cyclic dependency of theories: "
   442                      end
   462                           ^ child ^ "->" ^ base ^ result)
   443                    else []
   463                  else if is_some tinfo then
   444                 end
   464                    let val ThyInfo {children, ...} = the tinfo
   445             | list_descendants [] = [];
   465                    in seq (find_it ("->" ^ curr ^ result)) children
   446 
   466                    end
   447           (*Show the cycle that would be created by add_child *)
   467                  else ()
   448           fun show_cycle base =
   468               end
   449             let fun find_it result curr =
   469         in find_it "" child end;
   450                   let val tinfo = get_thyinfo curr
   470 
   451                   in if base = curr then
   471       (*Check if a cycle would be created by add_child *)
   452                        error ("Cyclic dependency of theories: "
   472       fun find_cycle base =
   453                               ^ child ^ "->" ^ base ^ result)
   473         if base mem (get_descendants [child]) then show_cycle base
   454                      else if is_some tinfo then
   474         else ();
   455                        let val ThyInfo {children, ...} = the tinfo
   475 
   456                        in seq (find_it ("->" ^ curr ^ result)) children
   476       (*Add child to child list of base *)
   457                        end
   477       fun add_child base =
   458                      else ()
   478         let val tinfo =
   459                   end
   479               case Symtab.lookup (!loaded_thys, base) of
   460             in find_it "" child end;
   480                   Some (ThyInfo {path, children, thy_time, ml_time,
   461 
   481                            theory, thms, thy_ss, simpset}) =>
   462           (*Check if a cycle would be created by add_child *)
   482                     ThyInfo {path = path, children = child ins children,
   463           fun find_cycle base =
   483                              thy_time = thy_time, ml_time = ml_time,
   464             if base mem (list_descendants [child]) then show_cycle base
   484                              theory = theory, thms = thms,
   465             else ();
   485                              thy_ss = thy_ss, simpset = simpset}
   466 
   486                 | None => ThyInfo {path = "", children = [child],
   467           (*Add child to child list of base *)
   487                                    thy_time = None, ml_time = None,
   468           fun add_child base =
   488                                    theory = None, thms = Symtab.null,
   469             let val tinfo =
   489                                    thy_ss = None, simpset = None};
   470                   case Symtab.lookup (!loaded_thys, base) of
   490         in loaded_thys := Symtab.update ((base, tinfo), !loaded_thys) end;
   471                       Some (ThyInfo {path, children, thy_time, ml_time,
   491 
   472                                      theory, thms, thy_simps, ml_simps}) =>
   492       (*Load a base theory if not already done
   473                         ThyInfo {path = path, children = child ins children,
   493         and no cycle would be created *)
   474                                  thy_time = thy_time, ml_time = ml_time,
   494       fun load base =
   475                                  theory = theory, thms = thms,
   495           let val thy_loaded = already_loaded base
   476                                  thy_simps = thy_simps, ml_simps = ml_simps}
   496                                        (*test this before child is added *)
   477                     | None => ThyInfo {path = "", children = [child],
   497           in
   478                                        thy_time = None, ml_time = None,
   498             if child = base then
   479                                        theory = None, thms = Symtab.null,
   499                 error ("Cyclic dependency of theories: " ^ child
   480                                        thy_simps = [], ml_simps = []};
   500                        ^ "->" ^ child)
   481             in loaded_thys := Symtab.update ((base, tinfo), !loaded_thys) end;
   501             else
   482 
   502               (find_cycle base;
   483           (*Load a base theory if not already done
   503                add_child base;
   484             and no cycle would be created *)
   504                if thy_loaded then ()
   485           fun load base =
   505                else (writeln ("Autoloading theory " ^ (quote base)
   486               let val thy_loaded = already_loaded base
   506                               ^ " (used by " ^ (quote child) ^ ")");
   487                                            (*test this before child is added *)
   507                      use_thy base)
   488               in
   508               )
   489                 if child = base then
   509           end;
   490                     error ("Cyclic dependency of theories: " ^ child
   510 
   491                            ^ "->" ^ child)
   511       (*Get simpset for a theory*)
   492                 else
   512       fun get_simpset tname =
   493                   (find_cycle base;
   513         let val ThyInfo {simpset, ...} = the (get_thyinfo tname);
   494                    add_child base;
   514         in simpset end;
   495                    if thy_loaded then ()
   515 
   496                    else (writeln ("Autoloading theory " ^ (quote base)
   516       (*Load all needed files and make a list of all real theories *)
   497                                   ^ " (used by " ^ (quote child) ^ ")");
   517       fun load_base (Thy b :: bs) =
   498                          use_thy base)
   518            (load b;
   499                   )
   519             b :: (load_base bs))
   500               end;
   520         | load_base (File b :: bs) =
   501 
   521            (load b;
   502           (*Load all needed files and make a list of all real theories *)
   522             load_base bs)                    (*don't add it to mergelist *)
   503           fun load_base (Thy b :: bs) =
   523         | load_base [] = [];
   504                (load b;
   524 
   505                 b :: (load_base bs))
   525       val dummy = unlink_thy child;
   506             | load_base (File b :: bs) =
   526       val mergelist = load_base bases;
   507                (load b;
   527 
   508                 load_base bs)                    (*don't add it to mergelist *)
   528       val base_thy = (writeln ("Loading theory " ^ (quote child));
   509             | load_base [] = [];
   529                       merge_thy_list mk_draft (map get_theory mergelist));
   510 
   530  in simpset := foldr merge_ss (mapfilter get_simpset mergelist, empty_ss);
   511           val mergelist = (unlink_thy child;
   531     base_thy
   512                            load_base bases);
   532  end;
   513      in writeln ("Loading theory " ^ (quote child));
       
   514         merge_thy_list mk_draft (map get_theory mergelist) end;
       
   515 
   533 
   516 (*Change theory object for an existent item of loaded_thys
   534 (*Change theory object for an existent item of loaded_thys
   517   or create a new item; also store axioms in Thm database*)
   535   or create a new item*)
   518 fun store_theory (thy, tname) =
   536 fun store_theory (thy, tname) =
   519   let val tinfo = case Symtab.lookup (!loaded_thys, tname) of
   537   let val tinfo = case Symtab.lookup (!loaded_thys, tname) of
   520                Some (ThyInfo {path, children, thy_time, ml_time, thms,
   538                Some (ThyInfo {path, children, thy_time, ml_time, thms,
   521                               thy_simps, ml_simps, ...}) =>
   539                               thy_ss, simpset, ...}) =>
   522                  ThyInfo {path = path, children = children,
   540                  ThyInfo {path = path, children = children,
   523                           thy_time = thy_time, ml_time = ml_time,
   541                           thy_time = thy_time, ml_time = ml_time,
   524                           theory = Some thy, thms = thms,
   542                           theory = Some thy, thms = thms,
   525                           thy_simps = thy_simps, ml_simps = ml_simps}
   543                           thy_ss = thy_ss, simpset = simpset}
   526              | None => ThyInfo {path = "", children = [],
   544              | None => ThyInfo {path = "", children = [],
   527                                 thy_time = None, ml_time = None,
   545                                 thy_time = None, ml_time = None,
   528                                 theory = Some thy, thms = Symtab.null,
   546                                 theory = Some thy, thms = Symtab.null,
   529                                 thy_simps = [], ml_simps = []};
   547                                 thy_ss = None, simpset = None};
   530   in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys)
   548   in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys)
   531   end;
   549   end;
   532 
   550 
   533 
   551 
   534 (** store and retrieve theorems **)
   552 (** store and retrieve theorems **)
   567 
   585 
   568 (*Store a theorem in the thy_info of its theory*)
   586 (*Store a theorem in the thy_info of its theory*)
   569 fun store_thm (name, thm) =
   587 fun store_thm (name, thm) =
   570   let
   588   let
   571     val (thy_name, ThyInfo {path, children, thy_time, ml_time, theory, thms,
   589     val (thy_name, ThyInfo {path, children, thy_time, ml_time, theory, thms,
   572                             thy_simps, ml_simps}) =
   590                             thy_ss, simpset}) =
   573       thyinfo_of_sign (#sign (rep_thm thm));
   591       thyinfo_of_sign (#sign (rep_thm thm));
   574 
   592 
   575     val thms' = Symtab.update_new ((name, thm), thms)
   593     val (thms', duplicate) = (Symtab.update_new ((name, thm), thms), false)
   576       handle Symtab.DUPLICATE s => 
   594       handle Symtab.DUPLICATE s => 
   577         (if same_thm (the (Symtab.lookup (thms, name)), thm) then 
   595         (if eq_thm (the (Symtab.lookup (thms, name)), thm) then 
   578            (writeln ("Warning: Theory database already contains copy of\
   596            (writeln ("Warning: Theory database already contains copy of\
   579                      \ theorem " ^ quote name);
   597                      \ theorem " ^ quote name);
   580             thms)
   598             (thms, true))
   581          else error ("Duplicate theorem name " ^ quote s
   599          else error ("Duplicate theorem name " ^ quote s
   582                      ^ " used in theory database"));
   600                      ^ " used in theory database"));
   583   in
   601   in
   584     loaded_thys := Symtab.update
   602     loaded_thys := Symtab.update
   585      ((thy_name, ThyInfo {path = path, children = children,
   603      ((thy_name, ThyInfo {path = path, children = children,
   586                           thy_time = thy_time, ml_time = ml_time,
   604                           thy_time = thy_time, ml_time = ml_time,
   587                           theory = theory, thms = thms',
   605                           theory = theory, thms = thms',
   588                           thy_simps = thy_simps, ml_simps = ml_simps}),
   606                           thy_ss = thy_ss, simpset = simpset}),
   589       !loaded_thys);
   607       !loaded_thys);
   590     store_thm_db (name, thm)
   608     if duplicate then thm else store_thm_db (name, thm)
   591   end;
   609   end;
   592 
   610 
   593 (*Store result of proof in loaded_thys and as ML value*)
   611 (*Store result of proof in loaded_thys and as ML value*)
   594 
   612 
   595 val qed_thm = ref flexpair_def(*dummy*);
   613 val qed_thm = ref flexpair_def(*dummy*);
   611 
   629 
   612 
   630 
   613 (* Retrieve theorems *)
   631 (* Retrieve theorems *)
   614 
   632 
   615 (*Get all theorems belonging to a given theory*)
   633 (*Get all theorems belonging to a given theory*)
   616 fun thmtab_ofthy thy =
   634 fun thmtab_of_thy thy =
   617   let val (_, ThyInfo {thms, ...}) = thyinfo_of_sign (sign_of thy);
   635   let val (_, ThyInfo {thms, ...}) = thyinfo_of_sign (sign_of thy);
   618   in thms end;
   636   in thms end;
   619 
   637 
   620 fun thmtab_ofname name =
   638 fun thmtab_of_name name =
   621   let val ThyInfo {thms, ...} = the (get_thyinfo name);
   639   let val ThyInfo {thms, ...} = the (get_thyinfo name);
   622   in thms end;
   640   in thms end;
   623 
   641 
   624 (*Get a stored theorem specified by theory and name*)
   642 (*Get a stored theorem specified by theory and name*)
   625 fun get_thm thy name =
   643 fun get_thm thy name =
   626   let fun get [] [] searched =
   644   let fun get [] [] searched =
   627            raise THEORY ("get_thm: no theorem " ^ quote name, [thy])
   645            raise THEORY ("get_thm: no theorem " ^ quote name, [thy])
   628         | get [] ng searched =
   646         | get [] ng searched =
   629             get (ng \\ searched) [] searched
   647             get (ng \\ searched) [] searched
   630         | get (t::ts) ng searched =
   648         | get (t::ts) ng searched =
   631             (case Symtab.lookup (thmtab_ofname t, name) of
   649             (case Symtab.lookup (thmtab_of_name t, name) of
   632                  Some thm => thm
   650                  Some thm => thm
   633                | None => get ts (ng union (get_parents t)) (t::searched));
   651                | None => get ts (ng union (get_parents t)) (t::searched));
   634 
   652 
   635       val (tname, _) = thyinfo_of_sign (sign_of thy);
   653       val (tname, _) = thyinfo_of_sign (sign_of thy);
   636   in get [tname] [] [] end;
   654   in get [tname] [] [] end;
   637 
   655 
   638 (*Get stored theorems of a theory*)
   656 (*Get stored theorems of a theory*)
   639 val thms_of = Symtab.dest o thmtab_ofthy;
   657 val thms_of = Symtab.dest o thmtab_of_thy;
   640 
   658 
       
   659 (*Get simpset of a theory*)
       
   660 fun simpset_of tname =
       
   661   case get_thyinfo tname of
       
   662       Some (ThyInfo {simpset, ...}) =>
       
   663         if is_some simpset then the simpset
       
   664         else error ("Simpset of theory " ^ tname ^ " has not been stored yet")
       
   665     | None => error ("Theory " ^ tname ^ " not stored by loader");
   641 
   666 
   642 (* print theory *)
   667 (* print theory *)
   643 
   668 
   644 fun print_thms thy =
   669 fun print_thms thy =
   645   let
   670   let