(* *)
(******************************************************************************)
-let raise e = print_endline "***" ; flush stdout ; print_endline (Printexc.to_string e) ; flush stdout ; raise e;;
-
-(*CSC: forse i due seguenti tipi sono da unificare? *)
-type cooked_obj =
- Cooked of Cic.obj
- | Frozen of Cic.obj
- | Unchecked of Cic.obj
type type_checked_obj =
CheckedObj of Cic.obj (* cooked obj *)
- | UncheckedObj of Cic.obj (* uncooked obj *)
+ | UncheckedObj of Cic.obj (* uncooked obj to proof-check *)
;;
exception NoFunctionProvided;;
cook_obj := foo
;;
+exception AlreadyCooked of string;;
exception CircularDependency of string;;
+exception CouldNotFreeze of string;;
exception CouldNotUnfreeze of string;;
-exception Impossible;;
-exception UncookedObj;;
-
-module HashedType =
- struct
- type t = UriManager.uri * int (* uri, livello di cottura *)
- let equal (u1,n1) (u2,n2) = UriManager.eq u1 u2 && n1 = n2
- let hash = Hashtbl.hash
- end
-;;
-
-(* Hashtable that uses == instead of = for testing equality *)
-module HashTable = Hashtbl.Make(HashedType);;
-
-let hashtable = HashTable.create 271;;
-(* n is the number of time that the object must be cooked *)
-let get_obj_and_type_checking_info uri n =
- try
- HashTable.find hashtable (uri,n)
- with
- Not_found ->
- try
- match HashTable.find hashtable (uri,0) with
- Cooked _
- | Frozen _ -> raise Impossible
- | Unchecked _ as t -> t
- with
- Not_found ->
- let filename = Getter.getxml uri in
- let (annobj,_) = CicParser.term_of_xml filename uri false in
- let obj = Deannotate.deannotate_obj annobj in
- let output = Unchecked obj in
- HashTable.add hashtable (uri,0) output ;
- output
-;;
-
-(* DANGEROUS!!! *)
-(* USEFUL ONLY DURING THE FIXING OF THE FILES *)
-(* change_obj uri (Some newobj) *)
-(* maps uri to newobj in cache. *)
-(* change_obj uri None *)
-(* maps uri to a freeze dummy-object. *)
-let change_obj uri newobj =
- let newobj =
- match newobj with
- Some newobj' -> Unchecked newobj'
- | None -> Frozen (Cic.Variable ("frozen-dummy", None, Cic.Implicit))
- in
- HashTable.remove hashtable (uri,0) ;
- HashTable.add hashtable (uri,0) newobj
+(* Cache that uses == instead of = for testing equality *)
+(* Invariant: an object is always in at most one of the *)
+(* following states: unchecked, frozen and cooked. *)
+module Cache :
+ sig
+ val find_or_add_unchecked :
+ UriManager.uri -> get_object_to_add:(unit -> Cic.obj) -> Cic.obj
+ val unchecked_to_frozen : UriManager.uri -> unit
+ val frozen_to_cooked :
+ uri:UriManager.uri ->
+ cooking_procedure:
+ (object_to_cook:Cic.obj ->
+ add_cooked:(UriManager.uri * int-> Cic.obj -> unit)
+ -> unit
+ )
+ -> unit
+ val find_cooked : key:(UriManager.uri * int) -> Cic.obj
+ end
+=
+ struct
+ module CacheOfCookedObjects :
+ sig
+ val mem : UriManager.uri -> int -> bool
+ val find : UriManager.uri -> int -> Cic.obj
+ val add : UriManager.uri -> int -> Cic.obj -> unit
+ end
+ =
+ struct
+ module HashedType =
+ struct
+ type t = UriManager.uri
+ let equal = UriManager.eq
+ let hash = Hashtbl.hash
+ end
+ ;;
+ module HT = Hashtbl.Make(HashedType);;
+ let hashtable = HT.create 1009;;
+ let mem uri cookingsno =
+ try
+ let cooked_list =
+ HT.find hashtable uri
+ in
+ List.mem_assq cookingsno !cooked_list
+ with
+ Not_found -> false
+ ;;
+ let find uri cookingsno =
+ List.assq cookingsno !(HT.find hashtable uri)
+ ;;
+ let add uri cookingsno obj =
+ let cooked_list =
+ try
+ HT.find hashtable uri
+ with
+ Not_found ->
+ let newl = ref [] in
+ HT.add hashtable uri newl ;
+ newl
+ in
+ cooked_list := (cookingsno,obj)::!cooked_list
+ ;;
+ end
+ ;;
+ let frozen_list = ref [];;
+ let unchecked_list = ref [];;
+
+ let find_or_add_unchecked uri ~get_object_to_add =
+ try
+ List.assq uri !unchecked_list
+ with
+ Not_found ->
+ if List.mem_assq uri !frozen_list then
+ raise (CircularDependency (UriManager.string_of_uri uri))
+ else
+ if CacheOfCookedObjects.mem uri 0 then
+ raise (AlreadyCooked (UriManager.string_of_uri uri))
+ else
+ (* OK, it is not already frozen nor cooked *)
+ let obj = get_object_to_add () in
+ unchecked_list := (uri,obj)::!unchecked_list ;
+ obj
+ ;;
+ let unchecked_to_frozen uri =
+ try
+ let obj = List.assq uri !unchecked_list in
+ unchecked_list := List.remove_assq uri !unchecked_list ;
+ frozen_list := (uri,obj)::!frozen_list
+ with
+ Not_found -> raise (CouldNotFreeze (UriManager.string_of_uri uri))
+ ;;
+ let frozen_to_cooked ~uri ~cooking_procedure =
+ try
+ let obj = List.assq uri !frozen_list in
+ frozen_list := List.remove_assq uri !frozen_list ;
+ cooking_procedure
+ ~object_to_cook:obj
+ ~add_cooked:(fun (uri,cookno) -> CacheOfCookedObjects.add uri cookno)
+ with
+ Not_found -> raise (CouldNotUnfreeze (UriManager.string_of_uri uri))
+ ;;
+ let find_cooked ~key:(uri,cookingsno)= CacheOfCookedObjects.find uri cookingsno;;
+ end
;;
-let is_annotation_uri uri =
- Str.string_match (Str.regexp ".*\.ann$") (UriManager.string_of_uri uri) 0
+(* get_cooked_obj uri *)
+(* returns the cooked cic object whose uri is uri. The term must be present *)
+(* and cooked in cache *)
+let get_cooked_obj uri cookingsno =
+ Cache.find_cooked (uri,cookingsno)
;;
-(* returns both the annotated and deannotated uncooked forms (plus the *)
-(* map from ids to annotation targets) *)
-let get_annobj_and_type_checking_info uri =
- let filename = Getter.getxml uri in
- match CicParser.term_of_xml filename uri true with
- (_, None) -> raise Impossible
- | (annobj, Some ids_to_targets) ->
- (* If uri is the uri of an annotation, let's use the annotation file *)
- if is_annotation_uri uri then
-(* CSC: la roba annotata non dovrebbe piu' servire
- AnnotationParser.annotate (Getter.get_ann uri) ids_to_targets ;
-*) assert false ;
- try
- (annobj, ids_to_targets, HashTable.find hashtable (uri,0))
- with
- Not_found ->
- let obj = Deannotate.deannotate_obj annobj in
- let output = Unchecked obj in
- HashTable.add hashtable (uri,0) output ;
- (annobj, ids_to_targets, output)
+let find_or_add_unchecked_to_cache uri =
+ Cache.find_or_add_unchecked uri
+ ~get_object_to_add:
+ (function () ->
+ let filename = Getter.getxml uri in
+ let obj = CicParser.obj_of_xml filename uri in
+ obj
+ )
;;
-
(* get_obj uri *)
(* returns the cic object whose uri is uri. If the term is not just in cache, *)
(* then it is parsed via CicParser.term_of_xml from the file whose name is *)
(* the result of Getter.getxml uri *)
let get_obj uri =
- match get_obj_and_type_checking_info uri 0 with
- Unchecked obj -> obj
- | Frozen obj -> obj
- | Cooked obj -> obj
-;;
-
-(* get_annobj uri *)
-(* returns the cic object whose uri is uri either in annotated and *)
-(* deannotated form. The term is put into the cache if it's not there yet. *)
-let get_annobj uri =
- let (ann, ids_to_targets, deann) = get_annobj_and_type_checking_info uri in
- let deannobj =
- match deann with
- Unchecked obj -> obj
- | Frozen _ -> raise (CircularDependency (UriManager.string_of_uri uri))
- | Cooked obj -> obj
- in
- (ann, ids_to_targets, deannobj)
-;;
-
-(*CSC Commento falso *)
-(* get_obj uri *)
-(* returns the cooked cic object whose uri is uri. The term must be present *)
-(* and cooked in cache *)
-let rec get_cooked_obj uri cookingsno =
- match get_obj_and_type_checking_info uri cookingsno with
- Unchecked _
- | Frozen _ -> raise UncookedObj
- | Cooked obj -> obj
-;;
+ try
+ get_cooked_obj uri 0
+ with
+ Not_found ->
+ find_or_add_unchecked_to_cache uri
+;;
-(* is_type_checked uri *)
+(* is_type_checked uri *)
(* CSC: commento falso ed obsoleto *)
-(* returns true if the term has been type-checked *)
-(* otherwise it returns false and freeze the term for type-checking *)
-(* set_type_checking_info must be called to unfreeze the term *)
+(* returns a CheckedObj if the term has been type-checked *)
+(* otherwise it freezes the term for type-checking and returns
+ it *)
+(* set_type_checking_info must be called to unfreeze the term *)
let is_type_checked uri cookingsno =
- match get_obj_and_type_checking_info uri cookingsno with
- Cooked obj -> CheckedObj obj
- | Unchecked obj ->
- HashTable.remove hashtable (uri,0) ;
- HashTable.add hashtable (uri,0) (Frozen obj) ;
- UncheckedObj obj
- | Frozen _ -> raise (CircularDependency (UriManager.string_of_uri uri))
+ try
+ CheckedObj (Cache.find_cooked (uri,cookingsno))
+ with
+ Not_found ->
+ let obj = find_or_add_unchecked_to_cache uri in
+ Cache.unchecked_to_frozen uri ;
+ UncheckedObj obj
;;
(* set_type_checking_info uri *)
(* must be called once the type-checking of uri is finished *)
(* The object whose uri is uri is unfreezed *)
let set_type_checking_info uri =
- match HashTable.find hashtable (uri,0) with
- Frozen obj ->
- (* let's cook the object at every level *)
- HashTable.remove hashtable (uri,0) ;
- let obj' = CicSubstitution.undebrujin_inductive_def uri obj in
- HashTable.add hashtable (uri,0) (Cooked obj') ;
- let cooked_objs = !cook_obj obj' uri in
- let last_cooked_level = ref 0 in
- let last_cooked_obj = ref obj' in
- List.iter
- (fun (n,cobj) ->
- for i = !last_cooked_level + 1 to n do
- HashTable.add hashtable (uri,i) (Cooked !last_cooked_obj)
- done ;
- HashTable.add hashtable (uri,n + 1) (Cooked cobj) ;
- last_cooked_level := n + 1 ;
- last_cooked_obj := cobj
- ) cooked_objs ;
- for i = !last_cooked_level + 1 to UriManager.depth_of_uri uri + 1 do
- HashTable.add hashtable (uri,i) (Cooked !last_cooked_obj)
- done
- | _ -> raise (CouldNotUnfreeze (UriManager.string_of_uri uri))
+ Cache.frozen_to_cooked uri
+ (fun ~object_to_cook:obj ~add_cooked ->
+ (* let's cook the object at every level *)
+ let obj' = CicSubstitution.undebrujin_inductive_def uri obj in
+ add_cooked (uri,0) obj' ;
+ let cooked_objs = !cook_obj obj' uri in
+ let last_cooked_level = ref 0 in
+ let last_cooked_obj = ref obj' in
+ List.iter
+ (fun (n,cobj) ->
+ for i = !last_cooked_level + 1 to n do
+ add_cooked (uri,i) !last_cooked_obj
+ done ;
+ add_cooked (uri,n + 1) cobj ;
+ last_cooked_level := n + 1 ;
+ last_cooked_obj := cobj
+ ) cooked_objs ;
+ for i = !last_cooked_level + 1 to UriManager.depth_of_uri uri + 1 do
+ add_cooked (uri,i) !last_cooked_obj
+ done
+ )
;;