123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173(************************************************************************)(* * 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) *)(************************************************************************)(* Created by Hugo Herbelin from contents related to inductive schemes
initially developed by Christine Paulin (induction schemes), Vincent
Siles (decidable equality and boolean equality) and Matthieu Sozeau
(combined scheme) in file command.ml, Sep 2009 *)(* This file builds schemes related to case analysis and recursion schemes *)openSortsopenConstropenIndrecopenDeclarationsopenTypeopsopenInd_tables(* Induction/recursion schemes *)letbuild_induction_scheme_in_typeenvdepsortind=letsigma=Evd.from_envenvinletsigma,pind=Evd.fresh_inductive_instance~rigid:UState.univ_rigidenvsigmaindinletpind=Util.on_sndEConstr.EInstance.makepindinletsigma,sort=Evd.fresh_sort_in_family~rigid:UnivRigidsigmasortinletsigma,c=build_induction_schemeenvsigmapinddepsortinEConstr.to_constrsigmac,Evd.evar_universe_contextsigma(**********************************************************************)(* [modify_sort_scheme s rec] replaces the sort of the scheme
[rec] by [s] *)letchange_sort_aritysort=letrecdreca=matchkindawith|Cast(c,_,_)->drecc|Prod(n,t,c)->lets,c'=dreccins,mkProd(n,t,c')|LetIn(n,b,t,c)->lets,c'=dreccins,mkLetIn(n,b,t,c')|Sorts->s,mkSortsort|_->assertfalseindrec(** [weaken_sort_scheme env sigma s n c t] derives by subtyping from [c:t]
whose conclusion is quantified on [Type i] at position [n] of [t] a
scheme quantified on sort [s]. [s] is declared less or equal to [i]. *)letweaken_sort_schemeenvevdsortnparstermty=letopenContext.Rel.Declarationinletevdref=refevdinletrecdrecctxnpelim=matchkindelimwith|Prod(n,t,c)->letctx=LocalAssum(n,t)::ctxinifInt.equalnp0thenletosort,t'=change_sort_arity(EConstr.ESorts.kind!evdrefsort)tinevdref:=(iffalsethenEvd.set_eq_sortelseEvd.set_leq_sort)env!evdrefsort(EConstr.ESorts.makeosort);mkProd(n,t',c),mkLambda(n,t',mkApp(term,Context.Rel.instancemkRel0ctx))elseletc',term'=drecctx(np-1)cinmkProd(n,t,c'),mkLambda(n,t,term')|LetIn(n,b,t,c)->letctx=LocalDef(n,b,t)::ctxinletc',term'=drecctxnpcinmkLetIn(n,b,t,c'),mkLetIn(n,b,t,term')|_->CErrors.anomaly~label:"weaken_sort_scheme"(Pp.str"wrong elimination type.")inletty,term=drec[]nparstyin!evdref,ty,termletoptimize_non_type_induction_schemekinddepsortenv_handleind=(* This non-local call to [lookup_scheme] is fine since we do not use it on a
dependency generated on the fly. *)matchlookup_schemekindindwith|Somecte->letsigma=Evd.from_envenvin(* in case the inductive has a type elimination, generates only one
induction scheme, the other ones share the same code with the
appropriate type *)letsigma,cte=Evd.fresh_constant_instanceenvsigmacteinletc=mkConstUcteinlett=type_of_constant_inenvcteinlet(mib,mip)=Inductive.lookup_mind_specifenvindinletnpars=(* if a constructor of [ind] contains a recursive call, the scheme
is generalized only wrt recursively uniform parameters *)if(Inductiveops.mis_is_recursive_subset[ind]mip.mind_recargs)thenmib.mind_nparams_recelsemib.mind_nparamsinletsigma,sort=Evd.fresh_sort_in_familysigmasortinletsigma,t',c'=weaken_sort_schemeenvsigmasortnparsctinletsigma=Evd.minimize_universessigmain(Evarutil.nf_evars_universessigmac',Evd.evar_universe_contextsigma)|None->build_induction_scheme_in_typeenvdepsortindletrect_dep=declare_individual_scheme_object"rect_dep"(funenv_x->build_induction_scheme_in_typeenvtrueInTypex)letrec_dep=declare_individual_scheme_object"rec_dep"(optimize_non_type_induction_schemerect_deptrueInSet)letind_dep=declare_individual_scheme_object"ind_dep"(optimize_non_type_induction_schemerec_deptrueInProp)letsind_dep=declare_individual_scheme_object"sind_dep"(funenv_x->build_induction_scheme_in_typeenvtrueInSPropx)letrect_nodep=declare_individual_scheme_object"rect_nodep"(funenv_x->build_induction_scheme_in_typeenvfalseInTypex)letrec_nodep=declare_individual_scheme_object"rec_nodep"(optimize_non_type_induction_schemerect_nodepfalseInSet)letind_nodep=declare_individual_scheme_object"ind_nodep"(optimize_non_type_induction_schemerec_nodepfalseInProp)letsind_nodep=declare_individual_scheme_object"sind_nodep"(funenv_x->build_induction_scheme_in_typeenvfalseInSPropx)letelim_scheme~dep~to_kind=matchdep,to_kindwith|false,InSProp->sind_nodep|false,InProp->ind_nodep|false,InSet->rec_nodep|false,(InType|InQSort)->rect_nodep|true,InSProp->sind_dep|true,InProp->ind_dep|true,InSet->rec_dep|true,(InType|InQSort)->rect_dep(* Case analysis *)letbuild_case_analysis_scheme_in_typeenvdepsortind=letsigma=Evd.from_envenvinlet(sigma,indu)=Evd.fresh_inductive_instanceenvsigmaindinletindu=Util.on_sndEConstr.EInstance.makeinduinletsigma,sort=Evd.fresh_sort_in_family~rigid:UnivRigidsigmasortinlet(sigma,c)=build_case_analysis_schemeenvsigmaindudepsortinlet(c,_)=Indrec.eval_case_analysiscinEConstr.Unsafe.to_constrc,Evd.evar_universe_contextsigmaletcase_dep=declare_individual_scheme_object"case_dep"(funenv_x->build_case_analysis_scheme_in_typeenvtrueInTypex)letcase_nodep=declare_individual_scheme_object"case_nodep"(funenv_x->build_case_analysis_scheme_in_typeenvfalseInTypex)letcasep_dep=declare_individual_scheme_object"casep_dep"(funenv_x->build_case_analysis_scheme_in_typeenvtrueInPropx)letcasep_nodep=declare_individual_scheme_object"casep_nodep"(funenv_x->build_case_analysis_scheme_in_typeenvfalseInPropx)