123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762(************************************************************************)(* * 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) *)(************************************************************************)openCErrorsopenUtilopenNamesopenUnivopenTermopenConstropenVarsopenContextopenTermopsopenDeclarationsopenDeclareopsopenEnvironopenReductionopsopenContext.Rel.Declaration(* The following three functions are similar to the ones defined in
Inductive, but they expect an env *)lettype_of_inductiveenv(ind,u)=let(mib,_asspecif)=Inductive.lookup_mind_specifenvindinTypeops.check_hyps_inclusionenv(GlobRef.IndRefind)mib.mind_hyps;Inductive.type_of_inductive(specif,u)(* Return type as quoted by the user *)lettype_of_constructorenv(cstr,u)=let(mib,_asspecif)=Inductive.lookup_mind_specifenv(inductive_of_constructorcstr)inTypeops.check_hyps_inclusionenv(GlobRef.ConstructRefcstr)mib.mind_hyps;Inductive.type_of_constructor(cstr,u)specif(* Return constructor types in user form *)lettype_of_constructorsenv(ind,uasindu)=letspecif=Inductive.lookup_mind_specifenvindinInductive.type_of_constructorsinduspecif(* Return constructor types in normal form *)letarities_of_constructorsenv(ind,uasindu)=letspecif=Inductive.lookup_mind_specifenvindinInductive.arities_of_constructorsinduspecif(* [inductive_family] = [inductive_instance] applied to global parameters *)typeinductive_family=pinductive*constrlistletmake_ind_family(mis,params)=(mis,params)letdest_ind_family(mis,params):inductive_family=(mis,params)letmap_ind_familyf(mis,params)=(mis,List.mapfparams)letliftn_inductive_familynd=map_ind_family(liftnnd)letlift_inductive_familyn=liftn_inductive_familyn1letsubstnl_ind_familyln=map_ind_family(substnlln)letrelevance_of_inductive_familyenv((ind,_),_:inductive_family)=Inductive.relevance_of_inductiveenvindtypeinductive_type=IndTypeofinductive_family*EConstr.constrlistletind_of_ind_type=functionIndType(((ind,_),_),_)->indletmake_ind_type(indf,realargs)=IndType(indf,realargs)letdest_ind_type(IndType(indf,realargs))=(indf,realargs)letmap_inductive_typef(IndType(indf,realargs))=letf'c=EConstr.Unsafe.to_constr(f(EConstr.of_constrc))inIndType(map_ind_familyf'indf,List.mapfrealargs)letliftn_inductive_typend=map_inductive_type(EConstr.Vars.liftnnd)letlift_inductive_typen=liftn_inductive_typen1letsubstnl_ind_typeln=map_inductive_type(EConstr.Vars.substnlln)letrelevance_of_inductive_typeenv(IndType(indf,_))=relevance_of_inductive_familyenvindfletmkAppliedInd(IndType((ind,params),realargs))=letopenEConstrinletind=on_sndEInstance.makeindinapplist(mkIndUind,(List.mapEConstr.of_constrparams)@realargs)(* Does not consider imbricated or mutually recursive types *)letmis_is_recursive_subsetlistindrarg=letone_is_recrvec=List.exists(funra->matchdest_recargrawith|Mrec(_,i)->Int.List.memilistind|_->false)rvecinArray.existsone_is_rec(dest_subtermsrarg)letmis_is_recursive(ind,mib,mip)=mis_is_recursive_subset(List.interval0(mib.mind_ntypes-1))mip.mind_recargsletmis_nf_constructor_type((_,j),u)(mib,mip)=letnconstr=Array.lengthmip.mind_consnamesinifj>nconstrthenuser_errPp.(str"Not enough constructors in the type.");let(ctx,cty)=mip.mind_nf_lc.(j-1)insubst_instance_constru(Term.it_mkProd_or_LetInctyctx)(* Number of constructors *)letnconstructorsenvind=let(_,mip)=Inductive.lookup_mind_specifenvindinArray.lengthmip.mind_consnamesletnconstructors_envenvind=nconstructorsenvind[@@ocaml.deprecated"Alias for Inductiveops.nconstructors"](* Arity of constructors excluding parameters, excluding local defs *)letconstructors_nrealargsenvind=let(_,mip)=Inductive.lookup_mind_specifenvindinmip.mind_consnrealargsletconstructors_nrealargs_envenvind=constructors_nrealargsenvind[@@ocaml.deprecated"Alias for Inductiveops.constructors_nrealargs"](* Arity of constructors excluding parameters, including local defs *)letconstructors_nrealdeclsenvind=let(_,mip)=Inductive.lookup_mind_specifenvindinmip.mind_consnrealdeclsletconstructors_nrealdecls_envenvind=constructors_nrealdeclsenvind[@@ocaml.deprecated"Alias for Inductiveops.constructors_nrealdecls"](* Arity of constructors including parameters, excluding local defs *)letconstructor_nallargsenv(ind,j)=let(mib,mip)=Inductive.lookup_mind_specifenvindinmip.mind_consnrealargs.(j-1)+mib.mind_nparamsletconstructor_nallargs_envenv(indsp,j)=constructor_nallargsenv(indsp,j)[@@ocaml.deprecated"Alias for Inductiveops.constructor_nallargs"](* Arity of constructors including params, including local defs *)letconstructor_nalldeclsenv(ind,j)=(* TOCHANGE en decls *)let(mib,mip)=Inductive.lookup_mind_specifenvindinmip.mind_consnrealdecls.(j-1)+Context.Rel.length(mib.mind_params_ctxt)letconstructor_nalldecls_envenv(indsp,j)=constructor_nalldeclsenv(indsp,j)[@@ocaml.deprecated"Alias for Inductiveops.constructor_nalldecls"](* Arity of constructors excluding params, excluding local defs *)letconstructor_nrealargsenv(ind,j)=let(_,mip)=Inductive.lookup_mind_specifenvindinmip.mind_consnrealargs.(j-1)letconstructor_nrealargs_envenv(ind,j)=constructor_nrealargsenv(ind,j)[@@ocaml.deprecated"Alias for Inductiveops.constructor_nrealargs"](* Arity of constructors excluding params, including local defs *)letconstructor_nrealdeclsenv(ind,j)=(* TOCHANGE en decls *)let(_,mip)=Inductive.lookup_mind_specifenvindinmip.mind_consnrealdecls.(j-1)letconstructor_nrealdecls_envenv(ind,j)=constructor_nrealdeclsenv(ind,j)[@@ocaml.deprecated"Alias for Inductiveops.constructor_nrealdecls"](* Length of arity, excluding params, excluding local defs *)letinductive_nrealargsenvind=let(_,mip)=Inductive.lookup_mind_specifenvindinmip.mind_nrealargsletinductive_nrealargs_envenvind=inductive_nrealargsenvind[@@ocaml.deprecated"Alias for Inductiveops.inductive_nrealargs"](* Length of arity, excluding params, including local defs *)letinductive_nrealdeclsenvind=let(_,mip)=Inductive.lookup_mind_specifenvindinmip.mind_nrealdeclsletinductive_nrealdecls_envenvind=inductive_nrealdeclsenvind[@@ocaml.deprecated"Alias for Inductiveops.inductive_nrealdecls"](* Full length of arity (w/o local defs) *)letinductive_nallargsenvind=let(mib,mip)=Inductive.lookup_mind_specifenvindinmib.mind_nparams+mip.mind_nrealargsletinductive_nallargs_envenvind=inductive_nallargsenvind[@@ocaml.deprecated"Alias for Inductiveops.inductive_nallargs"](* Length of arity (w/o local defs) *)letinductive_nparamsenvind=let(mib,mip)=Inductive.lookup_mind_specifenvindinmib.mind_nparamsletinductive_nparams_envenvind=inductive_nparamsenvind[@@ocaml.deprecated"Alias for Inductiveops.inductive_nparams"](* Length of arity (with local defs) *)letinductive_nparamdeclsenvind=let(mib,mip)=Inductive.lookup_mind_specifenvindinContext.Rel.lengthmib.mind_params_ctxtletinductive_nparamdecls_envenvind=inductive_nparamdeclsenvind[@@ocaml.deprecated"Alias for Inductiveops.inductive_nparamsdecls"](* Full length of arity (with local defs) *)letinductive_nalldeclsenvind=let(mib,mip)=Inductive.lookup_mind_specifenvindinContext.Rel.length(mib.mind_params_ctxt)+mip.mind_nrealdeclsletinductive_nalldecls_envenvind=inductive_nalldeclsenvind[@@ocaml.deprecated"Alias for Inductiveops.inductive_nalldecls"](* Others *)letinductive_paramdeclsenv(ind,u)=let(mib,mip)=Inductive.lookup_mind_specifenvindinInductive.inductive_paramdecls(mib,u)letinductive_paramdecls_envenv(ind,u)=inductive_paramdeclsenv(ind,u)[@@ocaml.deprecated"Alias for Inductiveops.inductive_paramsdecls"]letinductive_alldeclsenv(ind,u)=let(mib,mip)=Inductive.lookup_mind_specifenvindinVars.subst_instance_contextumip.mind_arity_ctxtletinductive_alldecls_envenv(ind,u)=inductive_alldeclsenv(ind,u)[@@ocaml.deprecated"Alias for Inductiveops.inductive_alldecls"]letinductive_alltagsenvind=let(mib,mip)=Inductive.lookup_mind_specifenvindinContext.Rel.to_tagsmip.mind_arity_ctxtletconstructor_alltagsenv(ind,j)=let(mib,mip)=Inductive.lookup_mind_specifenvindinContext.Rel.to_tags(fstmip.mind_nf_lc.(j-1))letconstructor_has_local_defsenv(indsp,j)=let(mib,mip)=Inductive.lookup_mind_specifenvindspinletl1=mip.mind_consnrealdecls.(j-1)+Context.Rel.length(mib.mind_params_ctxt)inletl2=recarg_lengthmip.mind_recargsj+mib.mind_nparamsinnot(Int.equall1l2)letinductive_has_local_defsenvind=let(mib,mip)=Inductive.lookup_mind_specifenvindinletl1=Context.Rel.length(mib.mind_params_ctxt)+mip.mind_nrealdeclsinletl2=mib.mind_nparams+mip.mind_nrealargsinnot(Int.equall1l2)lettop_allowed_sortenv(kn,iasind)=let(mib,mip)=Inductive.lookup_mind_specifenvindinmip.mind_kelimletsorts_belowtop=List.filter(funs->Sorts.family_leqstop)Sorts.[InSProp;InProp;InSet;InType]lethas_dependent_elimmib=matchmib.mind_recordwith|PrimRecord_->mib.mind_finite==BiFinite|NotRecord|FakeRecord->true(* Annotation for cases *)letmake_case_infoenvindrstyle=let(mib,mip)=Inductive.lookup_mind_specifenvindinletind_tags=Context.Rel.to_tags(List.firstnmip.mind_nrealdeclsmip.mind_arity_ctxt)inletcstr_tags=Array.map2(fun(d,_)n->Context.Rel.to_tags(List.firstnnd))mip.mind_nf_lcmip.mind_consnrealdeclsinletprint_info={ind_tags;cstr_tags;style}in{ci_ind=ind;ci_npar=mib.mind_nparams;ci_cstr_ndecls=mip.mind_consnrealdecls;ci_cstr_nargs=mip.mind_consnrealargs;ci_relevance=r;ci_pp_info=print_info}(*s Useful functions *)typeconstructor_summary={cs_cstr:pconstructor;cs_params:constrlist;cs_nargs:int;cs_args:Constr.rel_context;cs_concl_realargs:constrarray}letlift_constructorncs={cs_cstr=cs.cs_cstr;cs_params=List.map(liftn)cs.cs_params;cs_nargs=cs.cs_nargs;cs_args=Vars.lift_rel_contextncs.cs_args;cs_concl_realargs=Array.map(liftnn(cs.cs_nargs+1))cs.cs_concl_realargs}(* Accept either all parameters or only recursively uniform ones *)letinstantiate_paramstparamssign=letnnonrecpar=Context.Rel.nhypssign-List.lengthparamsin(* Adjust the signature if recursively non-uniform parameters are not here *)let_,sign=Context.Rel.chop_nhypsnnonrecparsigninlet_,t=decompose_prod_n_assum(Context.Rel.lengthsign)tinletsubst=subst_of_rel_context_instance_listsignparamsinsubstlsubsttletinstantiate_constructor_params(_,uascstru)(mib,_asmind_specif)params=lettypi=mis_nf_constructor_typecstrumind_specifinletctx=Vars.subst_instance_contextumib.mind_params_ctxtininstantiate_paramstypiparamsctxletget_constructor((ind,u),mib,mip,params)j=assert(j<=Array.lengthmip.mind_consnames);lettypi=instantiate_constructor_params((ind,j),u)(mib,mip)paramsinlet(args,ccl)=decompose_prod_assumtypiinlet(_,allargs)=decompose_appcclinletvargs=List.skipn(List.lengthparams)allargsin{cs_cstr=(ith_constructor_of_inductiveindj,u);cs_params=params;cs_nargs=Context.Rel.lengthargs;cs_args=args;cs_concl_realargs=Array.of_listvargs}letget_constructorsenv(ind,params)=let(mib,mip)=Inductive.lookup_mind_specifenv(fstind)inArray.init(Array.lengthmip.mind_consnames)(funj->get_constructor(ind,mib,mip,params)(j+1))letget_projections=Environ.get_projectionsletmake_case_invertenv(IndType(((ind,u),params),indices))ci=ifTypeops.should_invert_caseenvcithenCaseInvert{indices=Array.of_listindices}elseNoInvertletmake_projectenvsigmaindpredcbranchesps=letopenEConstrinassert(Array.lengthbranches==1);letna,ty,t=destLambdasigmapredinlet()=letmib,_=Inductive.lookup_mind_specifenvindinif(* dependent *)not(Vars.noccurnsigma1t)&¬(has_dependent_elimmib)thenuser_errPp.(str"Dependent case analysis not allowed"++str" on inductive type "++Termops.Internal.print_constr_envenvsigma(mkIndind)++str".")inletbranch=branches.(0)inletctx,br=decompose_lam_n_assumsigma(Array.lengthps)branchinletn,len,ctx=List.fold_right(fundecl(i,j,ctx)->matchdeclwith|LocalAssum(na,ty)->lett=mkProj(Projection.makeps.(i)true,mkRelj)in(i+1,j+1,LocalDef(na,t,Vars.liftn1jty)::ctx)|LocalDef(na,b,ty)->(i,j+1,LocalDef(na,Vars.liftn1jb,Vars.liftn1jty)::ctx))ctx(0,1,[])inmkLetIn(na,c,ty,it_mkLambda_or_LetIn(Vars.liftn1(Array.lengthps+1)br)ctx)letsimple_make_case_or_projectenvsigmacipredinvertcbranches=letopenEConstrinletind=ci.ci_indinletprojs=get_projectionsenvindinmatchprojswith|None->mkCase(EConstr.contract_caseenvsigma(ci,pred,invert,c,branches))|Someps->make_projectenvsigmaindpredcbranchespsletmake_case_or_projectenvsigmaindtcipredcbranches=letopenEConstrinletIndType(((ind,_),_),_)=indtinletprojs=get_projectionsenvindinmatchprojswith|None->letinvert=make_case_invertenvindtciinmkCase(EConstr.contract_caseenvsigma(ci,pred,invert,c,branches))|Someps->make_projectenvsigmaindpredcbranchesps(* substitution in a signature *)letsubstnl_rel_contextsubstnsign=letrecauxn=function|d::sign->substnl_declsubstnd::aux(n+1)sign|[]->[]inList.rev(auxn(List.revsign))letsubstl_rel_contextsubst=substnl_rel_contextsubst0letget_arityenv((ind,u),params)=let(mib,mip)=Inductive.lookup_mind_specifenvindinletparsign=(* Dynamically detect if called with an instance of recursively
uniform parameter only or also of recursively non-uniform
parameters *)letnparams=List.lengthparamsinifInt.equalnparamsmib.mind_nparamsthenInductive.inductive_paramdecls(mib,u)elsebeginassert(Int.equalnparamsmib.mind_nparams_rec);snd(Inductive.inductive_nonrec_rec_paramdecls(mib,u))endinletarproperlength=List.lengthmip.mind_arity_ctxt-List.lengthparsigninletarsign,_=List.choparproperlengthmip.mind_arity_ctxtinletsubst=subst_of_rel_context_instance_listparsignparamsinletarsign=Vars.subst_instance_contextuarsignin(substl_rel_contextsubstarsign,Inductive.inductive_sort_familymip)(* Functions to build standard types related to inductive *)letbuild_dependent_constructorcs=applist(mkConstructUcs.cs_cstr,(List.map(liftcs.cs_nargs)cs.cs_params)@(Context.Rel.instance_listmkRel0cs.cs_args))letbuild_dependent_inductiveenv((ind,params)asindf)=letarsign,_=get_arityenvindfinletnrealargs=List.lengtharsigninapplist(mkIndUind,(List.map(liftnrealargs)params)@(Context.Rel.instance_listmkRel0arsign))(* builds the arity of an elimination predicate in sort [s] *)letmake_arity_signatureenvsigmadepindf=let(arsign,s)=get_arityenvindfinletr=Sorts.relevance_of_sort_familysinletanon=make_annotAnonymousrinletarsign=List.map(fund->Termops.map_rel_declEConstr.of_constrd)arsigninifdepthen(* We need names everywhere *)Namegen.name_contextenvsigma((LocalAssum(anon,EConstr.of_constr(build_dependent_inductiveenvindf)))::arsign)(* Costly: would be better to name once for all at definition time *)else(* No need to enforce names *)arsignletmake_arityenvsigmadepindfs=letopenEConstrinit_mkProd_or_LetIn(mkSorts)(make_arity_signatureenvsigmadepindf)(* [p] is the predicate and [cs] a constructor summary *)letbuild_branch_typeenvsigmadeppcs=letbase=appvect(liftcs.cs_nargsp,cs.cs_concl_realargs)inifdepthenEConstr.Unsafe.to_constr(Namegen.it_mkProd_or_LetIn_nameenvsigma(EConstr.of_constr(applist(base,[build_dependent_constructorcs])))(List.map(fund->Termops.map_rel_declEConstr.of_constrd)cs.cs_args))elseTerm.it_mkProd_or_LetInbasecs.cs_args(**************************************************)(** From a rel context describing the constructor arguments,
build an expansion function.
The term built is expecting to be substituted first by
a substitution of the form [params, x : ind params] *)letcompute_projectionsenv(kn,iasind)=letopenTerminletmib=Environ.lookup_mindknenvinletu=make_abstract_instance(Declareops.inductive_polymorphic_contextmib)inletx=matchmib.mind_recordwith|NotRecord|FakeRecord->anomalyPp.(str"Trying to build primitive projections for a non-primitive record")|PrimRecordinfo->letid,_,_,_=info.(i)inmake_annot(Nameid)mib.mind_packets.(i).mind_relevanceinletpkt=mib.mind_packets.(i)inlet{mind_nparams=nparamargs;mind_params_ctxt=params}=mibinletctx,_=pkt.mind_nf_lc.(0)inletctx,paramslet=List.choppkt.mind_consnrealdecls.(0)ctxin(* We build a substitution smashing the lets in the record parameters so
that typechecking projections requires just a substitution and not
matching with a parameter context. *)letindty=(* [ty] = [Ind inst] is typed in context [params] *)letinst=Context.Rel.instancemkRel0paramsletinletindu=mkIndU(ind,u)inletty=mkApp(indu,inst)in(* [Ind inst] is typed in context [params-wo-let] *)tyinletprojectionsdecl(proj_arg,j,pbs,subst)=matchdeclwith|LocalDef(na,c,t)->(* From [params, field1,..,fieldj |- c(params,field1,..,fieldj)]
to [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)] *)letc=liftn1jcin(* From [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)]
to [params, x:I |- c(params,proj1 x,..,projj x)] *)letc1=substlsubstcin(* From [params, x:I |- subst:field1,..,fieldj]
to [params, x:I |- subst:field1,..,fieldj+1] where [subst]
is represented with instance of field1 last *)letsubst=c1::substin(proj_arg,j+1,pbs,subst)|LocalAssum(na,t)->matchna.binder_namewith|Nameid->letlab=Label.of_ididinletproj_relevant=matchna.binder_relevancewithSorts.Irrelevant->false|Sorts.Relevant->trueinletkn=Projection.Repr.makeind~proj_relevant~proj_npars:mib.mind_nparams~proj_arglabin(* from [params, field1,..,fieldj |- t(params,field1,..,fieldj)]
to [params, x:I, field1,..,fieldj |- t(params,field1,..,fieldj] *)lett=liftn1jtin(* from [params, x:I, field1,..,fieldj |- t(params,field1,..,fieldj)]
to [params-wo-let, x:I |- t(params,proj1 x,..,projj x)] *)(* from [params, x:I, field1,..,fieldj |- t(field1,..,fieldj)]
to [params, x:I |- t(proj1 x,..,projj x)] *)letty=substlsubsttinletterm=mkProj(Projection.makekntrue,mkRel1)inletfterm=mkProj(Projection.makeknfalse,mkRel1)inletetab=it_mkLambda_or_LetIn(mkLambda(x,indty,term))paramsinletetat=it_mkProd_or_LetIn(mkProd(x,indty,ty))paramsinletbody=(etab,etat)in(proj_arg+1,j+1,body::pbs,fterm::subst)|Anonymous->anomalyPp.(str"Trying to build primitive projections for a non-primitive record")inlet(_,_,pbs,subst)=List.fold_rightprojectionsctx(0,1,[],[])inArray.rev_of_listpbs(**************************************************)letextract_mrectypesigmat=letopenEConstrinlet(t,l)=decompose_appsigmatinmatchEConstr.kindsigmatwith|Indind->(ind,l)|_->raiseNot_foundletfind_mrectype_vectenvsigmac=let(t,l)=Termops.decompose_app_vectsigma(whd_allenvsigmac)inmatchEConstr.kindsigmatwith|Indind->(ind,l)|_->raiseNot_foundletfind_mrectypeenvsigmac=let(ind,v)=find_mrectype_vectenvsigmacin(ind,Array.to_listv)letfind_rectypeenvsigmac=letopenEConstrinlet(t,l)=decompose_appsigma(whd_allenvsigmac)inmatchEConstr.kindsigmatwith|Ind(ind,u)->let(mib,mip)=Inductive.lookup_mind_specifenvindinifmib.mind_nparams>List.lengthlthenraiseNot_found;letl=List.mapEConstr.Unsafe.to_constrlinlet(par,rargs)=List.chopmib.mind_nparamslinletindu=(ind,EInstance.kindsigmau)inIndType((indu,par),List.mapEConstr.of_constrrargs)|_->raiseNot_foundletfind_inductiveenvsigmac=letopenEConstrinlet(t,l)=decompose_appsigma(whd_allenvsigmac)inmatchEConstr.kindsigmatwith|Indindwhen(fst(Inductive.lookup_mind_specifenv(fstind))).mind_finite<>CoFinite->letl=List.mapEConstr.Unsafe.to_constrlin(ind,l)|_->raiseNot_foundletfind_coinductiveenvsigmac=letopenEConstrinlet(t,l)=decompose_appsigma(whd_allenvsigmac)inmatchEConstr.kindsigmatwith|Indindwhen(fst(Inductive.lookup_mind_specifenv(fstind))).mind_finite==CoFinite->letl=List.mapEConstr.Unsafe.to_constrlin(ind,l)|_->raiseNot_found(***********************************************)(* find appropriate names for pattern variables. Useful in the Case
and Inversion (case_then_using et case_nodep_then_using) tactics. *)letis_predicate_explicitly_depenvsigmapredarsign=letrecsrecenvpvalarsign=letpv'=whd_allenvsigmapvalinmatchEConstr.kindsigmapv',arsignwith|Lambda(na,t,b),(LocalAssum_)::arsign->srec(push_rel_assum(na,t)env)barsign|Lambda(na,_,t),_->(* The following code has an impact on the introduction names
given by the tactics "case" and "inversion": when the
elimination is not dependent, "case" uses Anonymous for
inductive types in Prop and names created by mkProd_name for
inductive types in Set/Type while "inversion" uses anonymous
for inductive types both in Prop and Set/Type !!
Previously, whether names were created or not relied on
whether the predicate created in Indrec.make_case_com had a
dependent arity or not. To avoid different predicates
printed the same in v8, all predicates built in indrec.ml
got a dependent arity (Aug 2004). The new way to decide
whether names have to be created or not is to use an
Anonymous or Named variable to enforce the expected
dependency status (of course, Anonymous implies non
dependent, but not conversely).
From Coq > 8.2, using or not the effective dependency of
the predicate is parametrable! *)beginmatchna.binder_namewith|Anonymous->false|Name_->trueend|_->anomaly(Pp.str"Non eta-expanded dep-expanded \"match\" predicate.")insrecenv(EConstr.of_constrpred)arsignletis_elim_predicate_explicitly_dependentenvsigmapredindf=letarsign,_=get_arityenvindfinis_predicate_explicitly_depenvsigmapredarsignletset_namesenvsigmanbrty=letopenEConstrinlet(ctxt,cl)=decompose_prod_n_assumsigmanbrtyinNamegen.it_mkProd_or_LetIn_nameenvsigmaclctxtletset_pattern_namesenvsigmaindbrv=let(mib,mip)=Inductive.lookup_mind_specifenvindinletarities=Array.map(fun(d,_)->List.lengthd-mib.mind_nparams)mip.mind_nf_lcinArray.map2(set_namesenvsigma)aritiesbrvlettype_case_branches_with_namesenvsigmaindspecpc=let(ind,args)=indspecinletargs=List.mapEConstr.Unsafe.to_constrargsinlet(mib,mipasspecif)=Inductive.lookup_mind_specifenv(fstind)inletnparams=mib.mind_nparamsinlet(params,realargs)=List.chopnparamsargsinletlbrty=Inductive.build_branches_typeindspecifparamspinletlbrty=Array.mapEConstr.of_constrlbrtyin(* Build case type *)letconclty=lambda_appvect_assum(mip.mind_nrealdecls+1)p(Array.of_list(realargs@[c]))in(* Adjust names *)ifis_elim_predicate_explicitly_dependentenvsigmap(ind,params)then(set_pattern_namesenvsigma(fstind)lbrty,conclty)else(lbrty,conclty)(* Type of Case predicates *)letarity_of_case_predicateenv(ind,params)depk=letarsign,s=get_arityenv(ind,params)inletr=Sorts.relevance_of_sort_familysinletmind=build_dependent_inductiveenv(ind,params)inletconcl=ifdepthenmkArrowmindr(mkSortk)elsemkSortkinTerm.it_mkProd_or_LetInconclarsign(***********************************************)(* Inferring the sort of parameters of a polymorphic inductive type
knowing the sort of the conclusion *)letuniv_level_memls=matchswith|Prop|Set|SProp->false|Typeu->univ_level_memlu(* Compute the inductive argument types: replace the sorts
that appear in the type of the inductive by the sort of the
conclusion, and the other ones by fresh universes. *)letrecinstantiate_universesenvevdrefsclis=function|(LocalDef_asd)::sign,exp->d::instantiate_universesenvevdrefsclis(sign,exp)|d::sign,None::exp->d::instantiate_universesenvevdrefsclis(sign,exp)|(LocalAssum(na,ty))::sign,Somel::exp->letctx,_=Reduction.dest_arityenvtyinletu=Univ.Universe.makelinlets=(* Does the sort of parameter [u] appear in (or equal)
the sort of inductive [is] ? *)ifuniv_level_memlisthenscl(* constrained sort: replace by scl *)else(* unconstrained sort: replace by fresh universe *)letevm,s=Evd.new_sort_variableEvd.univ_flexible!evdrefinletevm=Evd.set_leq_sortenvevms(Sorts.sort_of_univu)inevdref:=evm;sin(LocalAssum(na,mkArity(ctx,s)))::instantiate_universesenvevdrefsclis(sign,exp)|sign,[]->sign(* Uniform parameters are exhausted *)|[],_->assertfalselettype_of_inductive_knowing_conclusionenvsigma((mib,mip),u)conclty=matchmip.mind_aritywith|RegularAritys->sigma,EConstr.of_constr(subst_instance_construs.mind_user_arity)|TemplateArityar->lettempl=matchmib.mind_templatewith|None->assertfalse|Somet->tinlet_,scl=splay_arityenvsigmaconcltyinletscl=EConstr.ESorts.kindsigmasclinletctx=List.revmip.mind_arity_ctxtinletevdref=refsigmainletctx=instantiate_universesenvevdrefsclar.template_level(ctx,templ.template_param_levels)in!evdref,EConstr.of_constr(mkArity(List.revctx,scl))lettype_of_projection_constantenv(p,u)=letpty=lookup_projectionpenvinVars.subst_instance_construptylettype_of_projection_knowing_argenvsigmapcty=letc=EConstr.Unsafe.to_constrcinletIndType(pars,realargs)=tryfind_rectypeenvsigmatywithNot_found->raise(Invalid_argument"type_of_projection_knowing_arg_type: not an inductive type")inlet(_,u),pars=dest_ind_familyparsinsubstl(c::List.revpars)(type_of_projection_constantenv(p,u))(***********************************************)(* Guard condition *)(* A function which checks that a term well typed verifies both
syntactic conditions *)letcontrol_only_guardenvsigmac=letc=Evarutil.nf_evarsigmacinletcheck_fix_cofixec=(* [c] has already been normalized upfront *)letc=EConstr.Unsafe.to_constrcinmatchkindcwith|CoFix(_,(_,_,_)ascofix)->Inductive.check_cofixecofix|Fixfix->Inductive.check_fixefix|_->()inletreciterenvc=check_fix_cofixenvc;EConstr.iter_with_full_bindersenvsigmaEConstr.push_reliterenvciniterenvc