123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269(************************************************************************)(* * 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) *)(************************************************************************)openCErrorsopenUtilopenNamesopenContextopenConstrinternopenImpargsopenPretypingmoduleNamedDecl=Context.Named.Declaration(* 2| Variable/Hypothesis/Parameter/Axiom declarations *)(** Declares a local variable/let, possibly declaring it:
- as a coercion (is_coe)
- as a type class instance
- with implicit arguments (impls)
- with implicit status for discharge (impl)
- virtually with named universes *)letdeclare_local~coe~try_assum_as_instance~kind~univs~impargs~impl~namebodytyp=letdecl=matchbodywith|None->Declare.SectionLocalAssum{typ;impl;univs}|Someb->Declare.SectionLocalDef{clearbody=(* TODO *)false;entry=Declare.definition_entry~univs~types:typb}inlet()=Declare.declare_variable~name~kind~typing_flags:Nonedeclinlet()=ifbody=NonethenDeclare.assumption_messagenameelseDeclare.definition_messagenameinletr=GlobRef.VarRefnameinlet()=maybe_declare_manual_implicitstruerimpargsinlet_=iftry_assum_as_instance&&Option.is_emptybodythenletenv=Global.env()inletsigma=Evd.from_envenvinClasses.declare_instanceenvsigmaNoneHints.Localrinlet()=ifcoe=Vernacexpr.AddCoercionthenComCoercion.try_add_new_coercionr~local:true~reversible:falsein(r,UVars.Instance.empty)letdeclare_variable~coe~kind~univs~impargs~impl~nametyp=declare_local~coe~try_assum_as_instance:true~kind:(Decls.IsAssumptionkind)~univs~impargs~impl~nameNonetypletinstance_of_univ_entry=function|UState.Polymorphic_entryunivs->UVars.UContext.instanceunivs|UState.Monomorphic_entry_->UVars.Instance.empty(** Declares a global axiom/parameter, possibly declaring it:
- as a coercion
- as a type class instance
- with implicit arguments
- with inlining for functor application
- with named universes *)letdeclare_global~coe~try_assum_as_instance~local~kind?user_warns~univs~impargs~inline~namebodytyp=let(uentry,ubinders)=univsinletinl=letopenDeclaremodsinmatchinlinewith|NoInline->None|DefaultInline->Some(Flags.get_inline_level())|InlineAti->Someiinletdecl=matchbodywith|None->Declare.ParameterEntry(Declare.parameter_entry~univs:(uentry,ubinders)?inline:inltyp)|Someb->Declare.DefinitionEntry(Declare.definition_entry~univs~types:typb)inletkn=Declare.declare_constant~name~local~kind?user_warnsdeclinletgr=GlobRef.ConstRefkninlet()=maybe_declare_manual_implicitsfalsegrimpargsinlet()=matchbodywithNone->Declare.assumption_messagename|Some_->Declare.definition_messagenameinletlocal=matchlocalwith|Locality.ImportNeedQualified->true|Locality.ImportDefaultBehavior->falseinlet()=iftry_assum_as_instance&&Option.is_emptybodythen(* why local when is_modtype? *)letenv=Global.env()inletsigma=Evd.from_envenvinClasses.declare_instanceenvsigmaNoneHints.SuperGlobalgrinlet()=ifcoe=Vernacexpr.AddCoercionthenComCoercion.try_add_new_coerciongr~local~reversible:falseinletinst=instance_of_univ_entryuentryin(gr,inst)letdeclare_axiom~coe~local~kind?user_warns~univs~impargs~inline~nametyp=declare_global~coe~try_assum_as_instance:false~local~kind:(Decls.IsAssumptionkind)?user_warns~univs~impargs~inline~nameNonetypletinterp_assumption~program_modeenvsigmaimpl_envblc=letflags={Pretyping.all_no_fail_flagswithprogram_mode}inletsigma,(impls,((env_bl,ctx),impls1))=interp_context_evars~program_mode~impl_envenvsigmablinletsigma,(ty,impls2)=interp_type_evars_impls~flagsenv_blsigma~implscinletty=EConstr.it_mkProd_or_LetIntyctxinsigma,ty,impls1@impls2letempty_poly_univ_entry=UState.Polymorphic_entryUVars.UContext.empty,UnivNames.empty_bindersletempty_mono_univ_entry=UState.Monomorphic_entryUniv.ContextSet.empty,UnivNames.empty_bindersletempty_univ_entrypoly=ifpolythenempty_poly_univ_entryelseempty_mono_univ_entryletclear_univsscopeuniv=matchscope,univwith|Locality.Global_,(UState.Polymorphic_entry_,_asunivs)->univs|_,(UState.Monomorphic_entry_,_)->empty_univ_entryfalse|Locality.Discharge,(UState.Polymorphic_entry_,_)->empty_univ_entrytrueletcontext_substsubst(id,b,t,infos)=id,Option.map(Vars.replace_varssubst)b,Vars.replace_varssubstt,infosletdeclare_context~try_global_assum_as_instance~scope~univs?user_warns~inlinectx=letfnisubstd=let(name,b,t,(impl,kind,coe,impargs))=context_substsubstdinletunivs=ifi=0thenunivselseclear_univsscopeunivsinletrefu=matchscopewith|Locality.Discharge->declare_local~coe~try_assum_as_instance:true~kind~univs~impargs~impl~namebt|Locality.Globallocal->declare_global~coe~try_assum_as_instance:try_global_assum_as_instance~local~kind?user_warns~univs~impargs~inline~namebtin(name,Constr.mkRefrefu)::substinlet_=List.fold_left_ifn0[]ctxin()leterror_extra_universe_decl?loc()=user_err?locPp.(strbrk"When declaring multiple assumptions in one command, "++strbrk"only the first name is allowed to mention a universe binder "++strbrk"(which will be shared by the whole block).")letextract_assumption_names=function|({CAst.loc;v=id},Some_)->error_extra_universe_decl?loc()|(id,None)->idletprocess_assumptions_udecls=function|(coe,((id,udecl)::ids,c))::assums->letids=List.mapextract_assumption_namesidsinletassums=List.map(fun(coe,(idl,c))->(coe,(List.mapextract_assumption_namesidl,c)))assumsinudecl,(coe,(id::ids,c))::assums|(_,([],_))::_|[]->assertfalseleterror_polymorphic_section_variable?loc()=user_err?loc(Pp.str"Section variables cannot be polymorphic.")letprocess_assumptions_no_udeclsl=List.map(fun(coe,(ids,c))->(coe,(List.map(function|({CAst.loc},Some_)->error_polymorphic_section_variable?loc()|(id,None)->id)ids,c)))lletextract_manual_implicite=CAst.make(matchewith|Some{impl_pos=(na,_,_);impl_expl=Manual;impl_max=max}->Some(na,max)|Some{impl_expl=(DepFlexAndRigid_|DepFlex_|DepRigid_)}|None->None)letfind_implicitsidienv=tryletimpls=implicits_of_decl_in_internalization_envidienvinList.mapextract_manual_implicitimplswithNot_found->[]letlocal_binders_of_decls~polyl=letcoercions,l=List.fold_left_map(funcoercions(is_coe,(idl,c))->letcoercions=matchis_coewith|Vernacexpr.NoCoercion->coercions|Vernacexpr.AddCoercion->List.fold_right(funid->Id.Set.addid.CAst.v)idlcoercionsinletmake_nameid=CAst.make?loc:id.CAst.loc(Nameid.CAst.v)inletmake_assumidl=Constrexpr.(CLocalAssum(List.mapmake_nameidl,None,DefaultGlob_term.Explicit,c))inletdecl=ifpolythen(* Separate declarations so that A B : Type puts A and B in different levels. *)List.map(funid->make_assum[id])idlelse[make_assumidl]in(coercions,decl))Id.Set.emptylincoercions,List.flattenlletfind_binding_kindidimpls=letopenGlob_terminletfindx=matchx.CAst.vwith|Some(Nameid',max)whenId.equalidid'->Some(ifmaxthenMaxImplicitelseNonMaxImplicit)|_->NoneinOption.defaultExplicit(CList.find_mapfindimpls)letinterp_context_gen~program_mode~kind~share~autoimp_enable~coercionsenvsigmal=letsigma,(ienv,((env,ctx),impls))=interp_named_context_evars~program_mode~share~autoimp_enableenvsigmalin(* Note, we must use the normalized evar from now on! *)letsigma=solve_remaining_evarsall_and_fail_flagsenvsigmainletsigma,ctx=Evarutil.finalizesigma@@funnf->List.map(NamedDecl.map_constr_het(funx->x)nf)ctxin(* reorder, evar-normalize and add implicit status *)letctx=List.rev_map(fund->let{binder_name=id},b,t=NamedDecl.to_tupledinletimpl=find_binding_kindidimplsinletkind=Decls.(ifb=NonethenIsAssumptionkindelseIsDefinition(matchkindwithContext->LetContext|_->Let))inletis_coe=ifId.Set.memidcoercionsthenVernacexpr.AddCoercionelseVernacexpr.NoCoercioninletimpls=ifautoimp_enablethenfind_implicitsidienvelse[]inletdata=(impl,kind,is_coe,impls)in(id,b,t,data))ctxinsigma,ctxletdo_assumptions~program_mode~poly~scope~kind?user_warns~inlinel=letsec=Lib.sections_are_opened()inifDumpglob.dump()thenbeginList.iter(fun(_,(idl,_))->List.iter(fun(lid,_)->letty=ifsecthen"var"else"ax"inDumpglob.dump_definitionlidsecty)idl)lend;letenv=Global.env()inletudecl,l=matchscopewith|Locality.Globalimport_behavior->process_assumptions_udeclsl|Locality.Discharge->None,process_assumptions_no_udeclslinletsigma,udecl=interp_univ_decl_optenvudeclinletcoercions,ctx=local_binders_of_decls~polylinletsigma,ctx=interp_context_gen~program_mode~kind~share:true~autoimp_enable:true~coercionsenvsigmactxinletunivs=Evd.check_univ_decl~polysigmaudeclindeclare_context~try_global_assum_as_instance:false~scope~univs?user_warns~inlinectxletwarn_context_outside_section=CWarnings.create~name:"context-outside-section"~category:CWarnings.CoreCategories.vernacular~default:CWarnings.AsErrorPp.(fun()->strbrk"Use of \"Context\" outside sections behaves \
as \"#[local] Parameter\" or \"#[local] \
Axiom\" followed by \"Existing Instance\" \
for typeclasses.")letdo_context~program_mode~polyctx=letsec=Lib.sections_are_opened()inifnotsecthenwarn_context_outside_section();ifDumpglob.dump()thenbeginletl=List.map(function|Constrexpr.CLocalAssum(l,_,_,_)->letty=ifsecthen"var "else"ax"inList.map(funn->ty,n)l|Constrexpr.CLocalDef(n,_,_,_)->letty=ifsecthen"var "else"def"in[ty,n]|Constrexpr.CLocalPattern_->[])ctxinList.iter(function|ty,{CAst.v=Names.Name.Anonymous;_}->()|ty,{CAst.v=Names.Name.Nameid;loc}->Dumpglob.dump_definition(CAst.make?locid)secty)(List.flattenl)end;letenv=Global.env()inletsigma=Evd.from_envenvinletscope=letopenLocalityinifsecthenDischargeelseGlobal(ifLib.is_modtype()thenImportDefaultBehaviorelseImportNeedQualified)inletsigma,ctx=interp_context_gen~program_mode~kind:Context~share:false~autoimp_enable:false~coercions:Id.Set.emptyenvsigmactxinletunivs=Evd.univ_entry~polysigmaindeclare_context~try_global_assum_as_instance:true~scope~univs~inline:Declaremods.NoInlinectx(* API compatibility (used in Elpi) *)letinterp_contextenvsigmactx=letreverse_rel_context_of_reverse_named_contextctx=List.rev(snd(List.fold_left_i(funn(subst,ctx)(id,b,t,impl)->letdecl=(id,Option.map(Vars.subst_varssubst)b,Vars.subst_varssubstt,impl)in(id::subst,decl::ctx))1([],[])ctx))inletsigma,ctx=interp_context_gen~program_mode:false~kind:Context~share:false~autoimp_enable:false~coercions:Id.Set.emptyenvsigmactxinletctx=List.map(fun(id,b,t,(impl,_,_,_))->(id,b,t,impl))ctxinsigma,reverse_rel_context_of_reverse_named_contextctx