fun update_timings props =
(case Markup.parse_command_timing_properties props of
SOME ({file, offset, name}, time) =>
Symtab.map_default (file, Inttab.empty)
(Inttab.map_default (offset, (name, time)) (fn (_, t) => (name, t + time)))
| NONE => I);
fun make_timings command_timings =
fold update_timings command_timings empty_timings;
fun approximative_id name pos =
(case (Position.file_of pos, Position.offset_of pos) of
(SOME file, SOME offset) => if name = ""then NONE else SOME {file = file, offset = offset, name = name}
| _ => NONE);
fun get_timings timings tr =
(case approximative_id (Toplevel.name_of tr) (Toplevel.pos_of tr) of
SOME {file, offset, name} =>
(case Symtab.lookup timings file of
SOME offsets =>
(case Inttab.lookup offsets offset of
SOME (name', time) => if name = name'then SOME time else NONE
| NONE => NONE)
| NONE => NONE)
| NONE => NONE)
|> the_default Time.zeroTime;
(* session base *)
val default_qualifier = "Draft";
type entry = {pos: Position.T, serial: serial};
fun make_entry props : entry =
{pos = Position.of_properties props, serial = serial ()};
fun init_session_env () =
(case getenv "ISABELLE_INIT_SESSION"of "" => ()
| name => try Bytes.read (Path.explode name)
|> Option.app init_session_yxml);
val _ = init_session_env ();
fun finish_session_base () =
Synchronized.change global_session_base
(apfst (K (#1 empty_session_base)));
fun get_session_base f = f (Synchronized.value global_session_base); fun get_session_base1 f = get_session_base (f o #1); fun get_session_base2 f = get_session_base (f o #2);
fun global_theory a = Symtab.lookup (get_session_base2 #global_theories) a; fun loaded_theory a = Symset.member (get_session_base2 #loaded_theories) a;
type data =
{master_dir: Path.T, (*master directory of theory source*)
imports: (string * Position.T) list, (*source specification of imports*)
provided: (Path.T * SHA1.digest) list}; (*source path, digest*)
fun make_data (master_dir, imports, provided): data =
{master_dir = master_dir, imports = imports, provided = provided};
structure Data = Theory_Data
( type T = data; val empty = make_data (Path.current, [], []); fun merge ({master_dir, imports, provided = provided1}, {provided = provided2, ...}) = letval provided' = Library.merge (op =) (provided1, provided2) in make_data (master_dir, imports, provided') end
);
fun map_data f =
Data.map (fn {master_dir, imports, provided} =>
make_data (f (master_dir, imports, provided)));
val master_directory = #master_dir o Data.get; val imports_of = #imports o Data.get;
fun begin_theory master_dir {name, imports, keywords} parents = let val thy =
Theory.begin_theory name parents
|> map_data (fn _ => (Path.explode (File.symbolic_path master_dir), imports, []))
|> Thy_Header.add_keywords keywords; val ctxt = Proof_Context.init_global thy; val _ = List.app (ignore o check_load_command ctxt o #load_command o #2) keywords; in thy end;
(* theory files *)
val thy_path = Path.ext "thy";
fun theory_qualifier theory =
(case global_theory theory of
SOME qualifier => qualifier
| NONE => Long_Name.qualifier theory);
fun literal_theory theory =
Long_Name.is_qualified theory orelse is_some (global_theory theory);
fun theory_name qualifier theory = if literal_theory theory then theory else Long_Name.qualify qualifier theory;
fun find_theory_file thy_name = let val thy_file = thy_path (Path.basic (Long_Name.base_name thy_name)); val session = theory_qualifier thy_name; val dirs = Symtab.lookup_list (get_session_base1 #session_directories) session; in
dirs |> get_first (fn dir => letval path = dir + thy_file inif File.is_file path then SOME path else NONE end) end;
fun make_theory_node node_name theory =
{node_name = node_name, master_dir = Path.dir node_name, theory_name = theory};
fun loaded_theory_node theory =
{node_name = Path.basic theory, master_dir = Path.current, theory_name = theory};
fun import_name qualifier dir s = let val theory = theory_name qualifier (Thy_Header.import_name s); fun theory_node path = make_theory_node path theory; val literal_import = literal_theory theory andalso qualifier <> theory_qualifier theory; val _ = if literal_import andalso not (Thy_Header.is_base_name s) then
error ("Bad import of theory from other session via file-path: " ^ quote s) else (); in if loaded_theory theory then loaded_theory_node theory else
(case find_theory_file theory of
SOME node_name => theory_node node_name
| NONE => if Thy_Header.is_base_name s andalso Long_Name.is_qualified s then loaded_theory_node theory else theory_node (File.full_path dir (thy_path (Path.expand (Path.explode s))))) end;
fun check_file dir file = File.check_file (File.full_path dir file);
fun check_thy dir thy_name = let val thy_base_name = Long_Name.base_name thy_name; val master_file =
(case find_theory_file thy_name of
SOME path => check_file Path.current path
| NONE => check_file dir (thy_path (Path.basic thy_base_name))); val text = File.read master_file;
val {name = (name, pos), imports, keywords} =
Thy_Header.read (Position.file (File.symbolic_path master_file)) text; val _ =
thy_base_name <> name andalso
error ("Bad theory name " ^ quote name ^ " for file " ^ Path.print (Path.base master_file) ^ Position.here pos); in
{master = (master_file, SHA1.digest text), text = text, theory_pos = pos,
imports = imports, keywords = keywords} end;
(* read_file *)
fun read_file_node file_node master_dir (src_path, pos) = let fun read_local () = let val path = File.check_file (File.full_path master_dir src_path); val text = File.read path; val file_pos = Position.file (File.symbolic_path path); in (text, file_pos) end;
fun read_remote () = let val text = Bytes.content (Isabelle_System.download file_node); val file_pos = Position.file file_node; in (text, file_pos) end;
val (text, file_pos) =
(casetry Url.explode file_node of
NONE => read_local ()
| SOME (Url.File _) => read_local ()
| _ => read_remote ());
val lines = split_lines text; val digest = SHA1.digest text; in {src_path = src_path, lines = lines, digest = digest, pos = Position.copy_id pos file_pos} end handle ERROR msg => error (msg ^ Position.here pos);
val read_file = read_file_node "";
(* load files *)
fun parsed_files make_paths (files, source) thy = if null files then let val master_dir = master_directory thy; val name = Input.string_of source; val pos = Input.pos_of source; val delimited = Input.is_delimited source; val src_paths = make_paths (Path.explode name); val reports =
src_paths |> maps (fn src_path =>
[(pos, Markup.path (File.symbolic_path (master_dir + src_path))),
(pos, Markup.language_path delimited)]); val _ = Position.reports reports; inmap (read_file master_dir o rpair pos) src_paths end elsemap Exn.release files;
val provide_parse_file = provide_parse_files single >> (fn f => f #>> the_single);
fun load_file thy src_path = let val full_path = check_file (master_directory thy) src_path; val text = File.read full_path; val digest = SHA1.digest text; in ((full_path, digest), text) end;
fun loaded_files_current thy =
#provided (Data.get thy) |>
forall (fn (src_path, digest) =>
(casetry (load_file thy) src_path of
NONE => false
| SOME ((_, digest'), _) => digest = digest'));
(* formal check *)
fun formal_check (check: Path.T -> Path.T) ctxt opt_dir source = let val name = Input.string_of source; val pos = Input.pos_of source; val delimited = Input.is_delimited source;
val _ = Context_Position.report ctxt pos (Markup.language_path delimited);
fun err msg = error (msg ^ Position.here pos); val dir =
(case opt_dir of
SOME dir => dir
| NONE => master_directory (Proof_Context.theory_of ctxt)); val path = dir + Path.explode name handle ERROR msg => err msg; val _ = Path.expand path handle ERROR msg => err msg; val _ = Context_Position.report ctxt pos (Markup.path (File.symbolic_path path)); val _ = check path handle ERROR msg => err msg; in path end;
val check_path = formal_check I; val check_file = formal_check File.check_file; val check_dir = formal_check File.check_dir;
fun check_session_dir ctxt opt_dir s = let val dir = Path.expand (check_dir ctxt opt_dir s); val ok =
File.is_file (dir + Path.explode("ROOT")) orelse
File.is_file (dir + Path.explode("ROOTS")); in if ok then dir else
error ("Bad session root directory (missing ROOT or ROOTS): " ^
Path.print dir ^ Position.here (Input.pos_of s)) end;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.