123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719(************************************************************************)(* * 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) *)(************************************************************************)openCErrorsopenUtilopenNamesopenUnivopenTermopenConstropenVarsopenContextopenDeclarationsopenDeclareopsopenEnvironopenReductionopsopenContext.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;lett=Inductive.type_of_inductive(specif,u)inArguments_renaming.rename_typet(IndRefind)lete_type_of_inductiveenvsigma(ind,u)=let(mib,_asspecif)=Inductive.lookup_mind_specifenvindinReductionops.check_hyps_inclusionenvsigma(GlobRef.IndRefind)mib.mind_hyps;lett=Inductive.type_of_inductive(specif,EConstr.Unsafe.to_instanceu)inEConstr.of_constr(Arguments_renaming.rename_typet(IndRefind))(* 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;lett=Inductive.type_of_constructor(cstr,u)specifinArguments_renaming.rename_typet(ConstructRefcstr)lete_type_of_constructorenvsigma(cstr,u)=let(mib,_asspecif)=Inductive.lookup_mind_specifenv(inductive_of_constructorcstr)inReductionops.check_hyps_inclusionenvsigma(GlobRef.ConstructRefcstr)mib.mind_hyps;lett=Inductive.type_of_constructor(cstr,EConstr.Unsafe.to_instanceu)specifinEConstr.of_constr(Arguments_renaming.rename_typet(ConstructRefcstr))(* 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_elim(mib,mip)=matchmib.mind_recordwith|PrimRecord_->mib.mind_finite==BiFinite||mip.mind_relevance==Irrelevant|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_decls(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_declstypiinlet(_,allargs)=decompose_app_listcclinletvargs=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=destLambdasigmapredinletmib,mipasspecif=Inductive.lookup_mind_specifenvindinlet()=if(* dependent *)not(Vars.noccurnsigma1t)&¬(has_dependent_elimspecif)thenuser_errPp.(str"Dependent case analysis not allowed"++str" on inductive type "++Termops.pr_global_envenv(IndRefind)++str".")inletbranch=branches.(0)inletctx,br=decompose_lambda_n_declssigmamip.mind_consnrealdecls.(0)branchinletproj=matchEConstr.destRelsigmabrwith|exceptionDestKO->None|i->beginmatchList.skipn(i-1)ctxwith|exceptionFailure_->None|ctx->matchctxwith|[]->None|LocalDef_::_->(* XXX Maybe we should produce the applied constant for this letin pseudoprojection?
We would have to get the params etc*)None|LocalAssum_::ctx->(* This match is just a projection *)letp=ps.(Context.Rel.nhypsctx)inSome(mkProj(Projection.makeptrue,c))endinmatchprojwith|Someproj->proj|None->letn,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_contextuarsigninsubstl_rel_contextsubstarsign(* 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_signatureenvsigmadep((ind,_),_asindf)=letarsign=get_arityenvindfinletr=Inductive.relevance_of_inductiveenvindinletanon=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)(**************************************************)(** 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_relevancewith|Sorts.Irrelevant->false|Sorts.Relevant->true|Sorts.RelevanceVar_->assertfalseinletkn=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_app_listsigmatinmatchEConstr.kindsigmatwith|Indind->(ind,l)|_->raiseNot_foundletfind_mrectype_vectenvsigmac=let(t,l)=EConstr.decompose_appsigma(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_app_listsigma(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_app_listsigma(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_app_listsigma(whd_allenvsigmac)inmatchEConstr.kindsigmatwith|Indindwhen(fst(Inductive.lookup_mind_specifenv(fstind))).mind_finite==CoFinite->letl=List.mapEConstr.Unsafe.to_constrlin(ind,l)|_->raiseNot_found(* Type of Case predicates *)letarity_of_case_predicateenv(ind,params)depk=letarsign=get_arityenv(ind,params)inletr=Inductive.relevance_of_inductiveenv(fstind)inletmind=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|QSort(_,u)->assertfalse(* template cannot contain sort variables *)(* 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(EConstr.ESorts.make(Sorts.sort_of_univu))inevdref:=evm;sinlets=EConstr.ESorts.kind!evdrefsin(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_arityenvsigmaconcltyinletctx=List.revmip.mind_arity_ctxtinletevdref=refsigmainletctx=instantiate_universesenvevdrefsclar.template_level(ctx,templ.template_param_levels)inletscl=EConstr.ESorts.kind!evdrefsclin!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