-rw-r--r-- 27515 holtrace-20250617/holtrace.ml raw
Printf.printf("===== loading holtrace_save and holtrace_restore\n");; (* XXX: could automatically rename constants etc. to avoid collisions but this would be two-pass, so easier as a separate tool XXX: could inject new theorems into Toploop bindings XXX: could use de-duplication to save memory: rebuild types, rebuild terms, re-prove theorems XXX: for internal dedup_trace_type etc., really want mutual recursion with a function returning ID XXX: might encounter integer overflows on 32-bit machines *) (* ===== save *) module Holtrace_save: sig val REFL: term -> thm val TRANS: thm -> thm -> thm val MK_COMB: thm * thm -> thm val ABS: term -> thm -> thm val BETA: term -> thm val ASSUME: term -> thm val EQ_MP: thm -> thm -> thm val DEDUCT_ANTISYM_RULE: thm -> thm -> thm val INST_TYPE: (hol_type * hol_type) list -> thm -> thm val INST: (term * term) list -> thm -> thm val new_axiom: term -> thm val new_basic_definition: term -> thm val new_basic_type_definition: string -> string * string -> thm -> thm * thm val holtrace_nameonethm: string * thm -> unit val holtrace_namethm: (string * thm) list -> unit val holtrace_stop: unit -> unit val holtrace_typedef_thms: unit -> thm list end = struct let orig_REFL = REFL let orig_TRANS = TRANS let orig_MK_COMB = MK_COMB let orig_ABS = ABS let orig_BETA = BETA let orig_ASSUME = ASSUME let orig_EQ_MP = EQ_MP let orig_DEDUCT_ANTISYM_RULE = DEDUCT_ANTISYM_RULE let orig_INST_TYPE = INST_TYPE let orig_INST = INST let orig_new_axiom = new_axiom let orig_new_basic_definition = new_basic_definition let orig_new_basic_type_definition = new_basic_type_definition let envvar = Sys.getenv_opt("HOLTRACE_SAVE") let enabled = Option.is_some envvar let fd = if enabled then open_out_bin (Option.get envvar) else (* presumably there is an easier way to do this *) let fd = open_out_bin "/dev/null" in Out_channel.close fd; fd let tracing = ref enabled let trace_flush() = if !tracing then Out_channel.flush fd let trace_char c = if !tracing then output_char fd c let trace_string s = if !tracing then output_string fd s let trace_stop() = if !tracing then begin Out_channel.close fd; tracing := false end (* ===== holtrace encoding *) let rec base32 n = if n < 0 then "-" ^ (base32(-n)) else if n == 0 then "" else let d = n mod 32 in let c = Char.chr(d + (if d < 10 then 48 else 55)) in base32(n/32) ^ String.make 1 c let is_base32char c = (c >= '0' && c <= '9') || (c >= 'A' && c <= 'V') let simpleencode n = match n with | -1 -> "!" | -2 -> "@" | -3 -> "#" | -4 -> "$" | -5 -> "%" | -6 -> "^" | -7 -> "&" | -8 -> "*" | -9 -> "(" | -10 -> ")" | 0 -> "0" | _ -> base32 n let simpleencode_len n = String.length(simpleencode n) let is_printablenospaces s = String.for_all (fun c -> c > ' ' && c <= '~') s let need_version = ref true let trace tag idlist s = if not(is_printablenospaces s) then failwith "bad name" else if !need_version then begin trace_string "HOLTrace 1\n"; need_version := false end; trace_char tag; let idlist = map simpleencode idlist in let args = if String.length s = 0 then idlist else idlist@[s] in let lastbyte = ref ' ' in let doit = fun s -> ( (* s is nonempty now *) let firstbyte = s.[0] in if is_base32char !lastbyte && (is_base32char firstbyte || (firstbyte == ' ')) then trace_char ' '; trace_string s; lastbyte := s.[String.length s - 1] ) in List.iter doit args; trace_char '\n'; trace_flush() let compress reference id = if id < 0 then failwith "internal bug, negative integer" else let y = id-reference in if y >= 0 then id else if y >= -10 then y else if simpleencode_len y <= simpleencode_len id then y else id (* ===== types *) let some_type = bool_ty let id2type = Dynarray.make 0 some_type let type2id = Hashtbl.create 10000 let type2compress ty = compress (Dynarray.length id2type) (Hashtbl.find type2id ty) let rec dedup_trace_type ty = if Hashtbl.mem type2id ty then let id = Hashtbl.find type2id ty in Dynarray.get id2type id else begin if is_vartype ty then let name = dest_vartype ty in assert(String.length name > 0); trace 'a' [] name else begin let name,args = dest_type ty in let args = map dedup_trace_type args in assert(String.length name > 0); trace 'b' ((length args)::(map type2compress args)) name end; let id = Dynarray.length id2type in Dynarray.add_last id2type ty; Hashtbl.add type2id ty id; ty end (* ===== terms *) let some_constant = mk_const("=",[]) let id2term = Dynarray.make 0 some_constant let term2id = Hashtbl.create 10000 let term2compress x = compress (Dynarray.length id2term) (Hashtbl.find term2id x) let rec dedup_trace_term tm = if Hashtbl.mem term2id tm then let id = Hashtbl.find term2id tm in Dynarray.get id2term id else begin if is_const tm then let s,ty = dest_const tm in let ty = dedup_trace_type ty in assert(String.length s > 0); trace 'c' [type2compress ty] s else if is_var tm then let s,ty = dest_var tm in let ty = dedup_trace_type ty in assert(String.length s > 0); trace 'd' [type2compress ty] s else if is_comb tm then let f,x = dest_comb tm in let f = dedup_trace_term f in let x = dedup_trace_term x in let ty = dedup_trace_type(type_of tm) in trace 'e' [type2compress ty;term2compress f;term2compress x] "" else begin let v,b = dest_abs tm in let v = dedup_trace_term v in let b = dedup_trace_term b in let ty = dedup_trace_type(type_of tm) in trace 'f' [type2compress ty;term2compress v;term2compress b] "" end; let id = Dynarray.length id2term in Dynarray.add_last id2term tm; Hashtbl.add term2id tm id; tm end (* ===== theorems *) let some_thm = orig_REFL some_constant let id2thm = Dynarray.make 0 some_thm let thmhc2id = Hashtbl.create 10000 (* thmhc2id indexes by hypotheses,conclusion in case thm is augmented by, e.g., ProofTrace *) let knownthm th = Hashtbl.mem thmhc2id (dest_thm th) let thm2compress th = let h,c = dest_thm th in compress (Dynarray.length id2thm) (Hashtbl.find thmhc2id (h,c)) let rec dedup_trace_thm th = let h,c = dest_thm th in if Hashtbl.mem thmhc2id (h,c) then let id = Hashtbl.find thmhc2id (h,c) in Dynarray.get id2thm id else let hc = h@[c] in let hc = map dedup_trace_term hc in trace 't' (map term2compress hc) ""; let id = Dynarray.length id2thm in Dynarray.add_last id2thm th; Hashtbl.add thmhc2id (h,c) id; th (* ===== inferences *) let oneterm tag inf tm = if !tracing then let tm = dedup_trace_term tm in let result = inf tm in if knownthm result then result else begin trace tag [term2compress tm] ""; dedup_trace_thm result end else inf tm let trace_BETA = oneterm 'B' orig_BETA let trace_REFL = oneterm 'R' orig_REFL let trace_ASSUME = oneterm 'U' orig_ASSUME let trace_new_axiom = oneterm 'X' orig_new_axiom let twothms tag inf th TH = if !tracing then let th = dedup_trace_thm th in let TH = dedup_trace_thm TH in let result = inf th TH in if knownthm result then result else begin trace tag (map thm2compress [th;TH]) ""; dedup_trace_thm result end else inf th TH let trace_MK_COMB(th,TH) = twothms 'E' (fun th TH -> orig_MK_COMB(th,TH)) th TH let trace_EQ_MP = twothms 'P' orig_EQ_MP let trace_TRANS = twothms 'V' orig_TRANS let trace_DEDUCT_ANTISYM_RULE = twothms 'Z' orig_DEDUCT_ANTISYM_RULE let trace_ABS tm th = if !tracing then let tm = dedup_trace_term tm in let th = dedup_trace_thm th in let result = orig_ABS tm th in if knownthm result then result else begin trace 'F' [term2compress tm;thm2compress th] ""; dedup_trace_thm result end else orig_ABS tm th let trace_INST tmlist th = if !tracing then let th = dedup_trace_thm th in let dedup_trace_termpair(w,v) = dedup_trace_term w,dedup_trace_term v in let tmlist = map dedup_trace_termpair tmlist in let result = orig_INST tmlist th in if knownthm result then result else begin let listlist = map (fun(w,v) -> [v;w]) tmlist in let flat = List.flatten listlist in trace 'S' ((thm2compress th)::(map term2compress flat)) ""; dedup_trace_thm result end else orig_INST tmlist th let trace_INST_TYPE tylist th = if !tracing then let th = dedup_trace_thm th in let dedup_trace_typepair(z,y) = dedup_trace_type z,dedup_trace_type y in let tylist = map dedup_trace_typepair tylist in let result = orig_INST_TYPE tylist th in if knownthm result then result else begin let listlist = map (fun(z,y) -> [y;z]) tylist in let flat = List.flatten listlist in trace 'T' ((thm2compress th)::(map type2compress flat)) ""; dedup_trace_thm result end else orig_INST_TYPE tylist th let trace_new_basic_definition tm = if !tracing then let tm = dedup_trace_term tm in let result = orig_new_basic_definition tm in if knownthm result then result else begin let c,cdef = dest_eq tm in let cname,_ = dest_var c in assert(String.length cname > 0); trace 'C' [term2compress tm] cname; dedup_trace_thm result end else orig_new_basic_definition tm let trace_new_basic_type_definition tyname (absname,repname) th = if !tracing then let th = dedup_trace_thm th in let ath,rth = orig_new_basic_type_definition tyname (absname,repname) th in if knownthm ath && knownthm rth then ath,rth else begin let repprop,witness = dest_comb(concl th) in let reptype = type_of witness in let reptype = dedup_trace_type reptype in let repprop = dedup_trace_term repprop in let tyvars = sort (<=) (type_vars_in_term repprop) in let tyvarnames = map dest_vartype tyvars in let words = tyname::absname::repname::tyvarnames in let text = "]" ^ (String.concat "]" words) ^ "]" in let compressed = [type2compress reptype;term2compress repprop;thm2compress th] in trace 'A' compressed text; let ath = dedup_trace_thm ath in trace 'D' [-1] ""; let rth = dedup_trace_thm rth in ath,rth end else orig_new_basic_type_definition tyname (absname,repname) th (* ===== theorem names *) let names_saved_already = Hashtbl.create 100 let trace_nameonethm(name,th) = if Hashtbl.mem names_saved_already name then () (* just ignore (whether old th or not) *) else if knownthm th then begin assert(String.length(name) > 0); trace '/' [thm2compress th] name; Hashtbl.add names_saved_already name true end else failwith "unknown theorem; was HOLTrace running?" let trace_namethm = List.iter trace_nameonethm (* ===== switch *) let REFL = if enabled then trace_REFL else orig_REFL let TRANS = if enabled then trace_TRANS else orig_TRANS let MK_COMB = if enabled then trace_MK_COMB else orig_MK_COMB let ABS = if enabled then trace_ABS else orig_ABS let BETA = if enabled then trace_BETA else orig_BETA let ASSUME = if enabled then trace_ASSUME else orig_ASSUME let EQ_MP = if enabled then trace_EQ_MP else orig_EQ_MP let DEDUCT_ANTISYM_RULE = if enabled then trace_DEDUCT_ANTISYM_RULE else orig_DEDUCT_ANTISYM_RULE let INST_TYPE = if enabled then trace_INST_TYPE else orig_INST_TYPE let INST = if enabled then trace_INST else orig_INST let new_axiom = if enabled then trace_new_axiom else orig_new_axiom let new_basic_definition = if enabled then trace_new_basic_definition else orig_new_basic_definition let almost_new_basic_type_definition = if enabled then trace_new_basic_type_definition else orig_new_basic_type_definition let holtrace_nameonethm = if enabled then trace_nameonethm else ignore let holtrace_namethm = if enabled then trace_namethm else ignore let holtrace_stop = if enabled then trace_stop else ignore (* ===== even if tracing is disabled, save typedef theorems *) let typedef_thms = ref ([]:thm list) let new_basic_type_definition tyname (absname,repname) th = let ath,rth = almost_new_basic_type_definition tyname (absname,repname) th in typedef_thms := rth::ath::!typedef_thms; ath,rth let holtrace_typedef_thms() = !typedef_thms end include Holtrace_save (* ===== restore *) module Holtrace_restore: sig val holtrace_restore: (string * thm) list -> string -> unit val holtrace_restore_time: (string * thm) list -> string -> unit val holtrace_restore_skipthmchecks: (string * thm) list -> string -> unit val holtrace_restore_worker: (unit -> float) -> bool -> (string * thm) list -> string -> unit val holtrace_restore_name2thm: string -> thm end = struct (* ===== parsing *) let parse_subid line pos id = let linelen = String.length line in let rec parse_nonneg pos result = assert(result < 288230376151711744); if pos >= linelen then pos,result else let c = line.[pos] in if c = ' ' then pos+1,result else if c >= '0' && c <= '9' then parse_nonneg (pos+1) (result*32+(Char.code c-48)) else if c >= 'A' && c <= 'V' then parse_nonneg (pos+1) (result*32+(Char.code c-55)) else pos,result in let parse_allowneg pos = if pos >= linelen then pos,0 else let c = line.[pos] in if c = '-' then let outpos,n = parse_nonneg (pos+1) 0 in outpos,id-n else let outpos,n = parse_nonneg pos 0 in assert(outpos > pos); outpos,n in let parse_core pos = if pos >= linelen then pos,0 else match line.[pos] with | '!' -> pos+1,id-1 | '@' -> pos+1,id-2 | '#' -> pos+1,id-3 | '$' -> pos+1,id-4 | '%' -> pos+1,id-5 | '^' -> pos+1,id-6 | '&' -> pos+1,id-7 | '*' -> pos+1,id-8 | '(' -> pos+1,id-9 | ')' -> pos+1,id-10 | _ -> parse_allowneg pos in let pos,n = parse_core pos in assert(n >= 0 && (n < id || id < 0)); pos,n let parse_name line pos = String.sub line pos (String.length line - pos) let parse_pairs line pos id xfrm = let rec work result pos = if pos = String.length(line) then result else let pos,idfrom = parse_subid line pos id in let pos,idto = parse_subid line pos id in work ((xfrm idto,xfrm idfrom)::result) pos in rev(work [] pos) let parse_many_subid_reverse many line pos id = let rec work result many pos = if many <= 0 then pos,result else let pos,n = parse_subid line pos id in work (n::result) (many-1) pos in work [] many pos (* ===== types *) let type_id = ref 0 let some_type = bool_ty let holtrace_types = Dynarray.make 0 some_type let holtrace_types_add x = assert(Dynarray.length holtrace_types = !type_id); Dynarray.add_last holtrace_types x; type_id := 1 + !type_id let holtrace_vartype line = holtrace_types_add (mk_vartype(parse_name line 1)) let holtrace_type line = let pos,n = parse_subid line 1 (-1) in let pos,revargs = parse_many_subid_reverse n line pos !type_id in let args = rev revargs in let prevtypes = map (Dynarray.get holtrace_types) args in let name = parse_name line pos in holtrace_types_add (mk_type(name,prevtypes)) (* ===== terms *) let term_id = ref 0 let some_term = mk_const("=",[]) let holtrace_terms = Dynarray.make 0 some_term let holtrace_terms_add x = assert(Dynarray.length holtrace_terms = !term_id); Dynarray.add_last holtrace_terms x; term_id := 1 + !term_id let holtrace_const line = let pos,tyid = parse_subid line 1 !type_id in let ty = Dynarray.get holtrace_types tyid in let name = parse_name line pos in holtrace_terms_add (mk_mconst(name,ty)) let holtrace_var line = let pos,tyid = parse_subid line 1 !type_id in let ty = Dynarray.get holtrace_types tyid in let name = parse_name line pos in holtrace_terms_add (mk_var(name,ty)) let holtrace_comb line = let pos,tyid = parse_subid line 1 !type_id in let pos,id0 = parse_subid line pos !term_id in let pos,id1 = parse_subid line pos !term_id in assert(pos = String.length line); let t0 = Dynarray.get holtrace_terms id0 in let t1 = Dynarray.get holtrace_terms id1 in holtrace_terms_add (mk_comb(t0,t1)) let holtrace_abs line = let pos,tyid = parse_subid line 1 !type_id in let pos,id0 = parse_subid line pos !term_id in let pos,id1 = parse_subid line pos !term_id in assert(pos = String.length line); let t0 = Dynarray.get holtrace_terms id0 in let t1 = Dynarray.get holtrace_terms id1 in holtrace_terms_add (mk_abs(t0,t1)) (* ===== axioms *) let holtrace_axiom term = let target = [],term in let istarget = fun f -> dest_thm f = target in find istarget (axioms()) (* ===== theorems indexed by inf_id *) let thm_id = ref 0 let inf_id = ref 0 let typedef_id = ref 0 let some_thm = REFL some_term let holtrace_thms = Dynarray.make 0 some_thm let infs = Dynarray.make 0 some_thm let typedefs = Dynarray.make 0 some_thm let name2thm = Hashtbl.create 100 let infs_add x = assert(Dynarray.length infs = !inf_id); Dynarray.add_last infs x; inf_id := 1 + !inf_id let typedefs_add x = assert(Dynarray.length typedefs = !typedef_id); Dynarray.add_last typedefs x; typedef_id := 1 + !typedef_id let inf_term line inf = let pos,id0 = parse_subid line 1 !term_id in assert(pos = String.length line); let t0 = Dynarray.get holtrace_terms id0 in infs_add (inf t0) let inf_thTH line inf = let pos,id0 = parse_subid line 1 !thm_id in let pos,id1 = parse_subid line pos !thm_id in assert(pos = String.length line); let t0 = Dynarray.get holtrace_thms id0 in let t1 = Dynarray.get holtrace_thms id1 in infs_add (inf t0 t1) let inf_termth line inf = let pos,id0 = parse_subid line 1 !term_id in let pos,id1 = parse_subid line pos !thm_id in assert(pos = String.length line); let t0 = Dynarray.get holtrace_terms id0 in let t1 = Dynarray.get holtrace_thms id1 in infs_add (inf t0 t1) let inf_def line = let defC term name = let v,t = dest_eq term in let vname,vtype = dest_var(v) in if vname <> name then failwith "name mismatch" else if can get_const_type vname then let c = mk_mconst(vname,vtype) in let target = [],mk_eq(c,t) in let istarget = fun f -> dest_thm f = target in Printf.printf "matching constant %s\n%!" vname; find istarget (definitions()); else begin Printf.printf "creating constant %s\n%!" vname; new_basic_definition term end in let pos,id0 = parse_subid line 1 !term_id in let name = parse_name line pos in let t0 = Dynarray.get holtrace_terms id0 in infs_add (defC t0 name) let is_known_type_theorem concl = let ok = fun f -> dest_thm f = ([],concl) in exists ok (holtrace_typedef_thms()) let find_type_theorem concl = let ok = fun f -> dest_thm f = ([],concl) in find ok (holtrace_typedef_thms()) let inf_def_type line = let pos,reptype = parse_subid line 1 !type_id in let pos,repprop = parse_subid line pos !term_id in let pos,repth = parse_subid line pos !thm_id in let word = parse_name line pos in let reptype = Dynarray.get holtrace_types reptype in let repprop = Dynarray.get holtrace_terms repprop in let repth = Dynarray.get holtrace_thms repth in let thconcl = match dest_thm repth with | [],concl -> concl | _ -> failwith line in let thprop,_ = try dest_comb thconcl with Failure _ -> failwith line in assert(repprop = thprop); assert(word.[0] = ']'); let args = String.split_on_char ']' word in assert(hd(rev args) = ""); let args = rev(tl(rev args)) in match args with | ""::abstypename::absname::repname::tyvarnames -> let tyvars = map mk_vartype tyvarnames in let abstype = mk_type(abstypename,tyvars) in let abs = mk_mconst(absname,mk_fun_ty reptype abstype) in let rep = mk_mconst(repname,mk_fun_ty abstype reptype) in let absvar = mk_var("a",abstype) in let repvar = mk_var("r",reptype) in let atarget = mk_eq(mk_comb(abs,mk_comb(rep,absvar)),absvar) in let rtarget = mk_eq(mk_comb(repprop,repvar),mk_eq(mk_comb(rep,mk_comb(abs,repvar)),repvar)) in if is_known_type_theorem atarget && is_known_type_theorem rtarget then let athm = find_type_theorem atarget in let rthm = find_type_theorem rtarget in Printf.printf "matching typedef %s\n%!" abstypename; typedefs_add rthm; infs_add athm else begin Printf.printf "creating typedef %s\n%!" abstypename; let athm,rthm = new_basic_type_definition abstypename (absname,repname) repth in typedefs_add rthm; infs_add athm end | _ -> failwith line let inf_def_type_followup line = let pos,typedef = parse_subid line 1 !typedef_id in let rthm = Dynarray.get typedefs typedef in infs_add rthm let inf_inst line = let pos,id0 = parse_subid line 1 !thm_id in let xfrm = Dynarray.get holtrace_terms in let arg = parse_pairs line pos !term_id xfrm in let t0 = Dynarray.get holtrace_thms id0 in let thm = INST arg t0 in infs_add thm let inf_inst_type line = let pos,id0 = parse_subid line 1 !thm_id in let argmap = Dynarray.get holtrace_types in let arg = parse_pairs line pos !type_id argmap in let t0 = Dynarray.get holtrace_thms id0 in let thm = INST_TYPE arg t0 in infs_add thm let holtrace_thms_add x = while Dynarray.length holtrace_thms < !thm_id do Dynarray.add_last holtrace_thms some_thm done; assert(Dynarray.length holtrace_thms = !thm_id); Dynarray.add_last holtrace_thms x; thm_id := 1 + !thm_id let holtrace_thm checkthmstatements line = let linelen = String.length(line) in let rec all_subid result pos = if pos >= linelen then result else let pos,n = parse_subid line pos !term_id in all_subid (n::result) pos in let chhhid = all_subid [] 1 in let chhh = map (Dynarray.get holtrace_terms) chhhid in let c = hd chhh in let hhh = rev(tl chhh) in let thm = Dynarray.get infs (!inf_id-1) in if checkthmstatements then assert((hhh,c) = dest_thm(thm)); holtrace_thms_add thm let thmname_acceptable_firstchar c = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c == '_') let thmname_acceptable_char c = thmname_acceptable_firstchar c || (c == '\'') || (c == '.') let thmname_acceptable s = String.length s > 0 && thmname_acceptable_firstchar s.[0] && String.for_all thmname_acceptable_char s let holtrace_thmname previousthms line = let pos,id0 = parse_subid line 1 !thm_id in let name = parse_name line pos in if not(thmname_acceptable name) then failwith ("refusing unusual characters in theorem name "^name) else if Hashtbl.mem name2thm name then failwith "theorem name already used" else begin let th = Dynarray.get holtrace_thms id0 in Hashtbl.add name2thm name th; if exists (fun (n,t) -> n = name) previousthms then begin Printf.printf "matching thm %s\n%!" name; let known = assoc name previousthms in assert(dest_thm known = dest_thm th) end else Printf.printf "creating thm %s\n%!" name end (* ===== main *) let holtrace_restore_worker bench checkthmstatements previousthms fn = let total_time = ref 0.0 in total_time := !total_time -. bench(); type_id := 0; term_id := 0; thm_id := 0; inf_id := 0; typedef_id := 0; Dynarray.clear holtrace_types; Dynarray.clear holtrace_terms; Dynarray.clear holtrace_thms; Dynarray.clear infs; Dynarray.clear typedefs; Hashtbl.clear name2thm; let tag_occurrences = Array.make 256 0 in let tag_time = Array.make 256 0.0 in let linecount = ref 0 in let fd = open_in_bin fn in try while true do (* XXX: should reject partial final line *) let line = input_line fd in linecount := !linecount + 1; if !linecount = 1 then assert(line = "HOLTrace 1") else let tag = line.[0] in let tagcode = Char.code(tag) in tag_occurrences.(tagcode) <- tag_occurrences.(tagcode) + 1; tag_time.(tagcode) <- tag_time.(tagcode) -. bench(); ( match tag with | 'a' -> holtrace_vartype line | 'b' -> holtrace_type line | 'c' -> holtrace_const line | 'd' -> holtrace_var line | 'e' -> holtrace_comb line | 'f' -> holtrace_abs line | 't' -> holtrace_thm checkthmstatements line | '/' -> holtrace_thmname previousthms line | 'X' -> inf_term line holtrace_axiom | 'B' -> inf_term line BETA | 'R' -> inf_term line REFL | 'U' -> inf_term line ASSUME | 'F' -> inf_termth line ABS | 'P' -> inf_thTH line EQ_MP | 'V' -> inf_thTH line TRANS | 'Z' -> inf_thTH line DEDUCT_ANTISYM_RULE | 'E' -> inf_thTH line (fun t0 t1 -> MK_COMB(t0,t1)) | 'S' -> inf_inst line | 'T' -> inf_inst_type line | 'C' -> inf_def line | 'A' -> inf_def_type line | 'D' -> inf_def_type_followup line | ';' -> () | ',' -> () | _ -> failwith line ); tag_time.(tagcode) <- tag_time.(tagcode) +. bench(); done with End_of_file -> close_in fd; assert(!linecount >= 1); total_time := !total_time +. bench(); Printf.printf "type IDs: %d\n" !type_id; Printf.printf "term IDs: %d\n" !term_id; Printf.printf "theorem IDs: %d\n" !thm_id; Printf.printf "inference IDs: %d\n" !inf_id; Printf.printf "typedef IDs: %d\n" !typedef_id; for c = 33 to 126 do if tag_occurrences.(c) > 0 then Printf.printf "tag %c %12f seconds %12d occurrences\n" (Char.chr(c)) tag_time.(c) tag_occurrences.(c) done; Printf.printf "total %12f seconds\n%!" !total_time let holtrace_restore_skipthmchecks = holtrace_restore_worker (fun x -> 0.0) false let holtrace_restore_time = holtrace_restore_worker Sys.time true let holtrace_restore = holtrace_restore_worker (fun x -> 0.0) true let holtrace_restore_name2thm = Hashtbl.find name2thm end include Holtrace_restore Printf.printf("===== finished loading holtrace_save and holtrace_restore\n");;