1 (* Copyright (C) 2000, HELM Team.
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.
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.
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.
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,
22 * For details, see the HELM World-Wide-Web page,
23 * http://cs.unibo.it/helm/.
26 (**************************************************************************)
30 (* Andrea Asperti <asperti@cs.unibo.it> *)
33 (**************************************************************************)
37 let object_prefix = "obj:";;
38 let declaration_prefix = "decl:";;
39 let definition_prefix = "def:";;
40 let inductive_prefix = "ind:";;
41 let joint_prefix = "joint:";;
42 let proof_prefix = "proof:";;
43 let conclude_prefix = "concl:";;
44 let premise_prefix = "prem:";;
45 let lemma_prefix = "lemma:";;
47 let hide_coercions = ref true;;
49 (* e se mettessi la conversione di BY nell'apply_context ? *)
50 (* sarebbe carino avere l'invariante che la proof2pres
51 generasse sempre prove con contesto vuoto *)
53 let gen_id prefix seed =
54 let res = prefix ^ string_of_int !seed in
59 let name_of = function
61 | Cic.Name b -> Some b;;
63 exception Not_a_proof;;
64 exception NotImplemented;;
65 exception NotApplicable;;
67 (* we do not care for positivity, here, that in any case is enforced by
68 well typing. Just a brutal search *)
77 | C.Implicit _ -> assert false
78 | C.Prod (_,s,t) -> (occur uri s) or (occur uri t)
79 | C.Cast (te,ty) -> (occur uri te)
80 | C.Lambda (_,s,t) -> (occur uri s) or (occur uri t) (* or false ?? *)
81 | C.LetIn (_,s,ty,t) -> (occur uri s) or (occur uri ty) or (occur uri t)
86 else (occur uri a)) false l
87 | C.Const (_,_) -> false
88 | C.MutInd (uri1,_,_) -> if uri = uri1 then true else false
89 | C.MutConstruct (_,_,_,_) -> false
90 | C.MutCase _ -> false (* presuming too much?? *)
91 | C.Fix _ -> false (* presuming too much?? *)
92 | C.CoFix (_,_) -> false (* presuming too much?? *)
98 C.ARel (id,_,_,_) -> id
99 | C.AVar (id,_,_) -> id
100 | C.AMeta (id,_,_) -> id
101 | C.ASort (id,_) -> id
102 | C.AImplicit _ -> raise NotImplemented
103 | C.AProd (id,_,_,_) -> id
104 | C.ACast (id,_,_) -> id
105 | C.ALambda (id,_,_,_) -> id
106 | C.ALetIn (id,_,_,_,_) -> id
107 | C.AAppl (id,_) -> id
108 | C.AConst (id,_,_) -> id
109 | C.AMutInd (id,_,_,_) -> id
110 | C.AMutConstruct (id,_,_,_,_) -> id
111 | C.AMutCase (id,_,_,_,_,_) -> id
112 | C.AFix (id,_,_) -> id
113 | C.ACoFix (id,_,_) -> id
116 let test_for_lifting ~ids_to_inner_types ~ids_to_inner_sorts=
117 let module C = Cic in
118 let module C2A = Cic2acic in
119 (* atomic terms are never lifted, according to my policy *)
123 ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
125 with Not_found -> false)
128 ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
130 with Not_found -> false)
131 | C.AMeta (id,_,_) ->
133 Hashtbl.find ids_to_inner_sorts id = `Prop
134 with Not_found -> assert false)
135 | C.ASort (id,_) -> false
136 | C.AImplicit _ -> raise NotImplemented
137 | C.AProd (id,_,_,_) -> false
138 | C.ACast (id,_,_) ->
140 ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
142 with Not_found -> false)
143 | C.ALambda (id,_,_,_) ->
145 ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
147 with Not_found -> false)
148 | C.ALetIn (id,_,_,_,_) ->
150 ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
152 with Not_found -> false)
155 ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
157 with Not_found -> false)
158 | C.AConst (id,_,_) ->
160 ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
162 with Not_found -> false)
163 | C.AMutInd (id,_,_,_) -> false
164 | C.AMutConstruct (id,_,_,_,_) ->
166 ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
168 with Not_found -> false)
170 | C.AMutCase (id,_,_,_,_,_) ->
172 ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
174 with Not_found -> false)
177 ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
179 with Not_found -> false)
180 | C.ACoFix (id,_,_) ->
182 ignore (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized;
184 with Not_found -> false)
187 (* transform a proof p into a proof list, concatenating the last
188 conclude element to the apply_context list, in case context is
189 empty. Otherwise, it just returns [p] *)
192 let module K = Content in
193 if (p.K.proof_context = []) then
194 if p.K.proof_apply_context = [] then [p]
198 K.proof_context = [];
199 K.proof_apply_context = []
201 p.K.proof_apply_context@[p1]
206 let rec serialize seed =
209 | a::l -> (flat seed a)@(serialize seed l)
212 (* top_down = true if the term is a LAMBDA or a decl *)
213 let generate_conversion seed top_down id inner_proof ~ids_to_inner_types =
214 let module C2A = Cic2acic in
215 let module K = Content in
216 let exp = (try ((Hashtbl.find ids_to_inner_types id).C2A.annexpected)
217 with Not_found -> None)
222 if inner_proof.K.proof_conclude.K.conclude_method = "Intros+LetTac" then
223 { K.proof_name = inner_proof.K.proof_name;
224 K.proof_id = gen_id proof_prefix seed;
225 K.proof_context = [] ;
226 K.proof_apply_context = [];
228 { K.conclude_id = gen_id conclude_prefix seed;
229 K.conclude_aref = id;
230 K.conclude_method = "TD_Conversion";
232 [K.ArgProof {inner_proof with K.proof_name = None}];
233 K.conclude_conclusion = Some expty
237 { K.proof_name = inner_proof.K.proof_name;
238 K.proof_id = gen_id proof_prefix seed;
239 K.proof_context = [] ;
240 K.proof_apply_context = [{inner_proof with K.proof_name = None}];
242 { K.conclude_id = gen_id conclude_prefix seed;
243 K.conclude_aref = id;
244 K.conclude_method = "BU_Conversion";
247 { K.premise_id = gen_id premise_prefix seed;
248 K.premise_xref = inner_proof.K.proof_id;
249 K.premise_binder = None;
253 K.conclude_conclusion = Some expty
258 let generate_exact seed t id name ~ids_to_inner_types =
259 let module C2A = Cic2acic in
260 let module K = Content in
261 { K.proof_name = name;
262 K.proof_id = gen_id proof_prefix seed ;
263 K.proof_context = [] ;
264 K.proof_apply_context = [];
266 { K.conclude_id = gen_id conclude_prefix seed;
267 K.conclude_aref = id;
268 K.conclude_method = "Exact";
269 K.conclude_args = [K.Term (false, t)];
270 K.conclude_conclusion =
271 try Some (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
272 with Not_found -> None
277 let generate_intros_let_tac seed id n s ty inner_proof name ~ids_to_inner_types =
278 let module C2A = Cic2acic in
279 let module C = Cic in
280 let module K = Content in
281 { K.proof_name = name;
282 K.proof_id = gen_id proof_prefix seed ;
283 K.proof_context = [] ;
284 K.proof_apply_context = [];
286 { K.conclude_id = gen_id conclude_prefix seed;
287 K.conclude_aref = id;
288 K.conclude_method = "Intros+LetTac";
289 K.conclude_args = [K.ArgProof inner_proof];
290 K.conclude_conclusion =
292 (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
294 (match inner_proof.K.proof_conclude.K.conclude_conclusion with
298 None -> Some (C.AProd ("gen"^id,n,s,t))
299 | Some ty -> Some (C.ALetIn ("gen"^id,n,s,ty,t)))
304 let build_decl_item seed id n s ~ids_to_inner_sorts =
305 let module K = Content in
308 Some (Hashtbl.find ids_to_inner_sorts (Cic2acic.source_id_of_id id))
309 with Not_found -> None
314 { K.dec_name = name_of n;
315 K.dec_id = gen_id declaration_prefix seed;
316 K.dec_inductive = false;
322 { K.dec_name = name_of n;
323 K.dec_id = gen_id declaration_prefix seed;
324 K.dec_inductive = false;
330 let infer_dependent ~headless context metasenv = function
335 List.map (function s -> false,s) l
339 CicTypeChecker.type_of_aux'
340 metasenv context (Deannotate.deannotate_term he)
341 CicUniv.oblivion_ugraph
344 match CicReduction.whd context t with
345 | Cic.Prod _ -> false
348 let rec dummify_last_tgt t =
349 match CicReduction.whd context t with
350 | Cic.Prod (n,s,tgt) -> Cic.Prod(n,s, dummify_last_tgt tgt)
351 | _ -> Cic.Implicit None
353 let rec aux ty = function
357 FreshNamesGenerator.clean_dummy_dependent_types
358 (dummify_last_tgt ty)
360 | Cic.Prod (n,src,tgt) ->
361 (n <> Cic.Anonymous && fstorder src, t) ::
362 aux (CicSubstitution.subst
363 (Deannotate.deannotate_term t) tgt) tl
364 | _ -> List.map (fun s -> false,s) (t::tl)
366 (false, he) :: aux hety tl
367 with CicTypeChecker.TypeCheckerFailure _ -> assert false
370 let rec build_subproofs_and_args ?(headless=false) seed context metasenv l ~ids_to_inner_types ~ids_to_inner_sorts =
371 let module C = Cic in
372 let module K = Content in
378 test_for_lifting t ~ids_to_inner_types ~ids_to_inner_sorts in
379 let subproofs,args = aux (n + if need_lifting then 1 else 0) l1 in
383 seed context metasenv
384 ~name:("H" ^ string_of_int n) ~ids_to_inner_types
385 ~ids_to_inner_sorts t in
388 { K.premise_id = gen_id premise_prefix seed;
389 K.premise_xref = new_subproof.K.proof_id;
390 K.premise_binder = new_subproof.K.proof_name;
393 new_subproof::subproofs,new_arg::args
397 C.ARel (idr,idref,n,b) ->
400 Hashtbl.find ids_to_inner_sorts idr
401 with Not_found -> `Type (CicUniv.fresh())) in
404 { K.premise_id = gen_id premise_prefix seed;
405 K.premise_xref = idr;
406 K.premise_binder = Some b;
409 else (K.Term (dep,t))
410 | C.AConst(id,uri,[]) ->
413 Hashtbl.find ids_to_inner_sorts id
414 with Not_found -> `Type (CicUniv.fresh())) in
417 { K.lemma_id = gen_id lemma_prefix seed;
418 K.lemma_name = UriManager.name_of_uri uri;
419 K.lemma_uri = UriManager.string_of_uri uri
421 else (K.Term (dep,t))
422 | C.AMutConstruct(id,uri,tyno,consno,[]) ->
425 Hashtbl.find ids_to_inner_sorts id
426 with Not_found -> `Type (CicUniv.fresh())) in
428 let inductive_types =
430 CicEnvironment.get_obj CicUniv.oblivion_ugraph uri
433 | Cic.InductiveDefinition (l,_,_,_) -> l
436 let (_,_,_,constructors) =
437 List.nth inductive_types tyno in
438 let name,_ = List.nth constructors (consno - 1) in
440 { K.lemma_id = gen_id lemma_prefix seed;
443 UriManager.string_of_uri uri ^ "#xpointer(1/" ^
444 string_of_int (tyno+1) ^ "/" ^ string_of_int consno ^
447 else (K.Term (dep,t))
448 | _ -> (K.Term (dep,t))) in
451 match (aux 1 (infer_dependent ~headless context metasenv l)) with
453 [{p with K.proof_name = None}],
456 K.Premise prem when prem.K.premise_xref = p.K.proof_id ->
457 K.Premise {prem with K.premise_binder = None}
463 build_def_item seed context metasenv id n t ty ~ids_to_inner_sorts ~ids_to_inner_types =
464 let module K = Content in
466 let sort = Hashtbl.find ids_to_inner_sorts id in
469 (acic2content seed context metasenv ?name:(name_of n) ~ids_to_inner_sorts ~ids_to_inner_types t)
474 { K.def_name = name_of n;
475 K.def_id = gen_id definition_prefix seed;
481 Not_found -> assert false
483 (* the following function must be called with an object of sort
484 Prop. For debugging purposes this is tested again, possibly raising an
485 Not_a_proof exception *)
487 and acic2content seed context metasenv ?name ~ids_to_inner_sorts ~ids_to_inner_types t =
488 let rec aux ?name context t =
489 let module C = Cic in
490 let module K = Content in
491 let module C2A = Cic2acic in
494 C.ARel (id,idref,n,b) as t ->
495 let sort = Hashtbl.find ids_to_inner_sorts id in
497 generate_exact seed t id name ~ids_to_inner_types
498 else raise Not_a_proof
499 | C.AVar (id,uri,exp_named_subst) as t ->
500 let sort = Hashtbl.find ids_to_inner_sorts id in
502 generate_exact seed t id name ~ids_to_inner_types
503 else raise Not_a_proof
504 | C.AMeta (id,n,l) as t ->
505 let sort = Hashtbl.find ids_to_inner_sorts id in
507 generate_exact seed t id name ~ids_to_inner_types
508 else raise Not_a_proof
509 | C.ASort (id,s) -> raise Not_a_proof
510 | C.AImplicit _ -> raise NotImplemented
511 | C.AProd (_,_,_,_) -> raise Not_a_proof
512 | C.ACast (id,v,t) -> aux context v
513 | C.ALambda (id,n,s,t) ->
514 let sort = Hashtbl.find ids_to_inner_sorts id in
517 aux ((Some (n,Cic.Decl (Deannotate.deannotate_term s)))::context) t
520 if proof.K.proof_conclude.K.conclude_method = "Intros+LetTac" then
521 match proof.K.proof_conclude.K.conclude_args with
529 (build_decl_item seed id n s ids_to_inner_sorts)::
530 proof'.K.proof_context
533 generate_intros_let_tac seed id n s None proof'' name ~ids_to_inner_types
536 | C.ALetIn (id,n,s,ty,t) ->
537 let sort = Hashtbl.find ids_to_inner_sorts id in
542 Cic.Def (Deannotate.deannotate_term s,Deannotate.deannotate_term ty)))::context) t
545 if proof.K.proof_conclude.K.conclude_method = "Intros+LetTac" then
546 match proof.K.proof_conclude.K.conclude_args with
554 ((build_def_item seed context metasenv (get_id s) n s ty ids_to_inner_sorts
555 ids_to_inner_types):> Cic.annterm K.in_proof_context_element)
556 ::proof'.K.proof_context;
559 generate_intros_let_tac seed id n s (Some ty) proof'' name ~ids_to_inner_types
564 seed context metasenv id li ~ids_to_inner_types ~ids_to_inner_sorts
565 with NotApplicable ->
567 seed context metasenv name id li ~ids_to_inner_types ~ids_to_inner_sorts
568 with NotApplicable ->
570 seed context metasenv name id li ~ids_to_inner_types ~ids_to_inner_sorts
571 with NotApplicable ->
573 seed context metasenv name id li ~ids_to_inner_types ~ids_to_inner_sorts
574 with NotApplicable ->
575 let subproofs, args =
576 build_subproofs_and_args
577 seed context metasenv li ~ids_to_inner_types ~ids_to_inner_sorts in
580 List.filter (test_for_lifting ~ids_to_inner_types) li in
582 match args_to_lift with
583 [_] -> List.map aux args_to_lift
584 | _ -> List.map (aux ~name:"H") args_to_lift in
585 let args = build_args seed li subproofs
586 ~ids_to_inner_types ~ids_to_inner_sorts in *)
587 { K.proof_name = name;
588 K.proof_id = gen_id proof_prefix seed;
589 K.proof_context = [];
590 K.proof_apply_context = serialize seed subproofs;
592 { K.conclude_id = gen_id conclude_prefix seed;
593 K.conclude_aref = id;
594 K.conclude_method = "Apply";
595 K.conclude_args = args;
596 K.conclude_conclusion =
598 (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
599 with Not_found -> None
602 | C.AConst (id,uri,exp_named_subst) as t ->
603 let sort = Hashtbl.find ids_to_inner_sorts id in
605 generate_exact seed t id name ~ids_to_inner_types
606 else raise Not_a_proof
607 | C.AMutInd (id,uri,i,exp_named_subst) -> raise Not_a_proof
608 | C.AMutConstruct (id,uri,i,j,exp_named_subst) as t ->
609 let sort = Hashtbl.find ids_to_inner_sorts id in
611 generate_exact seed t id name ~ids_to_inner_types
612 else raise Not_a_proof
613 | C.AMutCase (id,uri,typeno,ty,te,patterns) ->
614 let inductive_types,noparams =
615 (let o, _ = CicEnvironment.get_obj CicUniv.oblivion_ugraph uri in
617 Cic.Constant _ -> assert false
618 | Cic.Variable _ -> assert false
619 | Cic.CurrentProof _ -> assert false
620 | Cic.InductiveDefinition (l,_,n,_) -> l,n
622 let (_,_,_,constructors) = List.nth inductive_types typeno in
623 let name_and_arities =
624 let rec count_prods =
626 C.Prod (_,_,t) -> 1 + count_prods t
629 (function (n,t) -> Some n,((count_prods t) - noparams)) constructors in
631 let build_proof p (name,arity) =
632 let rec make_context_and_body c p n =
633 if n = 0 then c,(aux context p)
636 Cic.ALambda(idl,vname,s1,t1) ->
639 seed idl vname s1 ~ids_to_inner_sorts in
640 make_context_and_body (ce::c) t1 (n-1)
641 | _ -> assert false) in
642 let context,body = make_context_and_body [] p arity in
644 {body with K.proof_name = name; K.proof_context=context} in
645 List.map2 build_proof patterns name_and_arities in
648 build_subproofs_and_args ~headless:true
649 seed context metasenv ~ids_to_inner_types ~ids_to_inner_sorts [te]
652 | _ -> assert false) in
653 { K.proof_name = name;
654 K.proof_id = gen_id proof_prefix seed;
655 K.proof_context = [];
656 K.proof_apply_context = serialize seed context;
658 { K.conclude_id = gen_id conclude_prefix seed;
659 K.conclude_aref = id;
660 K.conclude_method = "Case";
662 (K.Aux (UriManager.string_of_uri uri))::
663 (K.Aux (string_of_int typeno))::(K.Term (false,ty))::term::pp;
664 K.conclude_conclusion =
666 (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
667 with Not_found -> None
670 | C.AFix (id, no, funs) ->
673 (fun ctx (_,n,_,ty,_) ->
674 let ty = Deannotate.deannotate_term ty in
675 Some (Cic.Name n,Cic.Decl ty) :: ctx)
680 (function (_,name,_,_,bo) -> `Proof (aux context' ~name bo)) funs in
682 List.nth (List.map (fun (_,name,_,_,_) -> name) funs) no
684 let decreasing_args =
685 List.map (function (_,_,n,_,_) -> n) funs in
687 { K.joint_id = gen_id joint_prefix seed;
688 K.joint_kind = `Recursive decreasing_args;
689 K.joint_defs = proofs
692 { K.proof_name = name;
693 K.proof_id = gen_id proof_prefix seed;
694 K.proof_context = [`Joint jo];
695 K.proof_apply_context = [];
697 { K.conclude_id = gen_id conclude_prefix seed;
698 K.conclude_aref = id;
699 K.conclude_method = "Exact";
702 { K.premise_id = gen_id premise_prefix seed;
703 K.premise_xref = jo.K.joint_id;
704 K.premise_binder = Some fun_name;
705 K.premise_n = Some no;
708 K.conclude_conclusion =
710 (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
711 with Not_found -> None
714 | C.ACoFix (id,no,funs) ->
717 (fun ctx (_,n,ty,_) ->
718 let ty = Deannotate.deannotate_term ty in
719 Some (Cic.Name n,Cic.Decl ty) :: ctx)
724 (function (_,name,_,bo) -> `Proof (aux context' ~name bo)) funs in
726 { K.joint_id = gen_id joint_prefix seed;
727 K.joint_kind = `CoRecursive;
728 K.joint_defs = proofs
731 { K.proof_name = name;
732 K.proof_id = gen_id proof_prefix seed;
733 K.proof_context = [`Joint jo];
734 K.proof_apply_context = [];
736 { K.conclude_id = gen_id conclude_prefix seed;
737 K.conclude_aref = id;
738 K.conclude_method = "Exact";
741 { K.premise_id = gen_id premise_prefix seed;
742 K.premise_xref = jo.K.joint_id;
743 K.premise_binder = Some "tiralo fuori";
744 K.premise_n = Some no;
747 K.conclude_conclusion =
749 (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
750 with Not_found -> None
755 generate_conversion seed false id t1 ~ids_to_inner_types
756 in aux ?name context t
758 and inductive seed context metasenv name id li ~ids_to_inner_types ~ids_to_inner_sorts =
759 let aux context ?name =
760 acic2content seed context metasenv ~ids_to_inner_types ~ids_to_inner_sorts
762 let module C2A = Cic2acic in
763 let module K = Content in
764 let module C = Cic in
766 C.AConst (idc,uri,exp_named_subst)::args ->
767 let uri_str = UriManager.string_of_uri uri in
768 let suffix = Str.regexp_string "_ind.con" in
769 let len = String.length uri_str in
770 let n = (try (Str.search_backward suffix uri_str len)
771 with Not_found -> -1) in
772 if n<0 then raise NotApplicable
775 if UriManager.eq uri HelmLibraryObjects.Logic.ex_ind_URI then "Exists"
776 else if UriManager.eq uri HelmLibraryObjects.Logic.and_ind_URI then "AndInd"
777 else if UriManager.eq uri HelmLibraryObjects.Logic.false_ind_URI then "FalseInd"
778 else "ByInduction" in
779 let prefix = String.sub uri_str 0 n in
780 let ind_str = (prefix ^ ".ind") in
781 let ind_uri = UriManager.uri_of_string ind_str in
782 let inductive_types,noparams =
783 (let o,_ = CicEnvironment.get_obj CicUniv.oblivion_ugraph ind_uri in
785 | Cic.InductiveDefinition (l,_,n,_) -> (l,n)
789 if n = 0 then ([],l) else
790 let p,a = split (n-1) (List.tl l) in
791 ((List.hd l::p),a) in
792 let params_and_IP,tail_args = split (noparams+1) args in
794 (match inductive_types with
796 | _ -> raise NotApplicable) (* don't care for mutual ind *) in
798 let rec clean_up n t =
801 (label,Cic.Prod (_,_,t)) -> clean_up (n-1) (label,t)
802 | _ -> assert false) in
803 List.map (clean_up noparams) constructors in
804 let no_constructors= List.length constructors in
805 let args_for_cases, other_args =
806 split no_constructors tail_args in
807 let subproofs,other_method_args =
808 build_subproofs_and_args ~headless:true seed context metasenv
809 other_args ~ids_to_inner_types ~ids_to_inner_sorts in
811 let rec build_method_args =
813 [],_-> [] (* extra args are ignored ???? *)
814 | (name,ty)::tlc,arg::tla ->
815 let idarg = get_id arg in
817 (try (Hashtbl.find ids_to_inner_sorts idarg)
818 with Not_found -> `Type (CicUniv.fresh())) in
820 if sortarg = `Prop then
824 Cic.Prod (_,s,t),Cic.ALambda(idl,n,s1,t1) ->
826 Some (n,Cic.Decl(Deannotate.deannotate_term s1))
831 seed idl n s1 ~ids_to_inner_sorts in
832 if (occur ind_uri s) then
834 Cic.ALambda(id2,n2,s2,t2) ->
838 (Deannotate.deannotate_term s2))
843 { K.dec_name = name_of n2;
845 gen_id declaration_prefix seed;
846 K.dec_inductive = true;
850 let (context,body) = bc context'' (t,t2) in
851 (ce::inductive_hyp::context,body)
855 let (context,body) = bc context' (t,t1) in
857 | _ , t -> ([],aux context t) in
858 bc context (ty,arg) in
861 K.proof_name = Some name;
862 K.proof_context = co;
864 else (K.Term (false,arg)) in
865 hdarg::(build_method_args (tlc,tla))
866 | _ -> assert false in
867 build_method_args (constructors1,args_for_cases) in
868 { K.proof_name = name;
869 K.proof_id = gen_id proof_prefix seed;
870 K.proof_context = [];
871 K.proof_apply_context = serialize seed subproofs;
873 { K.conclude_id = gen_id conclude_prefix seed;
874 K.conclude_aref = id;
875 K.conclude_method = method_name;
877 K.Aux (string_of_int no_constructors)
878 ::K.Term (false,(C.AAppl(id,((C.AConst(idc,uri,exp_named_subst))::params_and_IP))))
879 ::method_args@other_method_args;
880 K.conclude_conclusion =
882 (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
883 with Not_found -> None
886 | _ -> raise NotApplicable
888 and coercion seed context metasenv id li ~ids_to_inner_types ~ids_to_inner_sorts =
890 | ((Cic.AConst _) as he)::tl
891 | ((Cic.AMutInd _) as he)::tl
892 | ((Cic.AMutConstruct _) as he)::tl when
893 (match CoercDb.is_a_coercion (Deannotate.deannotate_term he) with
894 | None -> false | Some (_,_,_,_,cpos) -> cpos < List.length tl)
895 && !hide_coercions ->
897 match CoercDb.is_a_coercion (Deannotate.deannotate_term he) with
898 | None -> assert false
899 | Some (_,_,_,sats,cpos) -> cpos, sats
901 let x = List.nth tl cpos in
903 try HExtlib.split_nth (cpos + sats +1) tl with Failure _ -> [],[]
907 seed context metasenv ~ids_to_inner_types ~ids_to_inner_sorts
911 seed context metasenv ~ids_to_inner_types ~ids_to_inner_sorts
912 (Cic.AAppl (id,x::rest))
913 | _ -> raise NotApplicable
915 and rewrite seed context metasenv name id li ~ids_to_inner_types ~ids_to_inner_sorts =
916 let aux context ?name =
917 acic2content seed context metasenv ~ids_to_inner_types ~ids_to_inner_sorts
919 let module C2A = Cic2acic in
920 let module K = Content in
921 let module C = Cic in
923 C.AConst (sid,uri,exp_named_subst)::args ->
924 if UriManager.eq uri HelmLibraryObjects.Logic.eq_ind_URI or
925 UriManager.eq uri HelmLibraryObjects.Logic.eq_ind_r_URI or
926 LibraryObjects.is_eq_ind_URI uri or
927 LibraryObjects.is_eq_ind_r_URI uri then
930 build_subproofs_and_args
931 seed context metasenv
932 ~ids_to_inner_types ~ids_to_inner_sorts [List.nth args 3]
935 | _,_ -> assert false) in
937 let rec ma_aux n = function
943 let aid = get_id a in
944 let asort = (try (Hashtbl.find ids_to_inner_sorts aid)
945 with Not_found -> `Type (CicUniv.fresh())) in
946 if asort = `Prop then
947 K.ArgProof (aux context a)
948 else K.Term (false,a) in
949 hd::(ma_aux (n-1) tl) in
951 { K.proof_name = name;
952 K.proof_id = gen_id proof_prefix seed;
953 K.proof_context = [];
954 K.proof_apply_context = serialize seed subproofs;
956 { K.conclude_id = gen_id conclude_prefix seed;
957 K.conclude_aref = id;
959 if UriManager.eq uri HelmLibraryObjects.Logic.eq_ind_URI
960 || LibraryObjects.is_eq_ind_URI uri then
965 K.Term (false,(C.AConst (sid,uri,exp_named_subst)))::method_args;
966 K.conclude_conclusion =
968 (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
969 with Not_found -> None
972 else raise NotApplicable
973 | _ -> raise NotApplicable
976 seed context metasenv name id li ~ids_to_inner_types ~ids_to_inner_sorts
978 let module C2A = Cic2acic in
979 let module K = Content in
980 let module C = Cic in
982 | C.AConst (sid,uri,exp_named_subst)::args
983 when LibraryObjects.is_trans_eq_URI uri ->
984 let exp_args = List.map snd exp_named_subst in
986 match exp_args@args with
987 | [_;t1;t2;t3;p1;p2] -> t1,t2,t3,p1,p2
988 | _ -> raise NotApplicable
990 { K.proof_name = name;
991 K.proof_id = gen_id proof_prefix seed;
992 K.proof_context = [];
993 K.proof_apply_context = [];
995 { K.conclude_id = gen_id conclude_prefix seed;
996 K.conclude_aref = id;
997 K.conclude_method = "Eq_chain";
1001 seed context metasenv ~ids_to_inner_types ~ids_to_inner_sorts p1)
1002 @ [K.Term (false,t2)]@
1004 seed context metasenv ~ids_to_inner_types ~ids_to_inner_sorts p2)
1005 @ [K.Term (false,t3)];
1006 K.conclude_conclusion =
1008 (Hashtbl.find ids_to_inner_types id).C2A.annsynthesized
1009 with Not_found -> None
1012 | _ -> raise NotApplicable
1014 and transitivity_aux seed context metasenv ~ids_to_inner_types ~ids_to_inner_sorts t =
1015 let module C2A = Cic2acic in
1016 let module K = Content in
1017 let module C = Cic in
1019 | C.AAppl (_,C.AConst (sid,uri,exp_named_subst)::args)
1020 when LibraryObjects.is_trans_eq_URI uri ->
1021 let exp_args = List.map snd exp_named_subst in
1022 let t1,t2,t3,p1,p2 =
1023 match exp_args@args with
1024 | [_;t1;t2;t3;p1;p2] -> t1,t2,t3,p1,p2
1025 | _ -> raise NotApplicable
1028 seed context metasenv ~ids_to_inner_types ~ids_to_inner_sorts p1)
1029 @[K.Term (false,t2)]
1031 seed context metasenv ~ids_to_inner_types ~ids_to_inner_sorts p2)
1033 (acic2content seed context metasenv ~ids_to_inner_sorts ~ids_to_inner_types t)]
1039 seed ~ids_to_inner_sorts ~ids_to_inner_types (id,n,context,ty)
1041 let module K = Content in
1046 | (id,Some (name,Cic.ADecl t)) ->
1048 (* We should call build_decl_item, but we have not computed *)
1049 (* the inner-types ==> we always produce a declaration *)
1051 { K.dec_name = name_of name;
1052 K.dec_id = gen_id declaration_prefix seed;
1053 K.dec_inductive = false;
1054 K.dec_aref = get_id t;
1057 | (id,Some (name,Cic.ADef (t,ty))) ->
1059 (* We should call build_def_item, but we have not computed *)
1060 (* the inner-types ==> we always produce a declaration *)
1062 { K.def_name = name_of name;
1063 K.def_id = gen_id definition_prefix seed;
1064 K.def_aref = get_id t;
1073 (* map_sequent is similar to map_conjectures, but the for the hid
1074 of the hypothesis, which are preserved instead of generating
1075 fresh ones. We shall have to adopt a uniform policy, soon or later *)
1077 let map_sequent ((id,n,context,ty):Cic.annconjecture) =
1078 let module K = Content in
1083 | (id,Some (name,Cic.ADecl t)) ->
1085 (* We should call build_decl_item, but we have not computed *)
1086 (* the inner-types ==> we always produce a declaration *)
1088 { K.dec_name = name_of name;
1090 K.dec_inductive = false;
1091 K.dec_aref = get_id t;
1094 | (id,Some (name,Cic.ADef (t,ty))) ->
1096 (* We should call build_def_item, but we have not computed *)
1097 (* the inner-types ==> we always produce a declaration *)
1099 { K.def_name = name_of name;
1101 K.def_aref = get_id t;
1110 let rec annobj2content ~ids_to_inner_sorts ~ids_to_inner_types =
1111 let module C = Cic in
1112 let module K = Content in
1113 let module C2A = Cic2acic in
1116 C.ACurrentProof (_,_,n,conjectures,bo,ty,params,_) ->
1117 (gen_id object_prefix seed, params,
1120 (map_conjectures seed ~ids_to_inner_sorts ~ids_to_inner_types)
1124 seed [] (Deannotate.deannotate_conjectures conjectures)
1125 (get_id bo) (C.Name n) bo ty
1126 ~ids_to_inner_sorts ~ids_to_inner_types))
1127 | C.AConstant (_,_,n,Some bo,ty,params,_) ->
1128 (gen_id object_prefix seed, params, None,
1130 build_def_item seed [] [] (get_id bo) (C.Name n) bo ty
1131 ~ids_to_inner_sorts ~ids_to_inner_types))
1132 | C.AConstant (id,_,n,None,ty,params,_) ->
1133 (gen_id object_prefix seed, params, None,
1135 build_decl_item seed id (C.Name n) ty
1136 ~ids_to_inner_sorts))
1137 | C.AVariable (_,n,Some bo,ty,params,_) ->
1138 (gen_id object_prefix seed, params, None,
1140 build_def_item seed [] [] (get_id bo) (C.Name n) bo ty
1141 ~ids_to_inner_sorts ~ids_to_inner_types))
1142 | C.AVariable (id,n,None,ty,params,_) ->
1143 (gen_id object_prefix seed, params, None,
1145 build_decl_item seed id (C.Name n) ty
1146 ~ids_to_inner_sorts))
1147 | C.AInductiveDefinition (id,l,params,nparams,_) ->
1148 (gen_id object_prefix seed, params, None,
1150 { K.joint_id = gen_id joint_prefix seed;
1151 K.joint_kind = `Inductive nparams;
1152 K.joint_defs = List.map (build_inductive seed) l
1156 build_inductive seed =
1157 let module K = Content in
1160 { K.inductive_id = gen_id inductive_prefix seed;
1161 K.inductive_name = n;
1162 K.inductive_kind = b;
1163 K.inductive_type = ty;
1164 K.inductive_constructors = build_constructors seed l
1168 build_constructors seed l =
1169 let module K = Content in
1172 { K.dec_name = Some n;
1173 K.dec_id = gen_id declaration_prefix seed;
1174 K.dec_inductive = false;
1181 and 'term cinductiveType =
1182 id * string * bool * 'term * (* typename, inductive, arity *)
1183 'term cconstructor list (* constructors *)
1185 and 'term cconstructor =