123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321(************************************************************************)(* * The Coq Proof Assistant / The Coq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)openUtilopenNamesletmake_dirl=DirPath.make(List.rev_mapId.of_stringl)(************************************************************************)(* Coq reference API *)(************************************************************************)letcoq=Libnames.coq_string(* "Coq" *)letinit_dir=[coq;"Init"]letjmeq_module_name=[coq;"Logic";"JMeq"]letjmeq_library_path=make_dirjmeq_module_nameletjmeq_module=MPfilejmeq_library_pathletfind_referencelocstrdirs=letdp=make_dirdirinletsp=Libnames.make_pathdp(Id.of_strings)inNametab.global_of_pathspletcoq_referencelocstrdirs=find_referencelocstr(coq::dir)slettable:GlobRef.tCString.Map.tref=letname="coqlib_registered"inSummary.ref~nameCString.Map.emptyletget_lib_refs()=CString.Map.bindings!tablelethas_refs=CString.Map.mems!tableletcheck_ind_refsind=matchCString.Map.finds!tablewith|GlobRef.IndRefr->Ind.CanOrd.equalrind|_->false|exceptionNot_found->falseletlib_refs=tryCString.Map.finds!tablewithNot_found->CErrors.user_errPp.(str"not found in table: "++strs)letadd_refsc=table:=CString.Map.addsc!tableletcache_ref(s,c)=add_refsclet(inCoqlibRef:string*GlobRef.t->Libobject.obj)=letopenLibobjectindeclare_object{(default_object"COQLIBREF")withcache_function=cache_ref;load_function=(fun_x->cache_refx);classify_function=(fun_->Substitute);subst_function=ident_subst_function;discharge_function=(funsc->Somesc);}(** Replaces a binding ! *)letregister_refsc=Lib.add_leaf@@inCoqlibRef(s,c)(************************************************************************)(* Generic functions to find Coq objects *)lethas_suffix_in_dirsdirsref=letdir=Libnames.dirpath(Nametab.path_of_globalref)inList.exists(fund->Libnames.is_dirpath_prefix_ofddir)dirsletgen_reference_in_moduleslocstrdirss=letdirs=List.mapmake_dirdirsinletqualid=Libnames.qualid_of_stringsinletall=Nametab.locate_allqualidinletall=List.sort_uniquizeGlobRef.UserOrd.compareallinletthese=List.filter(has_suffix_in_dirsdirs)allinmatchthesewith|[x]->x|[]->CErrors.anomaly~label:locstrPp.(str"cannot find "++strs++str" in module"++str(ifList.lengthdirs>1then"s "else" ")++prlist_with_seppr_commaDirPath.printdirs++str".")|l->CErrors.anomaly~label:locstrPp.(str"ambiguous name "++strs++str" can represent "++prlist_with_seppr_comma(funx->Libnames.pr_path(Nametab.path_of_globalx))l++str" in module"++str(ifList.lengthdirs>1then"s "else" ")++prlist_with_seppr_commaDirPath.printdirs++str".")(* For tactics/commands requiring vernacular libraries *)letcheck_required_libraryd=letdir=make_dirdintrylet_:Declarations.module_body=Global.lookup_module(ModPath.MPfiledir)in()withNot_found->letin_current_dir=matchLib.current_mp()with|MPfiledp->DirPath.equaldirdp|_->falseinifnotin_current_dirthenCErrors.user_errPp.(str"Library "++DirPath.printdir++str" has to be required first.")(************************************************************************)(* Specific Coq objects *)(************************************************************************)letarith_dir=[coq;"Arith"]letarith_modules=[arith_dir]letnumbers_dir=[coq;"Numbers"]letparith_dir=[coq;"PArith"]letnarith_dir=[coq;"NArith"]letzarith_dir=[coq;"ZArith"]letzarith_base_modules=[numbers_dir;parith_dir;narith_dir;zarith_dir]letinit_modules=[init_dir@["Datatypes"];init_dir@["Logic"];init_dir@["Specif"];init_dir@["Logic_Type"];init_dir@["Nat"];init_dir@["Peano"];init_dir@["Wf"]]letlogic_module_name=init_dir@["Logic"]letlogic_module=MPfile(make_dirlogic_module_name)letlogic_type_module_name=init_dir@["Logic_Type"]letlogic_type_module=make_dirlogic_type_module_nameletdatatypes_module_name=init_dir@["Datatypes"]letdatatypes_module=MPfile(make_dirdatatypes_module_name)(** Identity *)letid=Constant.make2datatypes_module@@Label.make"idProp"lettype_of_id=Constant.make2datatypes_module@@Label.make"IDProp"(** Natural numbers *)letnat_kn=MutInd.make2datatypes_module@@Label.make"nat"letnat_path=Libnames.make_path(make_dirdatatypes_module_name)(Id.of_string"nat")letglob_nat=GlobRef.IndRef(nat_kn,0)letpath_of_O=((nat_kn,0),1)letpath_of_S=((nat_kn,0),2)letglob_O=GlobRef.ConstructRefpath_of_Oletglob_S=GlobRef.ConstructRefpath_of_S(** Booleans *)letbool_kn=MutInd.make2datatypes_module@@Label.make"bool"letglob_bool=GlobRef.IndRef(bool_kn,0)letpath_of_true=((bool_kn,0),1)letpath_of_false=((bool_kn,0),2)letglob_true=GlobRef.ConstructRefpath_of_trueletglob_false=GlobRef.ConstructRefpath_of_false(** Equality *)leteq_kn=MutInd.make2logic_module@@Label.make"eq"letglob_eq=GlobRef.IndRef(eq_kn,0)letidentity_kn=MutInd.make2datatypes_module@@Label.make"identity"letglob_identity=GlobRef.IndRef(identity_kn,0)letjmeq_kn=MutInd.make2jmeq_module@@Label.make"JMeq"letglob_jmeq=GlobRef.IndRef(jmeq_kn,0)(* Sigma data *)typecoq_sigma_data={proj1:GlobRef.t;proj2:GlobRef.t;elim:GlobRef.t;intro:GlobRef.t;typ:GlobRef.t}letbuild_sigma_genstr={typ=lib_ref("core."^str^".type");elim=lib_ref("core."^str^".rect");intro=lib_ref("core."^str^".intro");proj1=lib_ref("core."^str^".proj1");proj2=lib_ref("core."^str^".proj2");}letbuild_prod()=build_sigma_gen"prod"letbuild_sigma()=build_sigma_gen"sig"letbuild_sigma_type()=build_sigma_gen"sigT"(* Booleans *)typecoq_bool_data={andb:GlobRef.t;andb_prop:GlobRef.t;andb_true_intro:GlobRef.t}letbuild_bool_type()={andb=lib_ref"core.bool.andb";andb_prop=lib_ref"core.bool.andb_prop";andb_true_intro=lib_ref"core.bool.andb_true_intro";}(* Equalities *)typecoq_eq_data={eq:GlobRef.t;ind:GlobRef.t;refl:GlobRef.t;sym:GlobRef.t;trans:GlobRef.t;congr:GlobRef.t}(* Leibniz equality on Type *)letbuild_eqdata_genstr={eq=lib_ref("core."^str^".type");ind=lib_ref("core."^str^".ind");refl=lib_ref("core."^str^".refl");sym=lib_ref("core."^str^".sym");trans=lib_ref("core."^str^".trans");congr=lib_ref("core."^str^".congr");}letbuild_coq_eq_data()=build_eqdata_gen"eq"letbuild_coq_jmeq_data()=build_eqdata_gen"JMeq"letbuild_coq_identity_data()=build_eqdata_gen"identity"(* Inversion data... *)(* Data needed for discriminate and injection *)typecoq_inversion_data={inv_eq:GlobRef.t;(* : forall params, t -> Prop *)inv_ind:GlobRef.t;(* : forall params P y, eq params y -> P y *)inv_congr:GlobRef.t(* : forall params B (f:t->B) y, eq params y -> f c=f y *)}letbuild_coq_inversion_genlstr=List.itercheck_required_libraryl;{inv_eq=lib_ref("core."^str^".type");inv_ind=lib_ref("core."^str^".ind");inv_congr=lib_ref("core."^str^".congr_canonical");}letbuild_coq_inversion_eq_data()=build_coq_inversion_gen[logic_module_name]"eq"letbuild_coq_inversion_eq_true_data()=build_coq_inversion_gen[logic_module_name]"True"letbuild_coq_inversion_identity_data()=build_coq_inversion_gen[logic_module_name]"identity"(* This needs a special case *)letbuild_coq_inversion_jmeq_data()={inv_eq=lib_ref"core.JMeq.hom";inv_ind=lib_ref"core.JMeq.ind";inv_congr=lib_ref"core.JMeq.congr_canonical";}(* Specif *)letbuild_coq_sumbool()=lib_ref"core.sumbool.type"letbuild_coq_eq()=lib_ref"core.eq.type"letbuild_coq_eq_refl()=lib_ref"core.eq.refl"letbuild_coq_eq_sym()=lib_ref"core.eq.sym"letbuild_coq_f_equal2()=lib_ref"core.eq.congr2"(* Runtime part *)letbuild_coq_True()=lib_ref"core.True.type"letbuild_coq_I()=lib_ref"core.True.I"letbuild_coq_identity()=lib_ref"core.identity.type"letbuild_coq_eq_true()=lib_ref"core.eq_true.type"letbuild_coq_jmeq()=lib_ref"core.JMeq.type"letbuild_coq_prod()=lib_ref"core.prod.type"letbuild_coq_pair()=lib_ref"core.prod.intro"letbuild_coq_False()=lib_ref"core.False.type"letbuild_coq_not()=lib_ref"core.not.type"letbuild_coq_and()=lib_ref"core.and.type"letbuild_coq_conj()=lib_ref"core.and.conj"letbuild_coq_or()=lib_ref"core.or.type"letbuild_coq_ex()=lib_ref"core.ex.type"letbuild_coq_sig()=lib_ref"core.sig.type"letbuild_coq_existT()=lib_ref"core.sigT.existT"letbuild_coq_iff()=lib_ref"core.iff.type"letbuild_coq_iff_left_proj()=lib_ref"core.iff.proj1"letbuild_coq_iff_right_proj()=lib_ref"core.iff.proj2"(* The following is less readable but does not depend on parsing *)letcoq_eq_ref=Lazy.from_funbuild_coq_eqletcoq_identity_ref=Lazy.from_funbuild_coq_identityletcoq_jmeq_ref=Lazy.from_funbuild_coq_jmeqletcoq_eq_true_ref=Lazy.from_funbuild_coq_eq_trueletcoq_existS_ref=Lazy.from_funbuild_coq_existTletcoq_existT_ref=Lazy.from_funbuild_coq_existTletcoq_exist_ref=Lazy.from_funbuild_coq_exletcoq_not_ref=Lazy.from_funbuild_coq_notletcoq_False_ref=Lazy.from_funbuild_coq_Falseletcoq_sumbool_ref=Lazy.from_funbuild_coq_sumboolletcoq_sig_ref=Lazy.from_funbuild_coq_sigletcoq_or_ref=Lazy.from_funbuild_coq_orletcoq_iff_ref=Lazy.from_funbuild_coq_iff(** Deprecated functions that search by library name. *)letbuild_sigma_set()=CErrors.anomaly(Pp.str"Use build_sigma_type.")