X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Fsoftware%2Fcomponents%2Fng_kernel%2FnCicLibrary.ml;h=6d1797677a6f23b8c587afe71709990f9e4189b1;hb=db7f6d6b32515c091e0f338dd4903624f35f27ac;hp=984b7ef6840a68552e952c58b882d10addbb2bb7;hpb=ea3883261d74eda2451ab90efc354a9c03b48707;p=helm.git diff --git a/helm/software/components/ng_kernel/nCicLibrary.ml b/helm/software/components/ng_kernel/nCicLibrary.ml index 984b7ef68..6d1797677 100644 --- a/helm/software/components/ng_kernel/nCicLibrary.ml +++ b/helm/software/components/ng_kernel/nCicLibrary.ml @@ -13,30 +13,33 @@ 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 local_aliases = ref [];; -let global_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 >} - method set_library_status - : 'status. < timestamp : timestamp; .. > as 'status -> 'self - = fun o -> {< timestamp = o#timestamp >} - 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; local_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 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 = @@ -51,8 +54,6 @@ let path_of_baseuri ?(no_suffix=false) baseuri = path ^ ".ng" ;; -let magic = 0;; - let require_path path = let ch = open_in path in let mmagic,dump = Marshal.from_channel ch in @@ -67,11 +68,96 @@ let require0 ~baseuri = require_path (path_of_baseuri baseuri);; let db_path () = Helm_registry.get "matita.basedir" ^ "/ng_db.ng";; -let init () = - try - global_aliases := require_path (db_path ()) - with - Sys_error _ -> () + +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 = @@ -79,41 +165,25 @@ let serialize ~baseuri dump = 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; - global_aliases := !local_aliases @ !global_aliases; - let ch = open_out (db_path ()) in - Marshal.to_channel ch (magic,!global_aliases) []; - close_out ch; + 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 @@ -133,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) @@ -141,27 +211,37 @@ 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 = - 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 - with - Unix.Unix_error _ -> () (* raised by Unix.opendir, we hope :-) *) + 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 @@ -176,7 +256,7 @@ let resolve name = try HExtlib.filter_map (fun (_,name',nref) -> if name'=name then Some nref else None) - (!local_aliases @ !global_aliases) + (!local_aliases @ get_global_aliases ()) with Not_found -> raise (NCicEnvironment.ObjectNotFound (lazy name)) ;; @@ -190,8 +270,9 @@ let aliases_of uri = 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 @@ -221,11 +302,21 @@ let add_obj status u obj = ) il) in local_aliases := references @ !local_aliases; - status#set_timestamp (!storage,!local_aliases,!cache) + 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 _ ->