]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/cic_omdoc/cic2acic.ml
Unuseful id removed from hypothesis.
[helm.git] / helm / ocaml / cic_omdoc / cic2acic.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 type anntypes =
27  {annsynthesized : Cic.annterm ; annexpected : Cic.annterm option}
28 ;;
29
30 let gen_id seed =
31  let res = "i" ^ string_of_int !seed in
32   incr seed ;
33   res
34 ;;
35
36 let fresh_id seed ids_to_terms ids_to_father_ids =
37  fun father t ->
38   let res = gen_id seed in
39    Hashtbl.add ids_to_father_ids res father ;
40    Hashtbl.add ids_to_terms res t ;
41    res
42 ;;
43
44 let source_id_of_id id = "#source#" ^ id;;
45
46 exception NotEnoughElements;;
47 exception NameExpected;;
48
49 (*CSC: cut&paste da cicPp.ml *)
50 (* get_nth l n   returns the nth element of the list l if it exists or *)
51 (* raises NotEnoughElements if l has less than n elements             *)
52 let rec get_nth l n =
53  match (n,l) with
54     (1, he::_) -> he
55   | (n, he::tail) when n > 1 -> get_nth tail (n-1)
56   | (_,_) -> raise NotEnoughElements
57 ;;
58
59 let acic_of_cic_context' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
60      ids_to_inner_types metasenv context idrefs t expectedty
61 =
62  let module D = DoubleTypeInference in
63  let module T = CicTypeChecker in
64  let module C = Cic in
65   let fresh_id' = fresh_id seed ids_to_terms ids_to_father_ids in
66 prerr_endline "*************** INIZIO DOUBLE TYPE INFERENCE ************";
67    let terms_to_types =
68     D.double_type_of metasenv context t expectedty
69    in
70 prerr_endline "*************** FINE DOUBLE TYPE INFERENCE ************";
71     let rec aux computeinnertypes father context idrefs tt =
72      let fresh_id'' = fresh_id' father tt in
73      (*CSC: computeinnertypes era true, il che e' proprio sbagliato, no? *)
74      let aux' = aux computeinnertypes (Some fresh_id'') in
75       (* First of all we compute the inner type and the inner sort *)
76       (* of the term. They may be useful in what follows.          *)
77       (*CSC: This is a very inefficient way of computing inner types *)
78       (*CSC: and inner sorts: very deep terms have their types/sorts *)
79       (*CSC: computed again and again.                               *)
80       let string_of_sort t =
81        match CicReduction.whd context t with 
82           C.Sort C.Prop -> "Prop"
83         | C.Sort C.Set  -> "Set"
84         | C.Sort C.Type -> "Type"
85         | _ -> assert false
86       in
87        let ainnertypes,innertype,innersort,expected_available =
88 (*CSC: Here we need the algorithm for Coscoy's double type-inference  *)
89 (*CSC: (expected type + inferred type). Just for now we use the usual *)
90 (*CSC: type-inference, but the result is very poor. As a very weak    *)
91 (*CSC: patch, I apply whd to the computed type. Full beta             *)
92 (*CSC: reduction would be a much better option.                       *)
93         let {D.synthesized = synthesized; D.expected = expected} =
94          if computeinnertypes then
95           D.CicHash.find terms_to_types tt
96          else
97           (* We are already in an inner-type and Coscoy's double *)
98           (* type inference algorithm has not been applied.      *)
99           {D.synthesized =
100             CicReduction.whd context (T.type_of_aux' metasenv context tt) ;
101            D.expected = None}
102         in
103          let innersort = T.type_of_aux' metasenv context synthesized in
104           let ainnertypes,expected_available =
105            if computeinnertypes then
106             let annexpected,expected_available =
107                match expected with
108                   None -> None,false
109                 | Some expectedty' ->
110                    Some
111                     (aux false (Some fresh_id'') context idrefs expectedty'),
112                     true
113             in
114              Some
115               {annsynthesized =
116                 aux false (Some fresh_id'') context idrefs synthesized ;
117                annexpected = annexpected
118               }, expected_available
119            else
120             None,false
121           in
122            ainnertypes,synthesized, string_of_sort innersort, expected_available
123        in
124         let add_inner_type id =
125          match ainnertypes with
126             None -> ()
127           | Some ainnertypes -> Hashtbl.add ids_to_inner_types id ainnertypes
128         in
129          match tt with
130             C.Rel n ->
131              let id =
132               match get_nth context n with
133                  (Some (C.Name s,_)) -> s
134                | _ -> raise NameExpected
135              in
136               Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
137               if innersort = "Prop"  && expected_available then
138                add_inner_type fresh_id'' ;
139               C.ARel (fresh_id'', List.nth idrefs (n-1), n, id)
140           | C.Var (uri,exp_named_subst) ->
141              Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
142              if innersort = "Prop"  && expected_available then
143               add_inner_type fresh_id'' ;
144              let exp_named_subst' =
145               List.map
146                (function i,t -> i, (aux' context idrefs t)) exp_named_subst
147              in
148               C.AVar (fresh_id'', uri,exp_named_subst')
149           | C.Meta (n,l) ->
150              let (_,canonical_context,_) =
151               List.find (function (m,_,_) -> n = m) metasenv
152              in
153              Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
154              if innersort = "Prop"  && expected_available then
155               add_inner_type fresh_id'' ;
156              C.AMeta (fresh_id'', n,
157               (List.map2
158                 (fun ct t ->
159                   match (ct, t) with
160                   | None, _ -> None
161                   | _, Some t -> Some (aux' context idrefs t)
162                   | Some _, None -> assert false (* due to typing rules *))
163                 canonical_context l))
164           | C.Sort s -> C.ASort (fresh_id'', s)
165           | C.Implicit -> C.AImplicit (fresh_id'')
166           | C.Cast (v,t) ->
167              Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
168              if innersort = "Prop" then
169               add_inner_type fresh_id'' ;
170              C.ACast (fresh_id'', aux' context idrefs v, aux' context idrefs t)
171           | C.Prod (n,s,t) ->
172               Hashtbl.add ids_to_inner_sorts fresh_id''
173                (string_of_sort innertype) ;
174                     let sourcetype = T.type_of_aux' metasenv context s in
175                      Hashtbl.add ids_to_inner_sorts (source_id_of_id fresh_id'')
176                       (string_of_sort sourcetype) ;
177               let n' =
178                match n with
179                   C.Anonymous -> n
180                 | C.Name n' ->
181                    if D.does_not_occur 1 t then
182                     C.Anonymous
183                    else
184                     C.Name n'
185               in
186                C.AProd
187                 (fresh_id'', n', aux' context idrefs s,
188                  aux' ((Some (n, C.Decl s))::context) (fresh_id''::idrefs) t)
189           | C.Lambda (n,s,t) ->
190              Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
191                    let sourcetype = T.type_of_aux' metasenv context s in
192                     Hashtbl.add ids_to_inner_sorts (source_id_of_id fresh_id'')
193                      (string_of_sort sourcetype) ;
194               if innersort = "Prop" then
195                begin
196                 let father_is_lambda =
197                  match father with
198                     None -> false
199                   | Some father' ->
200                      match Hashtbl.find ids_to_terms father' with
201                         C.Lambda _ -> true
202                       | _ -> false
203                 in
204                  if (not father_is_lambda) || expected_available then
205                   add_inner_type fresh_id''
206                end ;
207               C.ALambda
208                (fresh_id'',n, aux' context idrefs s,
209                 aux' ((Some (n, C.Decl s)::context)) (fresh_id''::idrefs) t)
210           | C.LetIn (n,s,t) ->
211              Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
212              if innersort = "Prop" then
213               add_inner_type fresh_id'' ;
214              C.ALetIn
215               (fresh_id'', n, aux' context idrefs s,
216                aux' ((Some (n, C.Def s))::context) (fresh_id''::idrefs) t)
217           | C.Appl l ->
218              Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
219              if innersort = "Prop" then
220               add_inner_type fresh_id'' ;
221              C.AAppl (fresh_id'', List.map (aux' context idrefs) l)
222           | C.Const (uri,exp_named_subst) ->
223              Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
224              if innersort = "Prop"  && expected_available then
225               add_inner_type fresh_id'' ;
226              let exp_named_subst' =
227               List.map
228                (function i,t -> i, (aux' context idrefs t)) exp_named_subst
229              in
230               C.AConst (fresh_id'', uri, exp_named_subst')
231           | C.MutInd (uri,tyno,exp_named_subst) ->
232              let exp_named_subst' =
233               List.map
234                (function i,t -> i, (aux' context idrefs t)) exp_named_subst
235              in
236               C.AMutInd (fresh_id'', uri, tyno, exp_named_subst')
237           | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
238              Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
239              if innersort = "Prop"  && expected_available then
240               add_inner_type fresh_id'' ;
241              let exp_named_subst' =
242               List.map
243                (function i,t -> i, (aux' context idrefs t)) exp_named_subst
244              in
245               C.AMutConstruct (fresh_id'', uri, tyno, consno, exp_named_subst')
246           | C.MutCase (uri, tyno, outty, term, patterns) ->
247              Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
248              if innersort = "Prop" then
249               add_inner_type fresh_id'' ;
250              C.AMutCase (fresh_id'', uri, tyno, aux' context idrefs outty,
251               aux' context idrefs term, List.map (aux' context idrefs) patterns)
252           | C.Fix (funno, funs) ->
253              let fresh_idrefs =
254               List.map (function _ -> gen_id seed) funs in
255              let new_idrefs = List.rev fresh_idrefs @ idrefs in
256              let tys =
257               List.map (fun (name,_,ty,_) -> Some (C.Name name, C.Decl ty)) funs
258              in
259               Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
260               if innersort = "Prop" then
261                add_inner_type fresh_id'' ;
262               C.AFix (fresh_id'', funno,
263                List.map2
264                 (fun id (name, indidx, ty, bo) ->
265                   (id, name, indidx, aux' context idrefs ty,
266                     aux' (tys@context) new_idrefs bo)
267                 ) fresh_idrefs funs
268              )
269           | C.CoFix (funno, funs) ->
270              let fresh_idrefs =
271               List.map (function _ -> gen_id seed) funs in
272              let new_idrefs = List.rev fresh_idrefs @ idrefs in
273              let tys =
274               List.map (fun (name,ty,_) -> Some (C.Name name, C.Decl ty)) funs
275              in
276               Hashtbl.add ids_to_inner_sorts fresh_id'' innersort ;
277               if innersort = "Prop" then
278                add_inner_type fresh_id'' ;
279               C.ACoFix (fresh_id'', funno,
280                List.map2
281                 (fun id (name, ty, bo) ->
282                   (id, name, aux' context idrefs ty,
283                     aux' (tys@context) new_idrefs bo)
284                 ) fresh_idrefs funs
285               )
286         in
287          aux true None context idrefs t
288 ;;
289
290 let acic_of_cic_context metasenv context idrefs t =
291  let ids_to_terms = Hashtbl.create 503 in
292  let ids_to_father_ids = Hashtbl.create 503 in
293  let ids_to_inner_sorts = Hashtbl.create 503 in
294  let ids_to_inner_types = Hashtbl.create 503 in
295  let seed = ref 0 in
296    acic_of_cic_context' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
297     ids_to_inner_types metasenv context idrefs t,
298    ids_to_terms, ids_to_father_ids, ids_to_inner_sorts, ids_to_inner_types
299 ;;
300
301 let acic_object_of_cic_object obj =
302  let module C = Cic in
303  let module E = Eta_fixing in
304   let ids_to_terms = Hashtbl.create 503 in
305   let ids_to_father_ids = Hashtbl.create 503 in
306   let ids_to_inner_sorts = Hashtbl.create 503 in
307   let ids_to_inner_types = Hashtbl.create 503 in
308   let ids_to_conjectures = Hashtbl.create 11 in
309   let ids_to_hypotheses = Hashtbl.create 127 in
310   let hypotheses_seed = ref 0 in
311   let conjectures_seed = ref 0 in
312   let seed = ref 0 in
313   let acic_term_of_cic_term_context' =
314    acic_of_cic_context' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
315     ids_to_inner_types in
316   let acic_term_of_cic_term' = acic_term_of_cic_term_context' [] [] [] in
317    let aobj =
318     match obj with
319       C.Constant (id,Some bo,ty,params) ->
320        let bo' = E.eta_fix [] bo in
321        let ty' = E.eta_fix [] ty in
322        let abo = acic_term_of_cic_term' bo' (Some ty') in
323        let aty = acic_term_of_cic_term' ty' None in
324         C.AConstant
325          ("mettereaposto",Some "mettereaposto2",id,Some abo,aty,params)
326     | C.Constant (id,None,ty,params) ->
327        let ty' = E.eta_fix [] ty in
328        let aty = acic_term_of_cic_term' ty' None in
329         C.AConstant
330          ("mettereaposto",None,id,None,aty,params)
331     | C.Variable (id,bo,ty,params) ->
332        let ty' = E.eta_fix [] ty in
333        let abo =
334         match bo with
335            None -> None
336          | Some bo ->
337             let bo' = E.eta_fix [] bo in
338              Some (acic_term_of_cic_term' bo' (Some ty'))
339        in
340        let aty = acic_term_of_cic_term' ty' None in
341         C.AVariable
342          ("mettereaposto",id,abo,aty, params)
343     | C.CurrentProof (id,conjectures,bo,ty,params) ->
344 prerr_endline "************* INIZIO ETA_FIXING (congetture) ********" ;
345        let conjectures' =
346         List.map
347          (function (i,canonical_context,term) ->
348            let canonical_context' =
349             List.map
350              (function
351                  None -> None
352                | Some (n, C.Decl t)-> Some (n, C.Decl (E.eta_fix conjectures t))
353                | Some (n, C.Def t) -> Some (n, C.Def (E.eta_fix conjectures t))
354              ) canonical_context
355            in
356            let term' = E.eta_fix conjectures term in
357             (i,canonical_context',term')
358          ) conjectures
359        in
360 prerr_endline "************* INIZIO CIC ==> ACIC (congetture) ********" ;
361        let aconjectures =
362         List.map
363          (function (i,canonical_context,term) as conjecture ->
364            let cid = "c" ^ string_of_int !conjectures_seed in
365             Hashtbl.add ids_to_conjectures cid conjecture ;
366             incr conjectures_seed ;
367             let idrefs',revacanonical_context =
368              let rec aux context idrefs =
369               function
370                  [] -> idrefs,[]
371                | hyp::tl ->
372                   let hid = "h" ^ string_of_int !hypotheses_seed in
373                   let new_idrefs = hid::idrefs in
374                    Hashtbl.add ids_to_hypotheses hid hyp ;
375                    incr hypotheses_seed ;
376                    match hyp with
377                       (Some (n,C.Decl t)) ->
378                         let final_idrefs,atl =
379                          aux (hyp::context) new_idrefs tl in
380                         let at =
381                          acic_term_of_cic_term_context'
382                           conjectures context idrefs t None
383                         in
384                          final_idrefs,(hid,Some (n,C.ADecl at))::atl
385                     | (Some (n,C.Def t)) ->
386                         let final_idrefs,atl =
387                          aux (hyp::context) new_idrefs tl in
388                         let at =
389                          acic_term_of_cic_term_context'
390                           conjectures context idrefs t None
391                         in
392                          final_idrefs,(hid,Some (n,C.ADef at))::atl
393                     | None ->
394                        let final_idrefs,atl =
395                         aux (hyp::context) new_idrefs tl
396                        in
397                         final_idrefs,(hid,None)::atl
398              in
399               aux [] [] (List.rev canonical_context)
400             in
401              let aterm =
402               acic_term_of_cic_term_context' conjectures
403                canonical_context idrefs' term None
404              in
405               (cid,i,(List.rev revacanonical_context),aterm)
406          ) conjectures' in
407 prerr_endline "*********** INIZIO ETA FIXING PROVA **********";
408        let bo' = E.eta_fix conjectures' bo in
409        let ty' = E.eta_fix conjectures' ty in
410 prerr_endline "*********** INIZIO CIC ==> ACIC PROVA **********";
411        let abo =
412         acic_term_of_cic_term_context' conjectures' [] [] bo' (Some ty') in
413        let aty = acic_term_of_cic_term_context' conjectures' [] [] ty' None in
414         C.ACurrentProof
415          ("mettereaposto","mettereaposto2",id,aconjectures,abo,aty,params)
416     | C.InductiveDefinition (tys,params,paramsno) ->
417        let context =
418         List.map
419          (fun (name,_,arity,_) -> Some (C.Name name, C.Decl arity)) tys in
420        let idrefs = List.map (function _ -> gen_id seed) tys in
421        let atys =
422         List.map2
423          (fun id (name,inductive,ty,cons) ->
424            let acons =
425             List.map
426              (function (name,ty) ->
427                (name,
428                  acic_term_of_cic_term_context' [] context idrefs ty None)
429              ) cons
430            in
431             (id,name,inductive,acic_term_of_cic_term' ty None,acons)
432          ) (List.rev idrefs) tys
433        in
434         C.AInductiveDefinition ("mettereaposto",atys,params,paramsno)
435    in
436     aobj,ids_to_terms,ids_to_father_ids,ids_to_inner_sorts,ids_to_inner_types,
437      ids_to_conjectures,ids_to_hypotheses
438 ;;