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