X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Fsoftware%2Fcomponents%2Fng_kernel%2FnCicLibrary.ml;h=6d1797677a6f23b8c587afe71709990f9e4189b1;hb=5d0d8107649b9264ebe7d8ff2c69bf777179b0d2;hp=1cb3a118b40c44eae03ac7bd6b445c6f9ea02162;hpb=8bc5bc0e8375a85736f6a5df317d129d5efa8de4;p=helm.git diff --git a/helm/software/components/ng_kernel/nCicLibrary.ml b/helm/software/components/ng_kernel/nCicLibrary.ml index 1cb3a118b..6d1797677 100644 --- a/helm/software/components/ng_kernel/nCicLibrary.ml +++ b/helm/software/components/ng_kernel/nCicLibrary.ml @@ -13,41 +13,49 @@ exception LibraryOutOfSync of string Lazy.t -type timestamp = - (NUri.uri * NCic.obj) list * - (NUri.uri * string * NReference.reference) list * - NCic.obj NUri.UriMap.t;; +let magic = 2;; -let time0 = [],[],NUri.UriMap.empty;; -let storage = ref [];; -let aliases = ref [];; -let cache = ref NUri.UriMap.empty;; +let refresh_uri uri = NUri.uri_of_string (NUri.string_of_uri uri);; -class status = - object - val timestamp = (time0 : timestamp) - method timestamp = timestamp - method set_timestamp v = {< timestamp = v >} - end +let refresh_uri_in_universe = + List.map (fun (x,u) -> x, refresh_uri u) +;; -let time_travel status = - let sto,ali,cac = status#timestamp in - storage := sto; aliases := ali; cache := cac +let rec refresh_uri_in_term = + function + | NCic.Const (NReference.Ref (u,spec)) -> + NCic.Const (NReference.reference_of_spec (refresh_uri u) spec) + | 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 + NCic.Match (r,outtype,term,pl) + | t -> NCicUtils.map (fun _ _ -> ()) () (fun _ -> refresh_uri_in_term) t ;; -let path_of_baseuri baseuri = +let refresh_uri_in_obj (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 +;; + +let 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 let dirname = Filename.dirname path in HExtlib.mkdir dirname; - path ^ ".ng" + if no_suffix then + path + else + path ^ ".ng" ;; -let magic = 0;; - -let require0 ~baseuri = - let ch = open_in (path_of_baseuri baseuri) in +let require_path path = + let ch = open_in path in let mmagic,dump = Marshal.from_channel ch in close_in ch; if mmagic <> magic then @@ -56,42 +64,126 @@ let require0 ~baseuri = dump ;; +let require0 ~baseuri = require_path (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 bool * NCic.universe * NCic.universe] list * + (NUri.uri * string * NReference.reference) list * + NCic.obj NUri.UriMap.t * + NUri.uri list +;; + +let time0 = [],[],NUri.UriMap.empty,[];; +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 + let rev_includes_map = ref NUri.UriMap.empty in + let store_db () = + let ch = open_out (db_path ()) in + Marshal.to_channel ch (magic,(!global_aliases,!rev_includes_map)) []; + close_out ch in + let load_db () = + HExtlib.mkdir (Helm_registry.get "matita.basedir"); + try + let ga,im = require_path (db_path ()) in + let ga = + List.map + (fun (uri,name,NReference.Ref (uri2,spec)) -> + refresh_uri uri,name,NReference.reference_of_spec (refresh_uri uri2) spec + ) ga in + let im = + NUri.UriMap.fold + (fun u l im -> NUri.UriMap.add (refresh_uri u) (List.map refresh_uri l) im + ) im NUri.UriMap.empty + in + global_aliases := ga; + rev_includes_map := im + with + Sys_error _ -> () in + let get_deps u = + let get_deps_one_step u = + try NUri.UriMap.find u !rev_includes_map with Not_found -> [] in + let rec aux res = + function + [] -> res + | he::tl -> + if List.mem he res then + aux res tl + else + aux (he::res) (get_deps_one_step he @ tl) + in + aux [] [u] in + let remove_deps u = + rev_includes_map := NUri.UriMap.remove u !rev_includes_map; + rev_includes_map := + NUri.UriMap.map + (fun l -> List.filter (fun uri -> not (NUri.eq u uri)) l) !rev_includes_map; + store_db () + in + load_db, + (fun ga -> global_aliases := ga; store_db ()), + (fun () -> !global_aliases), + (fun u l -> + rev_includes_map := NUri.UriMap.add u (l @ get_deps u) !rev_includes_map; + store_db ()), + get_deps, + remove_deps +;; + +let init = load_db;; + + +class status = + object + val timestamp = (time0 : timestamp) + method timestamp = timestamp + method set_timestamp v = {< timestamp = v >} + method set_library_status + : 'status. < timestamp : timestamp; .. > as 'status -> 'self + = fun o -> {< timestamp = o#timestamp >} + 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 serialize ~baseuri dump = let ch = open_out (path_of_baseuri baseuri) in - Marshal.to_channel ch (magic,dump) [Marshal.Closures]; + Marshal.to_channel ch (magic,dump) []; close_out ch; List.iter - (fun (uri,obj) -> - let ch = open_out (path_of_baseuri uri) in - Marshal.to_channel ch (magic,obj) []; - close_out ch + (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 refresh_uri uri = NUri.uri_of_string (NUri.string_of_uri uri);; - -let rec refresh_uri_in_term = - function - NCic.Const (NReference.Ref (u,spec)) -> - NCic.Const (NReference.reference_of_spec (refresh_uri u) spec) - | t -> NCicUtils.map (fun _ _ -> ()) () (fun _ -> refresh_uri_in_term) t -;; - -let refresh_uri_in_obj (uri,height,metasenv,subst,obj_kind) = - assert (metasenv = []); - assert (subst = []); - uri,height,metasenv,subst, - NCicUntrusted.map_obj_kind refresh_uri_in_term obj_kind -;; - module type Serializer = sig type status type obj val register: string -> - ('a -> refresh_uri_in_term:(NCic.term -> NCic.term) -> status -> status) -> + ('a -> refresh_uri_in_universe:(NCic.universe -> NCic.universe) -> refresh_uri_in_term:(NCic.term -> NCic.term) -> status -> status) -> ('a -> obj) val serialize: baseuri:NUri.uri -> obj list -> unit val require: baseuri:NUri.uri -> status -> status @@ -111,7 +203,7 @@ module Serializer(S: sig type status end) = require1 := (fun (tag',data) as x -> if tag=tag' then - require (Obj.magic data) ~refresh_uri_in_term + require (Obj.magic data) ~refresh_uri_in_universe ~refresh_uri_in_term else !require1 x); (fun x -> tag,Obj.repr x) @@ -119,15 +211,42 @@ module Serializer(S: sig type status end) = let serialize = serialize let require ~baseuri status = + includes := baseuri::!includes; let dump = require0 ~baseuri in List.fold_right !require1 dump status end let decompile ~baseuri = - Unix.unlink (path_of_baseuri baseuri) - (* WE ARE NOT REMOVING ALL THE OBJECTS YET! *) + 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 obj = require0 ~baseuri:uri in refresh_uri_in_obj obj @@ -136,7 +255,8 @@ let fetch_obj uri = let resolve name = try HExtlib.filter_map - (fun (_,name',nref) -> if name'=name then Some nref else None) !aliases + (fun (_,name',nref) -> if name'=name then Some nref else None) + (!local_aliases @ get_global_aliases ()) with Not_found -> raise (NCicEnvironment.ObjectNotFound (lazy name)) ;; @@ -144,13 +264,15 @@ let resolve name = let aliases_of uri = try HExtlib.filter_map - (fun (uri',_,nref) -> if NUri.eq uri' uri then Some nref else None) !aliases + (fun (uri',_,nref) -> + if NUri.eq uri' uri then Some nref else None) !local_aliases with Not_found -> raise (NCicEnvironment.ObjectNotFound (lazy (NUri.string_of_uri uri))) ;; -let add_obj status u obj = - storage := (u,obj)::!storage; +let add_obj status ((u,_,_,_,_) as obj) = + NCicEnvironment.check_and_add_obj obj; + storage := (`Obj (u,obj))::!storage; let _,height,_,_,obj = obj in let references = match obj with @@ -179,12 +301,22 @@ let add_obj status u obj = (NReference.Ind (inductive,i,leftno))] ) il) in - aliases := references @ !aliases; - status#set_timestamp (!storage,!aliases,!cache) + local_aliases := references @ !local_aliases; + status#set_timestamp (!storage,!local_aliases,!cache,!includes) +;; + +let add_constraint status strict u1 u2 = + NCicEnvironment.add_constraint strict u1 u2; + storage := (`Constr (strict,u1,u2)) :: !storage; + status#set_timestamp (!storage,!local_aliases,!cache,!includes) ;; let get_obj u = - try List.assq u !storage + try + List.assq u + (HExtlib.filter_map + (function `Obj (u,o) -> Some (u,o) | _ -> None ) + !storage) with Not_found -> try fetch_obj u with Sys_error _ ->