]> matita.cs.unibo.it Git - helm.git/blob - helm/interface/cicCache.ml
Initial revision
[helm.git] / helm / interface / cicCache.ml
1 (* Copyright (C) 2000, HELM Team.
2  * 
3  * This file is part of HELM, an Hypertextual, Electronic
4  * Library of Mathematics, developed at the Computer Science
5  * Department, University of Bologna, Italy.
6  * 
7  * HELM is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * 
12  * HELM is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with HELM; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://cs.unibo.it/helm/.
24  *)
25
26 (******************************************************************************)
27 (*                                                                            *)
28 (*                               PROJECT HELM                                 *)
29 (*                                                                            *)
30 (*                Claudio Sacerdoti Coen <sacerdot@cs.unibo.it>               *)
31 (*                                 24/01/2000                                 *)
32 (*                                                                            *)
33 (* This module implements a trival cache system (an hash-table) for cic       *)
34 (* objects. Uses the getter (getter.ml) and the parser (cicParser.ml)         *)
35 (*                                                                            *)
36 (******************************************************************************)
37
38 let raise e = print_endline "***" ; flush stdout ; print_endline (Printexc.to_string e) ; flush stdout ; raise e;;
39
40 (*CSC: forse i due seguenti tipi sono da unificare? *)
41 type cooked_obj =
42    Cooked of Cic.obj
43  | Frozen of Cic.obj
44  | Unchecked of Cic.obj
45 type type_checked_obj =
46    CheckedObj of Cic.obj     (* cooked obj *)
47  | UncheckedObj of Cic.obj   (* uncooked obj *)
48 ;;
49
50 exception NoFunctionProvided;;
51
52 (* CSC: da sostituire con un (...) option ref *)
53 let cook_obj = ref (fun obj uri -> raise NoFunctionProvided);;
54
55 exception CircularDependency of string;;
56 exception CouldNotUnfreeze of string;;
57 exception Impossible;;
58 exception UncookedObj;;
59
60 module HashedType =
61  struct
62   type t = UriManager.uri * int    (* uri, livello di cottura *)
63   let equal (u1,n1) (u2,n2) = UriManager.eq u1 u2 && n1 = n2
64   let hash = Hashtbl.hash
65  end
66 ;;
67
68 (* Hashtable that uses == instead of = for testing equality *)
69 module HashTable = Hashtbl.Make(HashedType);;
70
71 let hashtable = HashTable.create 271;;
72
73 (* n is the number of time that the object must be cooked *)
74 let get_obj_and_type_checking_info uri n =
75  try
76    HashTable.find hashtable (uri,n)
77  with
78   Not_found -> 
79    try
80     match HashTable.find hashtable (uri,0) with
81         Cooked _
82       | Frozen _ -> raise Impossible
83       | Unchecked _ as t -> t
84    with
85     Not_found ->
86      let filename = Getter.get uri in
87       let (annobj,_) = CicParser.term_of_xml filename uri false in
88        let obj = Deannotate.deannotate_obj annobj in
89         let output = Unchecked obj in
90          HashTable.add hashtable (uri,0) output ;
91          output
92 ;;
93
94 (* DANGEROUS!!!                                *)
95 (* USEFUL ONLY DURING THE FIXING OF THE FILES  *)
96 (* change_obj uri (Some newobj)                *)
97 (*  maps uri to newobj in cache.               *)
98 (* change_obj uri None                         *)
99 (*  maps uri to a freeze dummy-object.         *)
100 let change_obj uri newobj =
101  let newobj =
102   match newobj with
103      Some newobj' -> Unchecked newobj'
104    | None         -> Frozen (Cic.Variable ("frozen-dummy", None, Cic.Implicit))
105  in
106   HashTable.remove hashtable (uri,0) ;
107   HashTable.add hashtable (uri,0) newobj
108 ;;
109
110 let is_annotation_uri uri =
111  Str.string_match (Str.regexp ".*\.ann$") (UriManager.string_of_uri uri) 0
112 ;;
113
114 (* returns both the annotated and deannotated uncooked forms (plus the *)
115 (* map from ids to annotation targets)                                 *)
116 let get_annobj_and_type_checking_info uri =
117  let filename = Getter.get uri in
118   match CicParser.term_of_xml filename uri true with
119      (_, None) -> raise Impossible
120    | (annobj, Some ids_to_targets) ->
121     (* If uri is the uri of an annotation, let's use the annotation file *)
122     if is_annotation_uri uri  then
123      AnnotationParser.annotate (Getter.get_ann uri) ids_to_targets ;
124     try
125       (annobj, ids_to_targets, HashTable.find hashtable (uri,0))
126     with
127      Not_found -> 
128       let obj = Deannotate.deannotate_obj annobj in
129        let output = Unchecked obj in
130         HashTable.add hashtable (uri,0) output ;
131         (annobj, ids_to_targets, output)
132 ;;
133
134
135 (* get_obj uri                                                               *)
136 (* returns the cic object whose uri is uri. If the term is not just in cache, *)
137 (* then it is parsed via CicParser.term_of_xml from the file whose name is    *)
138 (* the result of Getter.get uri                                               *)
139 let get_obj uri =
140  match get_obj_and_type_checking_info uri 0 with
141     Unchecked obj -> obj
142   | Frozen    obj -> obj
143   | Cooked    obj -> obj
144 ;;
145
146 (* get_annobj uri                                                             *)
147 (* returns the cic object whose uri is uri either in annotated and            *)
148 (* deannotated form. The term is put into the cache if it's not there yet.    *)
149 let get_annobj uri =
150  let (ann, ids_to_targets, deann) = get_annobj_and_type_checking_info uri in
151   let deannobj =
152    match deann with
153       Unchecked obj -> obj
154     | Frozen    _   -> raise (CircularDependency (UriManager.string_of_uri uri))
155     | Cooked    obj -> obj
156   in
157    (ann, ids_to_targets, deannobj)
158 ;;
159
160 (*CSC Commento falso *)
161 (* get_obj uri                                                               *)
162 (* returns the cooked cic object whose uri is uri. The term must be present  *)
163 (* and cooked in cache                                                       *)
164 let rec get_cooked_obj uri cookingsno =
165  match get_obj_and_type_checking_info uri cookingsno with
166     Unchecked _
167   | Frozen    _ -> raise UncookedObj
168   | Cooked obj -> obj
169 ;;
170
171 (* is_type_checked uri                                              *)
172 (* CSC: commento falso ed obsoleto *)
173 (* returns true if the term has been type-checked                   *)
174 (* otherwise it returns false and freeze the term for type-checking *)
175 (* set_type_checking_info must be called to unfreeze the term       *)
176 let is_type_checked uri cookingsno =
177  match get_obj_and_type_checking_info uri cookingsno with
178     Cooked obj -> CheckedObj obj
179   | Unchecked obj ->
180      HashTable.remove hashtable (uri,0) ;
181      HashTable.add hashtable (uri,0) (Frozen obj) ;
182      UncheckedObj obj
183   | Frozen _ -> raise (CircularDependency (UriManager.string_of_uri uri))
184 ;;
185
186 (* set_type_checking_info uri                               *)
187 (* must be called once the type-checking of uri is finished *)
188 (* The object whose uri is uri is unfreezed                 *)
189 let set_type_checking_info uri =
190  match HashTable.find hashtable (uri,0) with
191     Frozen obj ->
192      (* let's cook the object at every level *)
193      HashTable.remove hashtable (uri,0) ;
194      let obj' = CicSubstitution.undebrujin_inductive_def uri obj in
195       HashTable.add hashtable (uri,0) (Cooked obj') ;
196       let cooked_objs = !cook_obj obj' uri in
197        let last_cooked_level = ref 0 in
198        let last_cooked_obj = ref obj' in
199         List.iter
200          (fun (n,cobj) ->
201            for i = !last_cooked_level + 1 to n do
202             HashTable.add hashtable (uri,i) (Cooked !last_cooked_obj)
203            done ;
204            HashTable.add hashtable (uri,n + 1) (Cooked cobj) ;
205            last_cooked_level := n + 1 ;
206            last_cooked_obj := cobj
207          ) cooked_objs ;
208         for i = !last_cooked_level + 1 to UriManager.depth_of_uri uri + 1 do
209          HashTable.add hashtable (uri,i) (Cooked !last_cooked_obj)
210         done
211   | _ -> raise (CouldNotUnfreeze (UriManager.string_of_uri uri))
212 ;;