]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/cic_omdoc/cic2acic.ml
added universes
[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 sort_kind = [ `Prop | `Set | `Type of CicUniv.universe | `CProp ]
27
28 let string_of_sort = function
29   | `Prop -> "Prop"
30   | `Set -> "Set"
31   | `Type u -> "Type:" ^ string_of_int (CicUniv.univno u)
32   | `CProp -> "CProp"
33
34 let sort_of_sort = function
35   | Cic.Prop  -> `Prop
36   | Cic.Set   -> `Set
37   | Cic.Type u -> `Type u
38   | Cic.CProp -> `CProp
39
40 (* let hashtbl_add_time = ref 0.0;; *)
41
42 let xxx_add h k v =
43 (*  let t1 = Sys.time () in *)
44   Hashtbl.add h k v ;
45 (*   let t2 = Sys.time () in
46    hashtbl_add_time := !hashtbl_add_time +. t2 -. t1 *)
47 ;;
48
49 (* let number_new_type_of_aux' = ref 0;;
50 let type_of_aux'_add_time = ref 0.0;; *)
51
52 let xxx_type_of_aux' m c t =
53 (*  let t1 = Sys.time () in *)
54  let res,_ = CicTypeChecker.type_of_aux' m c t CicUniv.empty_ugraph in
55 (*  let t2 = Sys.time () in
56  type_of_aux'_add_time := !type_of_aux'_add_time +. t2 -. t1 ; *)
57  res
58 ;;
59
60 type anntypes =
61  {annsynthesized : Cic.annterm ; annexpected : Cic.annterm option}
62 ;;
63
64 let gen_id seed =
65  let res = "i" ^ string_of_int !seed in
66   incr seed ;
67   res
68 ;;
69
70 let fresh_id seed ids_to_terms ids_to_father_ids =
71  fun father t ->
72   let res = gen_id seed in
73    xxx_add ids_to_father_ids res father ;
74    xxx_add ids_to_terms res t ;
75    res
76 ;;
77
78 let source_id_of_id id = "#source#" ^ id;;
79
80 exception NotEnoughElements;;
81
82 (*CSC: cut&paste da cicPp.ml *)
83 (* get_nth l n   returns the nth element of the list l if it exists or *)
84 (* raises NotEnoughElements if l has less than n elements             *)
85 let rec get_nth l n =
86  match (n,l) with
87     (1, he::_) -> he
88   | (n, he::tail) when n > 1 -> get_nth tail (n-1)
89   | (_,_) -> raise NotEnoughElements
90 ;;
91
92 let acic_of_cic_context' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
93      ids_to_inner_types metasenv context idrefs t expectedty
94 =
95  let module D = DoubleTypeInference in
96  let module C = Cic in
97   let fresh_id' = fresh_id seed ids_to_terms ids_to_father_ids in
98 (*    let time1 = Sys.time () in *)
99    let terms_to_types =
100 (*
101      let time0 = Sys.time () in
102      let prova = CicTypeChecker.type_of_aux' metasenv context t in
103      let time1 = Sys.time () in
104      prerr_endline ("*** Fine type_inference:" ^ (string_of_float (time1 -. time0)));
105      let res = D.double_type_of metasenv context t expectedty in
106      let time2 = Sys.time () in
107    prerr_endline ("*** Fine double_type_inference:" ^ (string_of_float (time2 -. time1)));
108      res 
109 *)
110     D.double_type_of metasenv context t expectedty
111    in
112 (*
113    let time2 = Sys.time () in
114    prerr_endline
115     ("++++++++++++ Tempi della double_type_of: "^ string_of_float (time2 -. time1)) ;
116 *)
117     let rec aux computeinnertypes father context idrefs tt =
118      let fresh_id'' = fresh_id' father tt in
119      (*CSC: computeinnertypes era true, il che e' proprio sbagliato, no? *)
120      let aux' = aux computeinnertypes (Some fresh_id'') in
121       (* First of all we compute the inner type and the inner sort *)
122       (* of the term. They may be useful in what follows.          *)
123       (*CSC: This is a very inefficient way of computing inner types *)
124       (*CSC: and inner sorts: very deep terms have their types/sorts *)
125       (*CSC: computed again and again.                               *)
126       let sort_of t =
127        match CicReduction.whd context t with 
128           C.Sort C.Prop  -> `Prop
129         | C.Sort C.Set   -> `Set
130         | C.Sort (C.Type u) -> `Type u
131         | C.Meta _       -> `Type (CicUniv.fresh())
132         | C.Sort C.CProp -> `CProp
133         | t              ->
134             prerr_endline ("Cic2acic.sort_of applied to: " ^ CicPp.ppterm t) ;
135             assert false
136       in
137        let ainnertypes,innertype,innersort,expected_available =
138 (*CSC: Here we need the algorithm for Coscoy's double type-inference  *)
139 (*CSC: (expected type + inferred type). Just for now we use the usual *)
140 (*CSC: type-inference, but the result is very poor. As a very weak    *)
141 (*CSC: patch, I apply whd to the computed type. Full beta             *)
142 (*CSC: reduction would be a much better option.                       *)
143 (*CSC: solo per testare i tempi *)
144 (*XXXXXXX *)
145         try
146 (* *)
147         let {D.synthesized = synthesized; D.expected = expected} =
148          if computeinnertypes then
149           D.CicHash.find terms_to_types tt
150          else
151           (* We are already in an inner-type and Coscoy's double *)
152           (* type inference algorithm has not been applied.      *)
153           {D.synthesized =
154 (***CSC: patch per provare i tempi
155             CicReduction.whd context (xxx_type_of_aux' metasenv context tt) ; *)
156 Cic.Sort (Cic.Type (CicUniv.fresh())); (* TASSI: non dovrebbe fare danni *)
157           D.expected = None}
158         in
159 (*          incr number_new_type_of_aux' ; *)
160          let innersort = (*XXXXX *) xxx_type_of_aux' metasenv context synthesized (* Cic.Sort Cic.Prop *) in
161           let ainnertypes,expected_available =
162            if computeinnertypes then
163             let annexpected,expected_available =
164                match expected with
165                   None -> None,false
166                 | Some expectedty' ->
167                    Some
168                     (aux false (Some fresh_id'') context idrefs expectedty'),
169                     true
170             in
171              Some
172               {annsynthesized =
173                 aux false (Some fresh_id'') context idrefs synthesized ;
174                annexpected = annexpected
175               }, expected_available
176            else
177             None,false
178           in
179            ainnertypes,synthesized, sort_of innersort, expected_available
180 (*XXXXXXXX *)
181         with
182          Not_found ->  (* l'inner-type non e' nella tabella ==> sort <> Prop *)
183           (* CSC: Type or Set? I can not tell *)
184           let u = CicUniv.fresh() in
185           None,Cic.Sort (Cic.Type u),`Type u,false 
186           (* TASSI non dovrebbe fare danni *)
187 (* *)
188        in
189         let add_inner_type id =
190          match ainnertypes with
191             None -> ()
192           | Some ainnertypes -> xxx_add ids_to_inner_types id ainnertypes
193         in
194          match tt with
195             C.Rel n ->
196              let id =
197               match get_nth context n with
198                  (Some (C.Name s,_)) -> s
199                | _ -> "__" ^ string_of_int n
200              in
201               xxx_add ids_to_inner_sorts fresh_id'' innersort ;
202               if innersort = `Prop  && expected_available then
203                add_inner_type fresh_id'' ;
204               C.ARel (fresh_id'', List.nth idrefs (n-1), n, id)
205           | C.Var (uri,exp_named_subst) ->
206              xxx_add ids_to_inner_sorts fresh_id'' innersort ;
207              if innersort = `Prop  && expected_available then
208               add_inner_type fresh_id'' ;
209              let exp_named_subst' =
210               List.map
211                (function i,t -> i, (aux' context idrefs t)) exp_named_subst
212              in
213               C.AVar (fresh_id'', uri,exp_named_subst')
214           | C.Meta (n,l) ->
215              let (_,canonical_context,_) = CicUtil.lookup_meta n metasenv in
216              xxx_add ids_to_inner_sorts fresh_id'' innersort ;
217              if innersort = `Prop  && expected_available then
218               add_inner_type fresh_id'' ;
219              C.AMeta (fresh_id'', n,
220               (List.map2
221                 (fun ct t ->
222                   match (ct, t) with
223                   | None, _ -> None
224                   | _, Some t -> Some (aux' context idrefs t)
225                   | Some _, None -> assert false (* due to typing rules *))
226                 canonical_context l))
227           | C.Sort s -> C.ASort (fresh_id'', s)
228           | C.Implicit annotation -> C.AImplicit (fresh_id'', annotation)
229           | C.Cast (v,t) ->
230              xxx_add ids_to_inner_sorts fresh_id'' innersort ;
231              if innersort = `Prop then
232               add_inner_type fresh_id'' ;
233              C.ACast (fresh_id'', aux' context idrefs v, aux' context idrefs t)
234           | C.Prod (n,s,t) ->
235               xxx_add ids_to_inner_sorts fresh_id''
236                (sort_of innertype) ;
237                     let sourcetype = xxx_type_of_aux' metasenv context s in
238                      xxx_add ids_to_inner_sorts (source_id_of_id fresh_id'')
239                       (sort_of sourcetype) ;
240               let n' =
241                match n with
242                   C.Anonymous -> n
243                 | C.Name n' ->
244                    if DoubleTypeInference.does_not_occur 1 t then
245                     C.Anonymous
246                    else
247                     C.Name n'
248               in
249                C.AProd
250                 (fresh_id'', n', aux' context idrefs s,
251                  aux' ((Some (n, C.Decl s))::context) (fresh_id''::idrefs) t)
252           | C.Lambda (n,s,t) ->
253              xxx_add ids_to_inner_sorts fresh_id'' innersort ;
254                    let sourcetype = xxx_type_of_aux' metasenv context s in
255                     xxx_add ids_to_inner_sorts (source_id_of_id fresh_id'')
256                      (sort_of sourcetype) ;
257               if innersort = `Prop then
258                begin
259                 let father_is_lambda =
260                  match father with
261                     None -> false
262                   | Some father' ->
263                      match Hashtbl.find ids_to_terms father' with
264                         C.Lambda _ -> true
265                       | _ -> false
266                 in
267                  if (not father_is_lambda) || expected_available then
268                   add_inner_type fresh_id''
269                end ;
270               C.ALambda
271                (fresh_id'',n, aux' context idrefs s,
272                 aux' ((Some (n, C.Decl s)::context)) (fresh_id''::idrefs) t)
273           | C.LetIn (n,s,t) ->
274              xxx_add ids_to_inner_sorts fresh_id'' innersort ;
275              if innersort = `Prop then
276               add_inner_type fresh_id'' ;
277              C.ALetIn
278               (fresh_id'', n, aux' context idrefs s,
279                aux' ((Some (n, C.Def(s,None)))::context) (fresh_id''::idrefs) t)
280           | C.Appl l ->
281              xxx_add ids_to_inner_sorts fresh_id'' innersort ;
282              if innersort = `Prop then
283               add_inner_type fresh_id'' ;
284              C.AAppl (fresh_id'', List.map (aux' context idrefs) l)
285           | C.Const (uri,exp_named_subst) ->
286              xxx_add ids_to_inner_sorts fresh_id'' innersort ;
287              if innersort = `Prop  && expected_available then
288               add_inner_type fresh_id'' ;
289              let exp_named_subst' =
290               List.map
291                (function i,t -> i, (aux' context idrefs t)) exp_named_subst
292              in
293               C.AConst (fresh_id'', uri, exp_named_subst')
294           | C.MutInd (uri,tyno,exp_named_subst) ->
295              let exp_named_subst' =
296               List.map
297                (function i,t -> i, (aux' context idrefs t)) exp_named_subst
298              in
299               C.AMutInd (fresh_id'', uri, tyno, exp_named_subst')
300           | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
301              xxx_add ids_to_inner_sorts fresh_id'' innersort ;
302              if innersort = `Prop  && expected_available then
303               add_inner_type fresh_id'' ;
304              let exp_named_subst' =
305               List.map
306                (function i,t -> i, (aux' context idrefs t)) exp_named_subst
307              in
308               C.AMutConstruct (fresh_id'', uri, tyno, consno, exp_named_subst')
309           | C.MutCase (uri, tyno, outty, term, patterns) ->
310              xxx_add ids_to_inner_sorts fresh_id'' innersort ;
311              if innersort = `Prop then
312               add_inner_type fresh_id'' ;
313              C.AMutCase (fresh_id'', uri, tyno, aux' context idrefs outty,
314               aux' context idrefs term, List.map (aux' context idrefs) patterns)
315           | C.Fix (funno, funs) ->
316              let fresh_idrefs =
317               List.map (function _ -> gen_id seed) funs in
318              let new_idrefs = List.rev fresh_idrefs @ idrefs in
319              let tys =
320               List.map (fun (name,_,ty,_) -> Some (C.Name name, C.Decl ty)) funs
321              in
322               xxx_add ids_to_inner_sorts fresh_id'' innersort ;
323               if innersort = `Prop then
324                add_inner_type fresh_id'' ;
325               C.AFix (fresh_id'', funno,
326                List.map2
327                 (fun id (name, indidx, ty, bo) ->
328                   (id, name, indidx, aux' context idrefs ty,
329                     aux' (tys@context) new_idrefs bo)
330                 ) fresh_idrefs funs
331              )
332           | C.CoFix (funno, funs) ->
333              let fresh_idrefs =
334               List.map (function _ -> gen_id seed) funs in
335              let new_idrefs = List.rev fresh_idrefs @ idrefs in
336              let tys =
337               List.map (fun (name,ty,_) -> Some (C.Name name, C.Decl ty)) funs
338              in
339               xxx_add ids_to_inner_sorts fresh_id'' innersort ;
340               if innersort = `Prop then
341                add_inner_type fresh_id'' ;
342               C.ACoFix (fresh_id'', funno,
343                List.map2
344                 (fun id (name, ty, bo) ->
345                   (id, name, aux' context idrefs ty,
346                     aux' (tys@context) new_idrefs bo)
347                 ) fresh_idrefs funs
348               )
349         in
350 (*
351          let timea = Sys.time () in
352          let res = aux true None context idrefs t in
353          let timeb = Sys.time () in
354           prerr_endline
355            ("+++++++++++++ Tempi della aux dentro alla acic_of_cic: "^ string_of_float (timeb -. timea)) ;
356           res
357 *)
358         aux true None context idrefs t
359 ;;
360
361 let acic_of_cic_context metasenv context idrefs t =
362  let ids_to_terms = Hashtbl.create 503 in
363  let ids_to_father_ids = Hashtbl.create 503 in
364  let ids_to_inner_sorts = Hashtbl.create 503 in
365  let ids_to_inner_types = Hashtbl.create 503 in
366  let seed = ref 0 in
367    acic_of_cic_context' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
368     ids_to_inner_types metasenv context idrefs t,
369    ids_to_terms, ids_to_father_ids, ids_to_inner_sorts, ids_to_inner_types
370 ;;
371
372 let aconjecture_of_conjecture seed ids_to_terms ids_to_father_ids 
373   ids_to_inner_sorts ids_to_inner_types ids_to_hypotheses hypotheses_seed
374   metasenv (metano,context,goal) = 
375   let acic_of_cic_context =
376     acic_of_cic_context' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
377       ids_to_inner_types  metasenv in
378   let _, acontext,final_idrefs =
379     (List.fold_right
380       (fun binding (context, acontext,idrefs) ->
381          let hid = "h" ^ string_of_int !hypotheses_seed in
382            Hashtbl.add ids_to_hypotheses hid binding ;
383            incr hypotheses_seed ;
384            match binding with
385                Some (n,Cic.Def (t,None)) ->
386                  let acic = acic_of_cic_context context idrefs t None in
387                  (binding::context),
388                    ((hid,Some (n,Cic.ADef acic))::acontext),(hid::idrefs)
389              | Some (n,Cic.Decl t) ->
390                  let acic = acic_of_cic_context context idrefs t None in
391                  (binding::context),
392                    ((hid,Some (n,Cic.ADecl acic))::acontext),(hid::idrefs)
393              | None ->
394                  (* Invariant: "" is never looked up *)
395                   (None::context),((hid,None)::acontext),""::idrefs
396              | Some (_,Cic.Def (_,Some _)) -> assert false
397          ) context ([],[],[])
398        )
399   in 
400   let agoal = acic_of_cic_context context final_idrefs goal None in
401   (metano,acontext,agoal)
402 ;;
403
404 let asequent_of_sequent (metasenv:Cic.metasenv) (sequent:Cic.conjecture) = 
405     let ids_to_terms = Hashtbl.create 503 in
406     let ids_to_father_ids = Hashtbl.create 503 in
407     let ids_to_inner_sorts = Hashtbl.create 503 in
408     let ids_to_inner_types = Hashtbl.create 503 in
409     let ids_to_hypotheses = Hashtbl.create 23 in
410     let hypotheses_seed = ref 0 in
411     let seed = ref 1 in (* 'i0' is used for the whole sequent *)
412     let sequent =
413      let i,canonical_context,term = sequent in
414       let canonical_context' =
415        List.fold_right
416         (fun d canonical_context' ->
417           let d =
418            match d with
419               None -> None
420             | Some (n, Cic.Decl t)->
421                Some (n, Cic.Decl (Unshare.unshare t))
422             | Some (n, Cic.Def (t,None)) ->
423                Some (n, Cic.Def ((Unshare.unshare t),None))
424             | Some (_,Cic.Def (_,Some _)) -> assert false
425           in
426            d::canonical_context'
427         ) canonical_context []
428       in
429       let term' = Unshare.unshare term in
430        (i,canonical_context',term')
431     in
432     let (metano,acontext,agoal) = 
433       aconjecture_of_conjecture seed ids_to_terms ids_to_father_ids 
434       ids_to_inner_sorts ids_to_inner_types ids_to_hypotheses hypotheses_seed
435       metasenv sequent in
436     ("i0",metano,acontext,agoal), 
437      ids_to_terms,ids_to_father_ids,ids_to_inner_sorts,ids_to_hypotheses
438 ;;
439
440 let acic_object_of_cic_object ?(eta_fix=true) obj =
441  let module C = Cic in
442  let module E = Eta_fixing in
443   let ids_to_terms = Hashtbl.create 503 in
444   let ids_to_father_ids = Hashtbl.create 503 in
445   let ids_to_inner_sorts = Hashtbl.create 503 in
446   let ids_to_inner_types = Hashtbl.create 503 in
447   let ids_to_conjectures = Hashtbl.create 11 in
448   let ids_to_hypotheses = Hashtbl.create 127 in
449   let hypotheses_seed = ref 0 in
450   let conjectures_seed = ref 0 in
451   let seed = ref 0 in
452   let acic_term_of_cic_term_context' =
453    acic_of_cic_context' seed ids_to_terms ids_to_father_ids ids_to_inner_sorts
454     ids_to_inner_types in
455   let acic_term_of_cic_term' = acic_term_of_cic_term_context' [] [] [] in
456   let aconjecture_of_conjecture' = aconjecture_of_conjecture seed 
457     ids_to_terms ids_to_father_ids ids_to_inner_sorts ids_to_inner_types 
458     ids_to_hypotheses hypotheses_seed in 
459    let eta_fix metasenv context t =
460     let t = if eta_fix then E.eta_fix metasenv context t else t in
461      Unshare.unshare t in
462    let aobj =
463     match obj with
464       C.Constant (id,Some bo,ty,params,attrs) ->
465        let bo' = eta_fix [] [] bo in
466        let ty' = eta_fix [] [] ty in
467        let abo = acic_term_of_cic_term' bo' (Some ty') in
468        let aty = acic_term_of_cic_term' ty' None in
469         C.AConstant
470          ("mettereaposto",Some "mettereaposto2",id,Some abo,aty,params,attrs)
471     | C.Constant (id,None,ty,params,attrs) ->
472        let ty' = eta_fix [] [] ty in
473        let aty = acic_term_of_cic_term' ty' None in
474         C.AConstant
475          ("mettereaposto",None,id,None,aty,params,attrs)
476     | C.Variable (id,bo,ty,params,attrs) ->
477        let ty' = eta_fix [] [] ty in
478        let abo =
479         match bo with
480            None -> None
481          | Some bo ->
482             let bo' = eta_fix [] [] bo in
483              Some (acic_term_of_cic_term' bo' (Some ty'))
484        in
485        let aty = acic_term_of_cic_term' ty' None in
486         C.AVariable
487          ("mettereaposto",id,abo,aty,params,attrs)
488     | C.CurrentProof (id,conjectures,bo,ty,params,attrs) ->
489        let conjectures' =
490         List.map
491          (function (i,canonical_context,term) ->
492            let canonical_context' =
493             List.fold_right
494              (fun d canonical_context' ->
495                let d =
496                 match d with
497                    None -> None
498                  | Some (n, C.Decl t)->
499                     Some (n, C.Decl (eta_fix conjectures canonical_context' t))
500                  | Some (n, C.Def (t,None)) ->
501                     Some (n,
502                      C.Def ((eta_fix conjectures canonical_context' t),None))
503                  | Some (_,C.Def (_,Some _)) -> assert false
504                in
505                 d::canonical_context'
506              ) canonical_context []
507            in
508            let term' = eta_fix conjectures canonical_context' term in
509             (i,canonical_context',term')
510          ) conjectures
511        in
512        let aconjectures = 
513         List.map
514          (function (i,canonical_context,term) as conjecture ->
515            let cid = "c" ^ string_of_int !conjectures_seed in
516             xxx_add ids_to_conjectures cid conjecture ;
517             incr conjectures_seed ;
518            let (i,acanonical_context,aterm) 
519              = aconjecture_of_conjecture' conjectures conjecture in
520            (cid,i,acanonical_context,aterm))
521           conjectures' in 
522 (*        let time1 = Sys.time () in *)
523        let bo' = eta_fix conjectures' [] bo in
524        let ty' = eta_fix conjectures' [] ty in
525 (*
526        let time2 = Sys.time () in
527        prerr_endline
528         ("++++++++++ Tempi della eta_fix: "^ string_of_float (time2 -. time1)) ;
529        hashtbl_add_time := 0.0 ;
530        type_of_aux'_add_time := 0.0 ;
531        DoubleTypeInference.syntactic_equality_add_time := 0.0 ;
532 *)
533        let abo =
534         acic_term_of_cic_term_context' conjectures' [] [] bo' (Some ty') in
535        let aty = acic_term_of_cic_term_context' conjectures' [] [] ty' None in
536 (*
537        let time3 = Sys.time () in
538        prerr_endline
539         ("++++++++++++ Tempi della hashtbl_add_time: " ^ string_of_float !hashtbl_add_time) ;
540        prerr_endline
541         ("++++++++++++ Tempi della type_of_aux'_add_time(" ^ string_of_int !number_new_type_of_aux' ^ "): " ^ string_of_float !type_of_aux'_add_time) ;
542        prerr_endline
543         ("++++++++++++ Tempi della type_of_aux'_add_time nella double_type_inference(" ^ string_of_int !DoubleTypeInference.number_new_type_of_aux'_double_work ^ ";" ^ string_of_int !DoubleTypeInference.number_new_type_of_aux'_prop ^ "/" ^ string_of_int !DoubleTypeInference.number_new_type_of_aux' ^ "): " ^ string_of_float !DoubleTypeInference.type_of_aux'_add_time) ;
544        prerr_endline
545         ("++++++++++++ Tempi della syntactic_equality_add_time: " ^ string_of_float !DoubleTypeInference.syntactic_equality_add_time) ;
546        prerr_endline
547         ("++++++++++ Tempi della acic_of_cic: " ^ string_of_float (time3 -. time2)) ;
548        prerr_endline
549         ("++++++++++ Numero di iterazioni della acic_of_cic: " ^ string_of_int !seed) ;
550 *)
551         C.ACurrentProof
552          ("mettereaposto","mettereaposto2",id,aconjectures,abo,aty,params,attrs)
553     | C.InductiveDefinition (tys,params,paramsno,attrs) ->
554        let tys =
555         List.map
556          (fun (name,i,arity,cl) ->
557            (name,i,Unshare.unshare arity,
558              List.map (fun (name,ty) -> name,Unshare.unshare ty) cl)) tys in
559        let context =
560         List.map
561          (fun (name,_,arity,_) ->
562            Some (C.Name name, C.Decl (Unshare.unshare arity))) tys in
563        let idrefs = List.map (function _ -> gen_id seed) tys in
564        let atys =
565         List.map2
566          (fun id (name,inductive,ty,cons) ->
567            let acons =
568             List.map
569              (function (name,ty) ->
570                (name,
571                  acic_term_of_cic_term_context' [] context idrefs ty None)
572              ) cons
573            in
574             (id,name,inductive,acic_term_of_cic_term' ty None,acons)
575          ) (List.rev idrefs) tys
576        in
577         C.AInductiveDefinition ("mettereaposto",atys,params,paramsno,attrs)
578    in
579     aobj,ids_to_terms,ids_to_father_ids,ids_to_inner_sorts,ids_to_inner_types,
580      ids_to_conjectures,ids_to_hypotheses
581 ;;
582
583 let plain_acic_term_of_cic_term =
584  let module C = Cic in
585  let mk_fresh_id =
586   let id = ref 0 in
587    function () -> incr id; "i" ^ string_of_int !id in
588  let rec aux context t =
589   let fresh_id = mk_fresh_id () in
590   match t with
591      C.Rel n ->
592       let idref,id =
593        match get_nth context n with
594           idref,(Some (C.Name s,_)) -> idref,s
595         | idref,_ -> idref,"__" ^ string_of_int n
596       in
597        C.ARel (fresh_id, idref, n, id)
598    | C.Var (uri,exp_named_subst) ->
599       let exp_named_subst' =
600        List.map
601         (function i,t -> i, (aux context t)) exp_named_subst
602       in
603        C.AVar (fresh_id,uri,exp_named_subst')
604    | C.Implicit _
605    | C.Meta _ -> assert false
606    | C.Sort s -> C.ASort (fresh_id, s)
607    | C.Cast (v,t) ->
608       C.ACast (fresh_id, aux context v, aux context t)
609    | C.Prod (n,s,t) ->
610         C.AProd
611          (fresh_id, n, aux context s,
612           aux ((fresh_id, Some (n, C.Decl s))::context) t)
613    | C.Lambda (n,s,t) ->
614        C.ALambda
615         (fresh_id,n, aux context s,
616          aux ((fresh_id, Some (n, C.Decl s))::context) t)
617    | C.LetIn (n,s,t) ->
618       C.ALetIn
619        (fresh_id, n, aux context s,
620         aux ((fresh_id, Some (n, C.Def(s,None)))::context) t)
621    | C.Appl l ->
622       C.AAppl (fresh_id, List.map (aux context) l)
623    | C.Const (uri,exp_named_subst) ->
624       let exp_named_subst' =
625        List.map
626         (function i,t -> i, (aux context t)) exp_named_subst
627       in
628        C.AConst (fresh_id, uri, exp_named_subst')
629    | C.MutInd (uri,tyno,exp_named_subst) ->
630       let exp_named_subst' =
631        List.map
632         (function i,t -> i, (aux context t)) exp_named_subst
633       in
634        C.AMutInd (fresh_id, uri, tyno, exp_named_subst')
635    | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
636       let exp_named_subst' =
637        List.map
638         (function i,t -> i, (aux context t)) exp_named_subst
639       in
640        C.AMutConstruct (fresh_id, uri, tyno, consno, exp_named_subst')
641    | C.MutCase (uri, tyno, outty, term, patterns) ->
642       C.AMutCase (fresh_id, uri, tyno, aux context outty,
643        aux context term, List.map (aux context) patterns)
644    | C.Fix (funno, funs) ->
645       let tys =
646        List.map
647         (fun (name,_,ty,_) -> mk_fresh_id (), Some (C.Name name, C.Decl ty)) funs
648       in
649        C.AFix (fresh_id, funno,
650         List.map2
651          (fun (id,_) (name, indidx, ty, bo) ->
652            (id, name, indidx, aux context ty, aux (tys@context) bo)
653          ) tys funs
654       )
655    | C.CoFix (funno, funs) ->
656       let tys =
657        List.map (fun (name,ty,_) ->
658         mk_fresh_id (),Some (C.Name name, C.Decl ty)) funs
659       in
660        C.ACoFix (fresh_id, funno,
661         List.map2
662          (fun (id,_) (name, ty, bo) ->
663            (id, name, aux context ty, aux (tys@context) bo)
664          ) tys funs
665        )
666  in
667   aux
668 ;;
669
670 let plain_acic_object_of_cic_object obj =
671  let module C = Cic in
672  let mk_fresh_id =
673   let id = ref 0 in
674    function () -> incr id; "it" ^ string_of_int !id
675  in
676   match obj with
677     C.Constant (id,Some bo,ty,params,attrs) ->
678      let abo = plain_acic_term_of_cic_term [] bo in
679      let aty = plain_acic_term_of_cic_term [] ty in
680       C.AConstant
681        ("mettereaposto",Some "mettereaposto2",id,Some abo,aty,params,attrs)
682   | C.Constant (id,None,ty,params,attrs) ->
683      let aty = plain_acic_term_of_cic_term [] ty in
684       C.AConstant
685        ("mettereaposto",None,id,None,aty,params,attrs)
686   | C.Variable (id,bo,ty,params,attrs) ->
687      let abo =
688       match bo with
689          None -> None
690        | Some bo -> Some (plain_acic_term_of_cic_term [] bo)
691      in
692      let aty = plain_acic_term_of_cic_term [] ty in
693       C.AVariable
694        ("mettereaposto",id,abo,aty,params,attrs)
695   | C.CurrentProof _ -> assert false
696   | C.InductiveDefinition (tys,params,paramsno,attrs) ->
697      let context =
698       List.map
699        (fun (name,_,arity,_) ->
700          mk_fresh_id (), Some (C.Name name, C.Decl arity)) tys in
701      let atys =
702       List.map2
703        (fun (id,_) (name,inductive,ty,cons) ->
704          let acons =
705           List.map
706            (function (name,ty) ->
707              (name,
708                plain_acic_term_of_cic_term context ty)
709            ) cons
710          in
711           (id,name,inductive,plain_acic_term_of_cic_term [] ty,acons)
712        ) context tys
713      in
714       C.AInductiveDefinition ("mettereaposto",atys,params,paramsno,attrs)
715 ;;