123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208(************************************************************************)(* * The Rocq Prover / The Rocq 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 *)openNamesopenIndrecopenDeclarationsopenInd_tablesopenUnivGenletprop_but_default_dependent_elim=Summary.ref~name:"PROP-BUT-DEFAULT-DEPENDENT-ELIM"Indset_env.emptyletinPropButDefaultDepElim:inductive->Libobject.obj=Libobject.declare_object@@Libobject.superglobal_object"prop_but_default_dependent_elim"~cache:(funi->prop_but_default_dependent_elim:=Indset_env.addi!prop_but_default_dependent_elim)~subst:(Some(fun(subst,i)->Mod_subst.subst_indsubsti))~discharge:(funi->Somei)letdeclare_prop_but_default_dependent_elimi=Lib.add_leaf(inPropButDefaultDepElimi)letis_prop_but_default_dependent_elimi=Indset_env.memi!prop_but_default_dependent_elimletpseudo_sort_quality_for_elimindmip=lets=mip.mind_sortinifSorts.is_props&&is_prop_but_default_dependent_elimindthenSorts.Quality.qtypeelseSorts.qualitysletdefault_case_analysis_dependenceenvind=let_,mipasspecif=Inductive.lookup_mind_specifenvindinInductiveops.has_dependent_elimspecif&&(not(Sorts.is_propmip.mind_sort)||is_prop_but_default_dependent_elimind)(* **************************************************** *)(* Induction/recursion schemes *)(* **************************************************** *)letbuild_induction_scheme_in_typeenvdepsortind=letsigma=Evd.from_envenvinletsigma,pind=Evd.fresh_inductive_instance~rigid:UState.univ_rigidenvsigmaindinletsigma,sort=Evd.fresh_sort_in_quality~rigid:UnivRigidsigmasortinletsigma,c=build_induction_schemeenvsigmapinddepsortinEConstr.to_constrsigmac,Evd.ustatesigmaletrect_dep=declare_individual_scheme_object"rect_dep"(funenv_x->build_induction_scheme_in_typeenvtrueQualityOrSet.qtypex)letrec_dep=declare_individual_scheme_object"rec_dep"(funenv_x->build_induction_scheme_in_typeenvtrueQualityOrSet.setx)letind_dep=declare_individual_scheme_object"ind_dep"(funenv_x->build_induction_scheme_in_typeenvtrueQualityOrSet.propx)letsind_dep=declare_individual_scheme_object"sind_dep"(funenv_x->build_induction_scheme_in_typeenvtrueQualityOrSet.spropx)letrect_nodep=declare_individual_scheme_object"rect_nodep"(funenv_x->build_induction_scheme_in_typeenvfalseQualityOrSet.qtypex)letrec_nodep=declare_individual_scheme_object"rec_nodep"(funenv_x->build_induction_scheme_in_typeenvfalseQualityOrSet.setx)letind_nodep=declare_individual_scheme_object"ind_nodep"(funenv_x->build_induction_scheme_in_typeenvfalseQualityOrSet.propx)letsind_nodep=declare_individual_scheme_object"sind_nodep"(funenv_x->build_induction_scheme_in_typeenvfalseQualityOrSet.spropx)letelim_scheme~dep~to_kind=letopenQualityOrSetinmatchto_kindwith|Qualq->beginmatchqwith|QConstantQSPropwhendep->sind_dep|QConstantQPropwhendep->ind_dep|(QConstantQType|QVar_)whendep->rect_dep|QConstantQSProp->sind_nodep|QConstantQProp->ind_nodep|QConstantQType|QVar_->rect_nodepend|Set->ifdepthenrec_depelserec_nodepletelimination_suffix=letopenUnivGen.QualityOrSetinletopenSorts.Qualityinfunction|Qual(QConstantQSProp)->"_sind"|Qual(QConstantQProp)->"_ind"|Qual(QConstantQType)|Qual(QVar_)->"_rect"|Set->"_rec"letmake_elimination_identids=Nameops.add_suffixid(elimination_suffixs)(* Look up function for the default elimination constant *)letlookup_eliminator_by_nameenvind_sps=letopenNamesinletopenEnvironinletkn,i=ind_spinletmpu=KerName.modpath@@MutInd.userkninletmpc=KerName.modpath@@MutInd.canonicalkninletind_id=(lookup_mindknenv).mind_packets.(i).mind_typenameinletid=make_elimination_identind_idsinletknu=KerName.makempuidinletknc=KerName.makempcidin(* Try first to get an eliminator defined in the same section as the *)(* inductive type *)letcst=Constant.makeknukncinifmem_constantcstenvthenGlobRef.ConstRefcstelse(* Then try to get a user-defined eliminator in some other places *)(* using short name (e.g. for "eq_rec") *)tryNametab.locate(Libnames.qualid_of_identid)withNot_found->CErrors.user_errPp.(strbrk"Cannot find the elimination combinator "++Id.printid++strbrk", the elimination of the inductive definition "++Nametab.pr_global_envId.Set.empty(GlobRef.IndRefind_sp)++strbrk" on sort "++UnivGen.QualityOrSet.prSorts.QVar.raw_prs++strbrk" is probably not allowed.")letdeprecated_lookup_by_name=CWarnings.create~name:"deprecated-lookup-elim-by-name"~category:Deprecation.Version.v9_2Pp.(fun(env,ind,to_kind,r)->letpp_scheme()s=str(scheme_kind_names)infmt"Found unregistered eliminator %t for %t by name.@ \
Use \"Register Scheme\" with it instead@ \
(\"as %a\" if dependent or \"as %a\" if non dependent)."(fun()->Termops.pr_global_envenvr)(fun()->Termops.pr_global_envenv(IndRefind))pp_scheme(elim_scheme~dep:true~to_kind)pp_scheme(elim_scheme~dep:false~to_kind))letlookup_eliminator_by_nameenvinds=letr=lookup_eliminator_by_nameenvindsindeprecated_lookup_by_name(env,ind,s,r);rletlookup_eliminatorenvinds=letnodep_scheme_first=(* compat, add an option to control this and remove someday *)let_,mip=Inductive.lookup_mind_specifenvindinSorts.is_propmip.mind_sort&¬(is_prop_but_default_dependent_elimind)inletschemes=List.map(fundep->elim_scheme~dep~to_kind:s)(ifnodep_scheme_firstthen[false;true]else[true;false])inmatchList.find_map(funscheme->lookup_schemeschemeind)schemeswith|Somec->c|None->(* XXX also lookup_scheme at less precise sort? eg if s=set try to_kind:qtype *)lookup_eliminator_by_nameenvinds(* **************************************************** *)(* Case Analysis *)(* **************************************************** *)letbuild_case_analysis_scheme_in_typeenvdepsortind=letsigma=Evd.from_envenvinlet(sigma,indu)=Evd.fresh_inductive_instanceenvsigmaindinletsigma,sort=Evd.fresh_sort_in_quality~rigid:UnivRigidsigmasortinlet(sigma,c,_)=build_case_analysis_schemeenvsigmaindudepsortinEConstr.Unsafe.to_constrc,Evd.ustatesigmaletcase_dep=declare_individual_scheme_object"case_dep"(funenv_x->build_case_analysis_scheme_in_typeenvtrueQualityOrSet.qtypex)letcase_nodep=declare_individual_scheme_object"case_nodep"(funenv_x->build_case_analysis_scheme_in_typeenvfalseQualityOrSet.qtypex)letcasep_dep=declare_individual_scheme_object"casep_dep"(funenv_x->build_case_analysis_scheme_in_typeenvtrueQualityOrSet.propx)letcasep_nodep=declare_individual_scheme_object"casep_nodep"(funenv_x->build_case_analysis_scheme_in_typeenvfalseQualityOrSet.propx)