X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=matita%2Fcomponents%2Fng_library%2FnCicLibrary.ml;h=87f0cb31b122f8e9f487a4187a947d143559f327;hb=894d518aa760c9f816ddb0dc2b3fa88e1fe20a94;hp=ad8084692fd11f3951546183b36d65083da22b7b;hpb=d4f2d4c1a4784f84aa27e1bb96b8b377a6553c65;p=helm.git diff --git a/matita/components/ng_library/nCicLibrary.ml b/matita/components/ng_library/nCicLibrary.ml index ad8084692..87f0cb31b 100644 --- a/matita/components/ng_library/nCicLibrary.ml +++ b/matita/components/ng_library/nCicLibrary.ml @@ -25,30 +25,33 @@ let refresh_uri_in_universe = let refresh_uri_in_reference (NReference.Ref (uri,spec)) = NReference.reference_of_spec (refresh_uri uri) spec -let rec refresh_uri_in_term = - function +let refresh_uri_in_term status = + let rec aux = + function | NCic.Meta (i,(n,NCic.Ctx l)) -> - NCic.Meta (i,(n,NCic.Ctx (List.map refresh_uri_in_term l))) + NCic.Meta (i,(n,NCic.Ctx (List.map aux l))) | NCic.Meta _ as t -> t | NCic.Const ref -> NCic.Const (refresh_uri_in_reference ref) | NCic.Sort (NCic.Type l) -> NCic.Sort (NCic.Type (refresh_uri_in_universe l)) | NCic.Match (NReference.Ref (uri,spec),outtype,term,pl) -> let r = NReference.reference_of_spec (refresh_uri uri) spec in - let outtype = refresh_uri_in_term outtype in - let term = refresh_uri_in_term term in - let pl = List.map refresh_uri_in_term pl in + let outtype = aux outtype in + let term = aux term in + let pl = List.map aux pl in NCic.Match (r,outtype,term,pl) - | t -> NCicUtils.map (fun _ _ -> ()) () (fun _ -> refresh_uri_in_term) t + | t -> NCicUtils.map status (fun _ _ -> ()) () (fun _ -> aux) t +in + aux ;; -let refresh_uri_in_obj (uri,height,metasenv,subst,obj_kind) = +let refresh_uri_in_obj status (uri,height,metasenv,subst,obj_kind) = assert (metasenv = []); assert (subst = []); refresh_uri uri,height,metasenv,subst, - NCicUntrusted.map_obj_kind refresh_uri_in_term obj_kind + NCicUntrusted.map_obj_kind (refresh_uri_in_term status) obj_kind ;; -let path_of_baseuri ?(no_suffix=false) baseuri = +let ng_path_of_baseuri ?(no_suffix=false) baseuri = let uri = NUri.string_of_uri baseuri in let path = String.sub uri 4 (String.length uri - 4) in let path = Helm_registry.get "matita.basedir" ^ path in @@ -70,26 +73,19 @@ let require_path path = dump ;; -let require0 ~baseuri = - require_path (path_of_baseuri baseuri) -;; +let require0 ~baseuri = require_path (ng_path_of_baseuri baseuri) let db_path () = Helm_registry.get "matita.basedir" ^ "/ng_db.ng";; - type timestamp = [ `Obj of NUri.uri * NCic.obj | `Constr of NCic.universe * NCic.universe] list * - (NUri.uri * string * NReference.reference) list * - NCic.obj NUri.UriMap.t * - NUri.uri list + (NUri.uri * string * NReference.reference) list ;; -let time0 = [],[],NUri.UriMap.empty,[];; +let time0 = [],[];; let storage = ref [];; let local_aliases = ref [];; -let cache = ref NUri.UriMap.empty;; -let includes = ref [];; let load_db,set_global_aliases,get_global_aliases,add_deps,get_deps,remove_deps= let global_aliases = ref [] in @@ -148,48 +144,52 @@ let load_db,set_global_aliases,get_global_aliases,add_deps,get_deps,remove_deps= let init = load_db;; -class status = - object(self) +class virtual status = + object + inherit NCic.status val timestamp = (time0 : timestamp) method timestamp = timestamp method set_timestamp v = {< timestamp = v >} end -let time_travel status = - let sto,ali,cac,inc = status#timestamp in - let diff_len = List.length !storage - List.length sto in - let to_be_deleted,_ = HExtlib.split_nth diff_len !storage in - if List.length to_be_deleted > 0 then - NCicEnvironment.invalidate_item (HExtlib.list_last to_be_deleted); - storage := sto; local_aliases := ali; cache := cac; includes := inc +let time_travel0 (sto,ali) = + let diff_len = List.length !storage - List.length sto in + let to_be_deleted,_ = HExtlib.split_nth diff_len !storage in + if List.length to_be_deleted > 0 then + List.iter NCicEnvironment.invalidate_item to_be_deleted; + storage := sto; local_aliases := ali ;; -let serialize ~baseuri dump = - let ch = open_out (path_of_baseuri baseuri) in - Marshal.to_channel ch (magic,dump) []; - close_out ch; - List.iter - (function - | `Obj (uri,obj) -> - let ch = open_out (path_of_baseuri uri) in - Marshal.to_channel ch (magic,obj) []; - close_out ch - | `Constr _ -> () - ) !storage; - set_global_aliases (!local_aliases @ get_global_aliases ()); - List.iter (fun u -> add_deps u [baseuri]) !includes; - time_travel (new status) -;; - +let time_travel status = time_travel0 status#timestamp;; + type obj = string * Obj.t +(* includes are transitively closed; dependencies are only immediate *) +type dump = + { objs: obj list ; includes: NUri.uri list; dependencies: string list } + +class type g_dumpable_status = + object + method dump: dump + end class dumpable_status = - object(self) - val dump = ([] : obj list) - method dump = dump - method set_dump v = {< dump = v >} + object + val db = { objs = []; includes = []; dependencies = [] } + method dump = db + method set_dump v = {< db = v >} + method set_dumpable_status + : 'status. #g_dumpable_status as 'status -> 'self + = fun o -> {< db = o#dump >} end +let get_transitively_included status = + status#dump.includes +;; + +let dump_obj status obj = + status#set_dump {status#dump with objs = obj::status#dump.objs } +;; + module type SerializerType = sig type dumpable_status @@ -197,27 +197,31 @@ module type SerializerType = type 'a register_type = 'a -> refresh_uri_in_universe:(NCic.universe -> NCic.universe) -> - refresh_uri_in_term:(NCic.term -> NCic.term) -> + refresh_uri_in_term:(NCic.status -> NCic.term -> NCic.term) -> refresh_uri_in_reference:(NReference.reference -> NReference.reference) -> + alias_only:bool -> dumpable_status -> dumpable_status val register: < run: 'a. string -> 'a register_type -> ('a -> obj) > - val serialize: baseuri:NUri.uri -> obj list -> unit - (* the obj is the "include" command to be added to the dump list *) - val require: baseuri:NUri.uri -> dumpable_status -> dumpable_status * obj + val serialize: baseuri:NUri.uri -> dumpable_status -> unit + val require: + baseuri:NUri.uri -> fname:string -> alias_only:bool -> + dumpable_status -> dumpable_status + val dependencies_of: baseuri:NUri.uri -> string list end -module Serializer(D: sig type dumpable_status end) = +module Serializer(D: sig type dumpable_s val get: dumpable_s -> dumpable_status val set: dumpable_s -> dumpable_status -> dumpable_s end) = struct - type dumpable_status = D.dumpable_status + type dumpable_status = D.dumpable_s type 'a register_type = 'a -> refresh_uri_in_universe:(NCic.universe -> NCic.universe) -> - refresh_uri_in_term:(NCic.term -> NCic.term) -> + refresh_uri_in_term:(NCic.status -> NCic.term -> NCic.term) -> refresh_uri_in_reference:(NReference.reference -> NReference.reference) -> + alias_only:bool -> dumpable_status -> dumpable_status - let require1 = ref (fun _ -> assert false) (* unknown data*) + let require1 = ref (fun ~alias_only:_ _ -> assert false) (* unknown data*) let already_registered = ref [] let register = @@ -228,74 +232,85 @@ module Serializer(D: sig type dumpable_status end) = already_registered := tag :: !already_registered; let old_require1 = !require1 in require1 := - (fun ((tag',data) as x) -> + (fun ~alias_only ((tag',data) as x) -> if tag=tag' then require (Obj.magic data) ~refresh_uri_in_universe ~refresh_uri_in_term - ~refresh_uri_in_reference + ~refresh_uri_in_reference ~alias_only else - old_require1 x); + old_require1 ~alias_only x); (fun x -> tag,Obj.repr x) end - let serialize = serialize - - let require2 ~baseuri status = + let serialize ~baseuri status = + let status = D.get status in + let ch = open_out (ng_path_of_baseuri baseuri) in + Marshal.to_channel ch (magic,(status#dump.dependencies,status#dump.objs)) []; + close_out ch; + List.iter + (function + | `Obj (uri,obj) -> + let ch = open_out (ng_path_of_baseuri uri) in + Marshal.to_channel ch (magic,obj) []; + close_out ch + | `Constr _ -> () + ) !storage; + set_global_aliases (!local_aliases @ get_global_aliases ()); + List.iter (fun u -> add_deps u [baseuri]) status#dump.includes; + time_travel0 time0 + + let require2 ~baseuri ~alias_only status = try - includes := baseuri::!includes; - let dump = require0 ~baseuri in - List.fold_right !require1 dump status + let s = D.get status in + let status = + D.set status + (s#set_dump + {s#dump with + includes = baseuri::List.filter ((<>) baseuri) s#dump.includes}) in + let _dependencies,dump = require0 ~baseuri in + List.fold_right (!require1 ~alias_only) dump status with Sys_error _ -> - raise (IncludedFileNotCompiled(path_of_baseuri baseuri,NUri.string_of_uri baseuri)) + raise (IncludedFileNotCompiled(ng_path_of_baseuri baseuri,NUri.string_of_uri baseuri)) + + let dependencies_of ~baseuri = fst (require0 ~baseuri) let record_include = - let aux baseuri ~refresh_uri_in_universe ~refresh_uri_in_term - ~refresh_uri_in_reference = - (* memorizzo baseuri in una tabella; *) - require2 ~baseuri + let aux (baseuri,fname) ~refresh_uri_in_universe:_ ~refresh_uri_in_term:_ + ~refresh_uri_in_reference:_ ~alias_only status = + let alias_only = + alias_only || List.mem baseuri (get_transitively_included (D.get status)) + in + HLog.warn ("include " ^ (if alias_only then "alias " else "") ^ fname); + let status = require2 ~baseuri ~alias_only status in + HLog.warn ("done: include " ^ (if alias_only then "alias " else "") ^ fname); + status in register#run "include" aux - let require ~baseuri status = - let status = require2 ~baseuri status in - status,record_include baseuri + let require ~baseuri ~fname ~alias_only status = + let alias_only = + alias_only || List.mem baseuri (get_transitively_included (D.get status)) in + let status = + if not alias_only then + let s = D.get status in + D.set status + (s#set_dump + {s#dump with + includes = baseuri::s#dump.includes; + dependencies = fname::s#dump.dependencies}) + else + status in + let status = require2 ~baseuri ~alias_only status in + let s = D.get status in + D.set status + (s#set_dump + {s#dump with + objs = record_include (baseuri,fname)::s#dump.objs }) end - -let decompile ~baseuri = - let baseuris = get_deps baseuri in - List.iter (fun baseuri -> - remove_deps baseuri; - HExtlib.safe_remove (path_of_baseuri baseuri); - let basepath = path_of_baseuri ~no_suffix:true baseuri in - try - let od = Unix.opendir basepath in - let rec aux names = - try - let name = Unix.readdir od in - if name <> "." && name <> ".." then aux (name::names) else aux names - with - End_of_file -> names in - let names = List.map (fun name -> basepath ^ "/" ^ name) (aux []) in - Unix.closedir od; - List.iter Unix.unlink names; - HExtlib.rmdir_descend basepath; - set_global_aliases - (List.filter - (fun (_,_,NReference.Ref (nuri,_)) -> - Filename.dirname (NUri.string_of_uri nuri) <> NUri.string_of_uri baseuri - ) (get_global_aliases ())) - with - Unix.Unix_error _ -> () (* raised by Unix.opendir, we hope :-) *) - ) baseuris -;; - -LibraryClean.set_decompile_cb - (fun ~baseuri -> decompile ~baseuri:(NUri.uri_of_string baseuri));; - -let fetch_obj uri = +let fetch_obj status uri = let obj = require0 ~baseuri:uri in - refresh_uri_in_obj obj + refresh_uri_in_obj status obj ;; let resolve name = @@ -314,7 +329,7 @@ let aliases_of uri = ;; let add_obj status ((u,_,_,_,_) as obj) = - NCicEnvironment.check_and_add_obj obj; + NCicEnvironment.check_and_add_obj status obj; storage := (`Obj (u,obj))::!storage; let _,height,_,_,obj = obj in let references = @@ -345,31 +360,32 @@ let add_obj status ((u,_,_,_,_) as obj) = ) il) in local_aliases := references @ !local_aliases; - status#set_timestamp (!storage,!local_aliases,!cache,!includes) + status#set_timestamp (!storage,!local_aliases) ;; let add_constraint status u1 u2 = + if + List.exists + (function `Constr (u1',u2') when u1=u1' && u2=u2' -> true | _ -> false) + !storage + then + (*CSC: raise an exception here! *) + (prerr_endline "CANNOT ADD A CONSTRAINT TWICE"; assert false); NCicEnvironment.add_lt_constraint u1 u2; storage := (`Constr (u1,u2)) :: !storage; - status#set_timestamp (!storage,!local_aliases,!cache,!includes) + status#set_timestamp (!storage,!local_aliases) ;; -let get_obj u = +let get_obj status u = try List.assq u (HExtlib.filter_map (function `Obj (u,o) -> Some (u,o) | _ -> None ) !storage) with Not_found -> - try fetch_obj u + try fetch_obj status u with Sys_error _ -> - try NUri.UriMap.find u !cache - with Not_found -> - raise (NCicEnvironment.ObjectNotFound - (lazy (NUri.string_of_uri u))) + raise (NCicEnvironment.ObjectNotFound (lazy (NUri.string_of_uri u))) ;; -let clear_cache () = cache := NUri.UriMap.empty;; - NCicEnvironment.set_get_obj get_obj;; -NCicPp.set_get_obj get_obj;;