]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/cic_omdoc/cic2content.ml
All the ids are now generated by gen_id. (Some of them were previously based
[helm.git] / helm / ocaml / cic_omdoc / cic2content.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 (*                Andrea Asperti <asperti@cs.unibo.it>                    *)
31 (*                             16/62003                                   *)
32 (*                                                                        *)
33 (**************************************************************************)
34
35 let object_prefix = "obj:";;
36 let declaration_prefix = "decl:";;
37 let definition_prefix = "def:";;
38 let inductive_prefix = "ind:";;
39 let joint_prefix = "joint:";;
40 let proof_prefix = "proof:";;
41 let conclude_prefix = "concl:";;
42 let premise_prefix = "prem:";;
43 let lemma_prefix = "lemma:";;
44
45 (* e se mettessi la conversione di BY nell'apply_context ? *)
46 (* sarebbe carino avere l'invariante che la proof2pres
47 generasse sempre prove con contesto vuoto *)
48  
49 let gen_id prefix seed =
50  let res = prefix ^ string_of_int !seed in
51   incr seed ;
52   res
53 ;;
54
55 let name_of = function
56     Cic.Anonymous -> None
57   | Cic.Name b -> Some b;;
58  
59 exception Not_a_proof;;
60 exception NotImplemented;;
61 exception NotApplicable;;
62    
63 (* we do not care for positivity, here, that in any case is enforced by
64    well typing. Just a brutal search *)
65
66 let rec occur uri = 
67   let module C = Cic in
68   function
69       C.Rel _ -> false
70     | C.Var _ -> false
71     | C.Meta _ -> false
72     | C.Sort _ -> false
73     | C.Implicit -> raise NotImplemented
74     | C.Prod (_,s,t) -> (occur uri s) or (occur uri t)
75     | C.Cast (te,ty) -> (occur uri te)
76     | C.Lambda (_,s,t) -> (occur uri s) or (occur uri t) (* or false ?? *)
77     | C.LetIn (_,s,t) -> (occur uri s) or (occur uri t)
78     | C.Appl l -> 
79         List.fold_left 
80           (fun b a -> 
81              if b then b  
82              else (occur uri a)) false l
83     | C.Const (_,_) -> false
84     | C.MutInd (uri1,_,_) -> if uri = uri1 then true else false
85     | C.MutConstruct (_,_,_,_) -> false
86     | C.MutCase _ -> false (* presuming too much?? *)
87     | C.Fix _ -> false (* presuming too much?? *)
88     | C.CoFix (_,_) -> false (* presuming too much?? *)
89 ;;
90
91 let get_id = 
92   let module C = Cic in
93   function
94       C.ARel (id,_,_,_) -> id
95     | C.AVar (id,_,_) -> id
96     | C.AMeta (id,_,_) -> id
97     | C.ASort (id,_) -> id
98     | C.AImplicit _ -> raise NotImplemented
99     | C.AProd (id,_,_,_) -> id
100     | C.ACast (id,_,_) -> id
101     | C.ALambda (id,_,_,_) -> id
102     | C.ALetIn (id,_,_,_) -> id
103     | C.AAppl (id,_) -> id
104     | C.AConst (id,_,_) -> id
105     | C.AMutInd (id,_,_,_) -> id
106     | C.AMutConstruct (id,_,_,_,_) -> id
107     | C.AMutCase (id,_,_,_,_,_) -> id
108     | C.AFix (id,_,_) -> id
109     | C.ACoFix (id,_,_) -> id
110 ;;
111
112 let test_for_lifting ~ids_to_inner_types ~ids_to_inner_sorts= 
113   let module C = Cic in
114   let module C2A = Cic2acic in
115   (* atomic terms are never lifted, according to my policy *)
116   function
117       C.ARel (id,_,_,_) -> false
118     | C.AVar (id,_,_) -> 
119          (try 
120             ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
121             true;
122           with Not_found -> false) 
123     | C.AMeta (id,_,_) -> 
124          (try 
125             Hashtbl.find ids_to_inner_sorts id = "Prop"
126           with Not_found -> assert false)
127     | C.ASort (id,_) -> false
128     | C.AImplicit _ -> raise NotImplemented
129     | C.AProd (id,_,_,_) -> false
130     | C.ACast (id,_,_) -> 
131          (try 
132             ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
133             true;
134           with Not_found -> false)
135     | C.ALambda (id,_,_,_) -> 
136          (try 
137             ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
138             true;
139           with Not_found -> false)
140     | C.ALetIn (id,_,_,_) -> 
141          (try 
142             ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
143             true;
144           with Not_found -> false)
145     | C.AAppl (id,_) ->
146          (try 
147             ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
148             true;
149           with Not_found -> false) 
150     | C.AConst (id,_,_) -> 
151          (try 
152             ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
153             true;
154           with Not_found -> false) 
155     | C.AMutInd (id,_,_,_) -> false
156     | C.AMutConstruct (id,_,_,_,_) -> 
157        (try 
158             ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
159             true;
160           with Not_found -> false)
161         (* oppure: false *)
162     | C.AMutCase (id,_,_,_,_,_) ->
163          (try 
164             ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
165             true;
166           with Not_found -> false)
167     | C.AFix (id,_,_) ->
168           (try 
169             ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
170             true;
171           with Not_found -> false)
172     | C.ACoFix (id,_,_) ->
173          (try 
174             ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
175             true;
176           with Not_found -> false)
177 ;;
178
179 (* transform a proof p into a proof list, concatenating the last 
180 conclude element to the apply_context list, in case context is
181 empty. Otherwise, it just returns [p] *)
182
183 let flat seed p = 
184  let module K = Content in
185   if (p.K.proof_context = []) then
186     if p.K.proof_apply_context = [] then [p]
187     else 
188       let p1 =
189         { p with
190           K.proof_context = []; 
191           K.proof_apply_context = []
192         } in
193       p.K.proof_apply_context@[p1]
194   else 
195     [p]
196 ;;
197
198 let rec serialize seed = 
199   function 
200     [] -> []
201   | a::l -> (flat seed a)@(serialize seed l) 
202 ;;
203
204 (* top_down = true if the term is a LAMBDA or a decl *)
205 let generate_conversion seed top_down id inner_proof ~ids_to_inner_types =
206  let module C2A = Cic2acic in
207  let module K = Content in
208  let exp = (try ((Hashtbl.find ids_to_inner_types id).C2A.annexpected)
209             with Not_found -> None)
210  in
211  match exp with
212      None -> inner_proof
213    | Some expty ->
214        if inner_proof.K.proof_conclude.K.conclude_method = "Intros+LetTac" then
215          { K.proof_name = inner_proof.K.proof_name;
216             K.proof_id   = gen_id proof_prefix seed;
217             K.proof_context = [] ;
218             K.proof_apply_context = [];
219             K.proof_conclude = 
220               { K.conclude_id = gen_id conclude_prefix seed; 
221                 K.conclude_aref = id;
222                 K.conclude_method = "TD_Conversion";
223                 K.conclude_args = 
224                   [K.ArgProof {inner_proof with K.proof_name = None}];
225                 K.conclude_conclusion = Some expty
226               };
227           }
228         else
229           { K.proof_name =  inner_proof.K.proof_name;
230             K.proof_id   = gen_id proof_prefix seed;
231             K.proof_context = [] ;
232             K.proof_apply_context = [{inner_proof with K.proof_name = None}];
233             K.proof_conclude = 
234               { K.conclude_id = gen_id conclude_prefix seed; 
235                 K.conclude_aref = id;
236                 K.conclude_method = "BU_Conversion";
237                 K.conclude_args =  
238                  [K.Premise 
239                   { K.premise_id = gen_id premise_prefix seed;
240                     K.premise_xref = inner_proof.K.proof_id; 
241                     K.premise_binder = None;
242                     K.premise_n = None
243                   } 
244                  ]; 
245                 K.conclude_conclusion = Some expty
246               };
247           }
248 ;;
249
250 let generate_exact seed t id name ~ids_to_inner_types =
251   let module C2A = Cic2acic in
252   let module K = Content in
253     { K.proof_name = name;
254       K.proof_id   = gen_id proof_prefix seed ;
255       K.proof_context = [] ;
256       K.proof_apply_context = [];
257       K.proof_conclude = 
258         { K.conclude_id = gen_id conclude_prefix seed; 
259           K.conclude_aref = id;
260           K.conclude_method = "Exact";
261           K.conclude_args = [K.Term t];
262           K.conclude_conclusion = 
263               try Some (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
264               with Not_found -> None
265         };
266     }
267 ;;
268
269 let generate_intros_let_tac seed id n s is_intro inner_proof name ~ids_to_inner_types =
270   let module C2A = Cic2acic in
271   let module C = Cic in
272   let module K = Content in
273     { K.proof_name = name;
274       K.proof_id  = gen_id proof_prefix seed ;
275       K.proof_context = [] ;
276       K.proof_apply_context = [];
277       K.proof_conclude = 
278         { K.conclude_id = gen_id conclude_prefix seed; 
279           K.conclude_aref = id;
280           K.conclude_method = "Intros+LetTac";
281           K.conclude_args = [K.ArgProof inner_proof];
282           K.conclude_conclusion = 
283             try Some 
284              (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
285             with Not_found -> 
286               (match inner_proof.K.proof_conclude.K.conclude_conclusion with
287                  None -> None
288               | Some t -> 
289                   if is_intro then Some (C.AProd ("gen"^id,n,s,t))
290                   else Some (C.ALetIn ("gen"^id,n,s,t)))
291         };
292     }
293 ;;
294
295 let build_decl_item seed id n s ~ids_to_inner_sorts =
296  let module K = Content in
297   try
298    let sort = Hashtbl.find ids_to_inner_sorts (Cic2acic.source_id_of_id id) in
299    if sort = "Prop" then
300       `Hypothesis
301         { K.dec_name = name_of n;
302           K.dec_id = gen_id declaration_prefix seed; 
303           K.dec_inductive = false;
304           K.dec_aref = id;
305           K.dec_type = s
306         }
307    else 
308       `Declaration
309         { K.dec_name = name_of n;
310           K.dec_id = gen_id declaration_prefix seed; 
311           K.dec_inductive = false;
312           K.dec_aref = id;
313           K.dec_type = s
314         }
315   with
316    Not_found -> assert false
317 ;;
318
319 let rec build_subproofs_and_args seed l ~ids_to_inner_types ~ids_to_inner_sorts =
320   let module C = Cic in
321   let module K = Content in
322   let rec aux =
323     function
324       [] -> [],[]
325     | t::l1 -> 
326        let subproofs,args = aux l1 in
327         if (test_for_lifting t ~ids_to_inner_types ~ids_to_inner_sorts) then
328           let new_subproof = 
329             acic2content 
330               seed ~name:"H" ~ids_to_inner_types ~ids_to_inner_sorts t in
331           let new_arg = 
332             K.Premise
333               { K.premise_id = gen_id premise_prefix seed;
334                 K.premise_xref = new_subproof.K.proof_id;
335                 K.premise_binder = new_subproof.K.proof_name;
336                 K.premise_n = None
337               } in
338           new_subproof::subproofs,new_arg::args
339         else 
340           let hd = 
341             (match t with 
342                C.ARel (idr,idref,n,b) ->
343                  let sort = 
344                    (try Hashtbl.find ids_to_inner_sorts idr 
345                     with Not_found -> "Type") in 
346                  if sort ="Prop" then 
347                     K.Premise 
348                       { K.premise_id = gen_id premise_prefix seed;
349                         K.premise_xref = idr;
350                         K.premise_binder = Some b;
351                         K.premise_n = Some n
352                       }
353                  else (K.Term t)
354              | C.AConst(id,uri,[]) ->
355                  let sort = 
356                    (try Hashtbl.find ids_to_inner_sorts id 
357                     with Not_found -> "Type") in 
358                  if sort ="Prop" then 
359                     K.Lemma 
360                       { K.lemma_id = gen_id lemma_prefix seed;
361                         K.lemma_name = UriManager.name_of_uri uri;
362                         K.lemma_uri = UriManager.string_of_uri uri
363                       }
364                  else (K.Term t)
365              | C.AMutConstruct(id,uri,tyno,consno,[]) ->
366                  let sort = 
367                    (try Hashtbl.find ids_to_inner_sorts id 
368                     with Not_found -> "Type") in 
369                  if sort ="Prop" then 
370                     let inductive_types =
371                       (match CicEnvironment.get_obj uri with
372                          Cic.Constant _ -> assert false
373                        | Cic.Variable _ -> assert false
374                        | Cic.CurrentProof _ -> assert false
375                        | Cic.InductiveDefinition (l,_,_) -> l 
376                       ) in
377                     let (_,_,_,constructors) = 
378                       List.nth inductive_types tyno in 
379                     let name,_ = List.nth constructors (consno - 1) in
380                     K.Lemma 
381                       { K.lemma_id = gen_id lemma_prefix seed;
382                         K.lemma_name = name;
383                         K.lemma_uri = 
384                           UriManager.string_of_uri uri ^ "#xpointer(1/" ^
385                           string_of_int (tyno+1) ^ "/" ^ string_of_int consno ^
386                           ")"
387                       }
388                  else (K.Term t) 
389              | _ -> (K.Term t)) in
390           subproofs,hd::args
391   in 
392   match (aux l) with
393     [p],args -> 
394       [{p with K.proof_name = None}], 
395         List.map 
396           (function 
397               K.Premise prem when prem.K.premise_xref = p.K.proof_id ->
398                K.Premise {prem with K.premise_binder = None}
399             | i -> i) args
400   | p,a as c -> c
401
402 and
403
404 build_def_item seed id n t ~ids_to_inner_sorts ~ids_to_inner_types =
405  let module K = Content in
406   try
407    let sort = Hashtbl.find ids_to_inner_sorts id in
408    (match name_of n with
409      Some "w" -> prerr_endline ("build_def: " ^ sort );
410    | _ -> ());
411    if sort = "Prop" then
412        (prerr_endline ("entro");
413        let p = 
414         (acic2content seed ?name:(name_of n) ~ids_to_inner_sorts  ~ids_to_inner_types t)
415        in 
416         (match p.K.proof_name with
417            Some "w" -> prerr_endline ("TUTTO BENE:");
418          | Some s -> prerr_endline ("mi chiamo " ^ s);
419          | _ -> prerr_endline ("ho perso il nome"););
420       prerr_endline ("esco"); `Proof p;)
421    else 
422       (prerr_endline ("siamo qui???");
423       `Definition
424         { K.def_name = name_of n;
425           K.def_id = gen_id definition_prefix seed; 
426           K.def_aref = id;
427           K.def_term = t
428         })
429   with
430    Not_found -> assert false
431
432 (* the following function must be called with an object of sort
433 Prop. For debugging purposes this is tested again, possibly raising an 
434 Not_a_proof exception *)
435
436 and acic2content seed ?name ~ids_to_inner_sorts ~ids_to_inner_types t =
437   let rec aux ?name t =
438   let module C = Cic in
439   let module K = Content in
440   let module C2A = Cic2acic in
441   let t1 =
442     match t with 
443       C.ARel (id,idref,n,b) as t ->
444         let sort = Hashtbl.find ids_to_inner_sorts id in
445         if sort = "Prop" then
446           generate_exact seed t id name ~ids_to_inner_types 
447         else raise Not_a_proof
448     | C.AVar (id,uri,exp_named_subst) as t ->
449         let sort = Hashtbl.find ids_to_inner_sorts id in
450         if sort = "Prop" then
451           generate_exact seed t id name ~ids_to_inner_types 
452         else raise Not_a_proof
453     | C.AMeta (id,n,l) as t ->
454         let sort = Hashtbl.find ids_to_inner_sorts id in
455         if sort = "Prop" then
456           generate_exact seed t id name ~ids_to_inner_types 
457         else raise Not_a_proof
458     | C.ASort (id,s) -> raise Not_a_proof
459     | C.AImplicit _ -> raise NotImplemented
460     | C.AProd (_,_,_,_) -> raise Not_a_proof
461     | C.ACast (id,v,t) -> aux v
462     | C.ALambda (id,n,s,t) -> 
463         let sort = Hashtbl.find ids_to_inner_sorts id in
464         if sort = "Prop" then 
465           let proof = aux t in
466           let proof' = 
467             if proof.K.proof_conclude.K.conclude_method = "Intros+LetTac" then
468                match proof.K.proof_conclude.K.conclude_args with
469                  [K.ArgProof p] -> p
470                | _ -> assert false                  
471             else proof in
472           let proof'' =
473             { proof' with
474               K.proof_name = None;
475               K.proof_context = 
476                 (build_decl_item seed id n s ids_to_inner_sorts)::
477                   proof'.K.proof_context
478             }
479           in
480           generate_intros_let_tac seed id n s true proof'' name ~ids_to_inner_types
481         else raise Not_a_proof 
482     | C.ALetIn (id,n,s,t) ->
483         let sort = Hashtbl.find ids_to_inner_sorts id in
484         if sort = "Prop" then
485           let proof = aux t in
486           let proof' = 
487             if proof.K.proof_conclude.K.conclude_method = "Intros+LetTac" then
488                match proof.K.proof_conclude.K.conclude_args with
489                  [K.ArgProof p] -> p
490                | _ -> assert false                  
491             else proof in
492           let proof'' =
493             { proof' with
494                K.proof_name = None;
495                K.proof_context = 
496                  ((build_def_item seed id n s ids_to_inner_sorts 
497                    ids_to_inner_types):> Cic.annterm K.in_proof_context_element)
498                  ::proof'.K.proof_context;
499             }
500           in
501           generate_intros_let_tac seed id n s false proof'' name ~ids_to_inner_types
502         else raise Not_a_proof 
503     | C.AAppl (id,li) ->
504         (try rewrite 
505            seed name id li ~ids_to_inner_types ~ids_to_inner_sorts
506          with NotApplicable ->
507          try inductive 
508           seed name id li ~ids_to_inner_types ~ids_to_inner_sorts
509          with NotApplicable ->
510           let subproofs, args =
511             build_subproofs_and_args 
512               seed li ~ids_to_inner_types ~ids_to_inner_sorts in
513 (*            
514           let args_to_lift = 
515             List.filter (test_for_lifting ~ids_to_inner_types) li in
516           let subproofs = 
517             match args_to_lift with
518                 [_] -> List.map aux args_to_lift 
519             | _ -> List.map (aux ~name:"H") args_to_lift in
520           let args = build_args seed li subproofs 
521                  ~ids_to_inner_types ~ids_to_inner_sorts in *)
522             { K.proof_name = name;
523               K.proof_id   = gen_id proof_prefix seed;
524               K.proof_context = [];
525               K.proof_apply_context = serialize seed subproofs;
526               K.proof_conclude = 
527                 { K.conclude_id = gen_id conclude_prefix seed;
528                   K.conclude_aref = id;
529                   K.conclude_method = "Apply";
530                   K.conclude_args = args;
531                   K.conclude_conclusion = 
532                      try Some 
533                        (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
534                      with Not_found -> None
535                  };
536             })
537     | C.AConst (id,uri,exp_named_subst) as t ->
538         let sort = Hashtbl.find ids_to_inner_sorts id in
539         if sort = "Prop" then
540           generate_exact seed t id name ~ids_to_inner_types
541         else raise Not_a_proof
542     | C.AMutInd (id,uri,i,exp_named_subst) -> raise Not_a_proof
543     | C.AMutConstruct (id,uri,i,j,exp_named_subst) as t ->
544         let sort = Hashtbl.find ids_to_inner_sorts id in
545         if sort = "Prop" then 
546           generate_exact seed t id name ~ids_to_inner_types
547         else raise Not_a_proof
548     | C.AMutCase (id,uri,typeno,ty,te,patterns) ->
549         let inductive_types =
550            (match CicEnvironment.get_obj uri with
551                Cic.Constant _ -> assert false
552              | Cic.Variable _ -> assert false
553              | Cic.CurrentProof _ -> assert false
554              | Cic.InductiveDefinition (l,_,_) -> l 
555            ) in
556         let (_,_,_,constructors) = List.nth inductive_types typeno in 
557         let teid = get_id te in
558         let pp = List.map2 
559           (fun p (name,_) -> (K.ArgProof (aux ~name p))) 
560            patterns constructors in
561         let context,term =
562           (match 
563              build_subproofs_and_args 
564                seed ~ids_to_inner_types ~ids_to_inner_sorts [te]
565            with
566              l,[t] -> l,t
567            | _ -> assert false) in
568         { K.proof_name = name;
569           K.proof_id   = gen_id proof_prefix seed;
570           K.proof_context = []; 
571           K.proof_apply_context = serialize seed context;
572           K.proof_conclude = 
573             { K.conclude_id = gen_id conclude_prefix seed; 
574               K.conclude_aref = id;
575               K.conclude_method = "Case";
576               K.conclude_args = 
577                 (K.Aux (UriManager.string_of_uri uri))::
578                 (K.Aux (string_of_int typeno))::(K.Term ty)::term::pp;
579               K.conclude_conclusion = 
580                 try Some 
581                   (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
582                 with Not_found -> None  
583              }
584         }
585     | C.AFix (id, no, funs) -> 
586         let proofs = 
587           List.map 
588             (function (_,name,_,_,bo) -> `Proof (aux ~name bo)) funs in
589         let decreasing_args = 
590           List.map (function (_,_,n,_,_) -> n) funs in
591         let jo = 
592           { K.joint_id = gen_id joint_prefix seed;
593             K.joint_kind = `Recursive decreasing_args;
594             K.joint_defs = proofs
595           } 
596         in
597           { K.proof_name = name;
598             K.proof_id  = gen_id proof_prefix seed;
599             K.proof_context = [`Joint jo]; 
600             K.proof_apply_context = [];
601             K.proof_conclude = 
602               { K.conclude_id = gen_id conclude_prefix seed; 
603                 K.conclude_aref = id;
604                 K.conclude_method = "Exact";
605                 K.conclude_args =
606                 [ K.Premise
607                   { K.premise_id = gen_id premise_prefix seed; 
608                     K.premise_xref = jo.K.joint_id;
609                     K.premise_binder = Some "tiralo fuori";
610                     K.premise_n = Some no;
611                   }
612                 ];
613                 K.conclude_conclusion =
614                    try Some 
615                      (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
616                    with Not_found -> None
617               }
618         } 
619     | C.ACoFix (id,no,funs) -> 
620         let proofs = 
621           List.map 
622             (function (_,name,_,bo) -> `Proof (aux ~name bo)) funs in
623         let jo = 
624           { K.joint_id = gen_id joint_prefix seed;
625             K.joint_kind = `CoRecursive;
626             K.joint_defs = proofs
627           } 
628         in
629           { K.proof_name = name;
630             K.proof_id   = gen_id proof_prefix seed;
631             K.proof_context = [`Joint jo]; 
632             K.proof_apply_context = [];
633             K.proof_conclude = 
634               { K.conclude_id = gen_id conclude_prefix seed; 
635                 K.conclude_aref = id;
636                 K.conclude_method = "Exact";
637                 K.conclude_args =
638                 [ K.Premise
639                   { K.premise_id = gen_id premise_prefix seed; 
640                     K.premise_xref = jo.K.joint_id;
641                     K.premise_binder = Some "tiralo fuori";
642                     K.premise_n = Some no;
643                   }
644                 ];
645                 K.conclude_conclusion =
646                   try Some 
647                     (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
648                   with Not_found -> None
649               };
650         } 
651      in 
652      let id = get_id t in
653      generate_conversion seed false id t1 ~ids_to_inner_types
654 in aux ?name t
655
656 and inductive seed name id li ~ids_to_inner_types ~ids_to_inner_sorts =
657   let aux ?name = acic2content seed  ~ids_to_inner_types ~ids_to_inner_sorts in
658   let module C2A = Cic2acic in
659   let module K = Content in
660   let module C = Cic in
661   match li with 
662     C.AConst (idc,uri,exp_named_subst)::args ->
663       let uri_str = UriManager.string_of_uri uri in
664       let suffix = Str.regexp_string "_ind.con" in
665       let len = String.length uri_str in 
666       let n = (try (Str.search_backward suffix uri_str len)
667                with Not_found -> -1) in
668       if n<0 then raise NotApplicable
669       else 
670         let method_name =
671           if (uri_str = "cic:/Coq/Init/Logic_Type/exT_ind.con" or
672               uri_str = "cic:/Coq/Init/Logic/ex_ind.con") then "Exists"
673           else if uri_str = "cic:/Coq/Init/Logic/and_ind.con" then "AndInd"
674           else if uri_str = "cic:/Coq/Init/Logic/False_ind.con" then "FalseInd"
675           else "ByInduction" in
676         let prefix = String.sub uri_str 0 n in
677         let ind_str = (prefix ^ ".ind") in 
678         let ind_uri = UriManager.uri_of_string ind_str in
679         let inductive_types,noparams =
680            (match CicEnvironment.get_obj ind_uri with
681                Cic.Constant _ -> assert false
682              | Cic.Variable _ -> assert false
683              | Cic.CurrentProof _ -> assert false
684              | Cic.InductiveDefinition (l,_,n) -> (l,n) 
685            ) in
686         let rec split n l =
687           if n = 0 then ([],l) else
688           let p,a = split (n-1) (List.tl l) in
689           ((List.hd l::p),a) in
690         let params_and_IP,tail_args = split (noparams+1) args in
691         let constructors = 
692             (match inductive_types with
693               [(_,_,_,l)] -> l
694             | _ -> raise NotApplicable) (* don't care for mutual ind *) in
695         let constructors1 = 
696           let rec clean_up n t =
697              if n = 0 then t else
698              (match t with
699                 (label,Cic.Prod (_,_,t)) -> clean_up (n-1) (label,t)
700               | _ -> assert false) in
701           List.map (clean_up noparams) constructors in
702         let no_constructors= List.length constructors in
703         let args_for_cases, other_args = 
704           split no_constructors tail_args in
705         let subproofs,other_method_args =
706           build_subproofs_and_args seed other_args
707              ~ids_to_inner_types ~ids_to_inner_sorts in
708         prerr_endline "****** end other *******"; flush stderr;
709         let method_args=
710           let rec build_method_args =
711             function
712                 [],_-> [] (* extra args are ignored ???? *)
713               | (name,ty)::tlc,arg::tla ->
714                   let idarg = get_id arg in
715                   let sortarg = 
716                     (try (Hashtbl.find ids_to_inner_sorts idarg)
717                      with Not_found -> "Type") in
718                   let hdarg = 
719                     if sortarg = "Prop" then
720                       let (co,bo) = 
721                         let rec bc = 
722                           function 
723                             Cic.Prod (_,s,t),Cic.ALambda(idl,n,s1,t1) ->
724                               let ce = 
725                                 build_decl_item 
726                                   seed idl n s1 ~ids_to_inner_sorts in
727                               if (occur ind_uri s) then
728                                 (  prerr_endline ("inductive:" ^ (UriManager.string_of_uri ind_uri) ^ (CicPp.ppterm s)); flush stderr; 
729                                    match t1 with
730                                    Cic.ALambda(id2,n2,s2,t2) ->
731                                      let inductive_hyp =
732                                        `Hypothesis
733                                          { K.dec_name = name_of n2;
734                                            K.dec_id =
735                                             gen_id declaration_prefix seed; 
736                                            K.dec_inductive = true;
737                                            K.dec_aref = id2;
738                                            K.dec_type = s2
739                                          } in
740                                      let (context,body) = bc (t,t2) in
741                                      (ce::inductive_hyp::context,body)
742                                  | _ -> assert false)
743                               else 
744                                 (  prerr_endline ("no inductive:" ^ (UriManager.string_of_uri ind_uri) ^ (CicPp.ppterm s)); flush stderr; 
745                                 let (context,body) = bc (t,t1) in
746                                 (ce::context,body))
747                             | _ , t -> ([],aux t) in
748                         bc (ty,arg) in
749                       K.ArgProof
750                        { bo with
751                          K.proof_name = Some name;
752                          K.proof_context = co; 
753                        };
754                     else (K.Term arg) in
755                   hdarg::(build_method_args (tlc,tla))
756               | _ -> assert false in
757           build_method_args (constructors1,args_for_cases) in
758           { K.proof_name = name;
759             K.proof_id   = gen_id proof_prefix seed;
760             K.proof_context = []; 
761             K.proof_apply_context = serialize seed subproofs;
762             K.proof_conclude = 
763               { K.conclude_id = gen_id conclude_prefix seed; 
764                 K.conclude_aref = id;
765                 K.conclude_method = method_name;
766                 K.conclude_args =
767                   K.Aux (string_of_int no_constructors) 
768                   ::K.Term (C.AAppl id ((C.AConst(idc,uri,exp_named_subst))::params_and_IP))
769                   ::method_args@other_method_args;
770                 K.conclude_conclusion = 
771                    try Some 
772                      (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
773                    with Not_found -> None  
774               }
775           } 
776   | _ -> raise NotApplicable
777
778 and rewrite seed name id li ~ids_to_inner_types ~ids_to_inner_sorts =
779   let aux ?name = acic2content seed ~ids_to_inner_types ~ids_to_inner_sorts in
780   let module C2A = Cic2acic in
781   let module K = Content in
782   let module C = Cic in
783   match li with 
784     C.AConst (sid,uri,exp_named_subst)::args ->
785       let uri_str = UriManager.string_of_uri uri in
786       if uri_str = "cic:/Coq/Init/Logic/eq_ind.con" or
787          uri_str = "cic:/Coq/Init/Logic/eq_ind_r.con" then 
788         let subproofs,arg = 
789           (match 
790              build_subproofs_and_args 
791                seed ~ids_to_inner_types ~ids_to_inner_sorts [List.nth args 3]
792            with 
793              l,[p] -> l,p
794            | _,_ -> assert false) in 
795         let method_args =
796           let rec ma_aux n = function
797               [] -> []
798             | a::tl -> 
799                 let hd = 
800                   if n = 0 then arg
801                   else 
802                     let aid = get_id a in
803                     let asort = (try (Hashtbl.find ids_to_inner_sorts aid)
804                       with Not_found -> "Type") in
805                     if asort = "Prop" then
806                       K.ArgProof (aux a)
807                     else K.Term a in
808                 hd::(ma_aux (n-1) tl) in
809           (ma_aux 3 args) in 
810           { K.proof_name = name;
811             K.proof_id  = gen_id proof_prefix seed;
812             K.proof_context = []; 
813             K.proof_apply_context = serialize seed subproofs;
814             K.proof_conclude = 
815               { K.conclude_id = gen_id conclude_prefix seed; 
816                 K.conclude_aref = id;
817                 K.conclude_method = "Rewrite";
818                 K.conclude_args = 
819                   K.Term (C.AConst (sid,uri,exp_named_subst))::method_args;
820                 K.conclude_conclusion = 
821                    try Some 
822                      (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
823                    with Not_found -> None
824               }
825           } 
826       else raise NotApplicable
827   | _ -> raise NotApplicable
828 ;; 
829
830 let map_conjectures
831  seed ~ids_to_inner_sorts ~ids_to_inner_types (id,n,context,ty)
832 =
833  let module K = Content in
834  let context' =
835   List.map
836    (function
837        (id,None) as item -> item
838      | (id,Some (name,Cic.ADecl t)) ->
839          id,
840           Some
841            (* We should call build_decl_item, but we have not computed *)
842            (* the inner-types ==> we always produce a declaration      *)
843            (`Declaration
844              { K.dec_name = name_of name;
845                K.dec_id = gen_id declaration_prefix seed; 
846                K.dec_inductive = false;
847                K.dec_aref = get_id t;
848                K.dec_type = t
849              })
850      | (id,Some (name,Cic.ADef t)) ->
851          id,
852           Some
853            (* We should call build_def_item, but we have not computed *)
854            (* the inner-types ==> we always produce a declaration     *)
855            (`Definition
856               { K.def_name = name_of name;
857                 K.def_id = gen_id definition_prefix seed; 
858                 K.def_aref = get_id t;
859                 K.def_term = t
860               })
861    ) context
862  in
863   (id,n,context',ty)
864 ;;
865
866 let rec annobj2content ~ids_to_inner_sorts ~ids_to_inner_types = 
867   let module C = Cic in
868   let module K = Content in
869   let module C2A = Cic2acic in
870   let seed = ref 0 in
871   function
872       C.ACurrentProof (_,_,n,conjectures,bo,ty,params) ->
873         (gen_id object_prefix seed, params,
874           Some
875            (List.map
876              (map_conjectures seed ~ids_to_inner_sorts ~ids_to_inner_types)
877              conjectures),
878           `Def (K.Const,ty,
879             build_def_item seed (get_id bo) (C.Name n) bo 
880              ~ids_to_inner_sorts ~ids_to_inner_types))
881     | C.AConstant (_,_,n,Some bo,ty,params) ->
882          (gen_id object_prefix seed, params, None,
883            `Def (K.Const,ty,
884              build_def_item seed (get_id bo) (C.Name n) bo 
885                ~ids_to_inner_sorts ~ids_to_inner_types))
886     | C.AConstant (id,_,n,None,ty,params) ->
887          (gen_id object_prefix seed, params, None,
888            `Decl (K.Const,
889              build_decl_item seed id (C.Name n) ty 
890                ~ids_to_inner_sorts))
891     | C.AVariable (_,n,Some bo,ty,params) ->
892          (gen_id object_prefix seed, params, None,
893            `Def (K.Var,ty,
894              build_def_item seed (get_id bo) (C.Name n) bo
895                ~ids_to_inner_sorts ~ids_to_inner_types))
896     | C.AVariable (id,n,None,ty,params) ->
897          (gen_id object_prefix seed, params, None,
898            `Decl (K.Var,
899              build_decl_item seed id (C.Name n) ty
900               ~ids_to_inner_sorts))
901     | C.AInductiveDefinition (id,l,params,nparams) ->
902          (gen_id object_prefix seed, params, None,
903             `Joint
904               { K.joint_id = gen_id joint_prefix seed;
905                 K.joint_kind = `Inductive nparams;
906                 K.joint_defs = List.map (build_inductive seed) l
907               }) 
908
909 and
910     build_inductive seed = 
911      let module K = Content in
912       fun (_,n,b,ty,l) ->
913         `Inductive
914           { K.inductive_id = gen_id inductive_prefix seed;
915             K.inductive_kind = b;
916             K.inductive_type = ty;
917             K.inductive_constructors = build_constructors seed l
918            }
919
920 and 
921     build_constructors seed l =
922      let module K = Content in
923       List.map 
924        (fun (n,t) ->
925            { K.dec_name = Some n;
926              K.dec_id = gen_id declaration_prefix seed;
927              K.dec_inductive = false;
928              K.dec_aref = "";
929              K.dec_type = t
930            }) l
931 ;;
932    
933 (* 
934 and 'term cinductiveType = 
935  id * string * bool * 'term *                (* typename, inductive, arity *)
936    'term cconstructor list                   (*  constructors        *)
937
938 and 'term cconstructor =
939  string * 'term    
940 *)
941
942