123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271(************************************************************************)(* * 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) *)(************************************************************************)openCErrorsopenUtilopenVarsopenNamesopenContextopenConstrinternopenImpargsopenPretypingmoduleRelDecl=Context.Rel.Declaration(* 2| Variable/Hypothesis/Parameter/Axiom declarations *)letdeclare_variableis_coe~kindtypunivsimpsimpl{CAst.v=name}=letkind=Decls.IsAssumptionkindinlet()=Declare.declare_variable~name~kind~typ~impl~univsinlet()=Declare.assumption_messagenameinletr=GlobRef.VarRefnameinlet()=maybe_declare_manual_implicitstruerimpsinletenv=Global.env()inletsigma=Evd.from_envenvinlet()=Classes.declare_instanceenvsigmaNoneHints.Localrinlet()=ifis_coe=Vernacexpr.AddCoercionthenComCoercion.try_add_new_coercionr~local:true~poly:false~nonuniform:false~reversible:truein()letinstance_of_univ_entry=function|UState.Polymorphic_entryunivs->Univ.UContext.instanceunivs|UState.Monomorphic_entry_->Univ.Instance.emptyletdeclare_axiomis_coe~poly~local~kindtyp(univs,ubinders)impsnl{CAst.v=name}=letinl=letopenDeclaremodsinmatchnlwith|NoInline->None|DefaultInline->Some(Flags.get_inline_level())|InlineAti->Someiinletkind=Decls.IsAssumptionkindinletentry=Declare.parameter_entry~univs:(univs,ubinders)?inline:inltypinletdecl=Declare.ParameterEntryentryinletkn=Declare.declare_constant~name~local~kinddeclinletgr=GlobRef.ConstRefkninlet()=maybe_declare_manual_implicitsfalsegrimpsinlet()=Declare.assumption_messagenameinletlocal=matchlocalwith|Locality.ImportNeedQualified->true|Locality.ImportDefaultBehavior->falseinlet()=ifis_coe=Vernacexpr.AddCoercionthenComCoercion.try_add_new_coerciongr~local~poly~nonuniform:false~reversible:trueinletinst=instance_of_univ_entryunivsin(gr,inst)letinterp_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_entryUniv.UContext.empty,UnivNames.empty_bindersletempty_mono_univ_entry=UState.Monomorphic_entryUniv.ContextSet.empty,UnivNames.empty_bindersletempty_univ_entry~poly=ifpolythenempty_poly_univ_entryelseempty_mono_univ_entry(* When declarations are monomorphic (which is always the case in
sections, even when universes are treated as polymorphic variables)
the universe constraints and universe names are declared with the
first declaration only. *)letclear_univsscopeuniv=matchscope,univwith|Locality.Global_,(UState.Polymorphic_entry_,_asunivs)->univs|_,(UState.Monomorphic_entry_,_)->empty_univ_entry~poly:false|Locality.Discharge,(UState.Polymorphic_entry_,_)->empty_univ_entry~poly:trueletdeclare_assumptions~poly~scope~kindunivsnll=let_,_=List.fold_left(fun(subst,univs)((is_coe,idl),typ,imps)->(* NB: here univs are ignored when scope=Discharge *)lettyp=replace_varssubsttypinletunivs,subst'=List.fold_left_map(fununivsid->letrefu=matchscopewith|Locality.Discharge->declare_variableis_coe~kindtypunivsimpsGlob_term.Explicitid;GlobRef.VarRefid.CAst.v,Univ.Instance.empty|Locality.Globallocal->declare_axiomis_coe~local~poly~kindtypunivsimpsnlidinclear_univsscopeunivs,(id.CAst.v,Constr.mkRefrefu))univsidlinsubst'@subst,clear_univsscopeunivs)([],univs)lin()letmaybe_error_many_udecls=function|({CAst.loc;v=id},Some_)->user_err?locPp.(strbrk"When declaring multiple axioms in one command, "++strbrk"only the first is allowed a universe binder "++strbrk"(which will be shared by the whole block).")|(_,None)->()letprocess_assumptions_udecls~scopel=letudecl,first_id=matchlwith|(coe,((id,udecl)::rest,c))::rest'->List.itermaybe_error_many_udeclsrest;List.iter(fun(coe,(idl,c))->List.itermaybe_error_many_udeclsidl)rest';udecl,id|(_,([],_))::_|[]->assertfalseinlet()=matchscope,udeclwith|Locality.Discharge,Some_->letloc=first_id.CAst.locinletmsg=Pp.str"Section variables cannot be polymorphic."inuser_err?locmsg|_->()inudecl,List.map(fun(coe,(idl,c))->coe,(List.mapfstidl,c))lletdo_assumptions~program_mode~poly~scope~kindnll=letopenContext.Named.Declarationinletenv=Global.env()inletudecl,l=process_assumptions_udecls~scopelinletsigma,udecl=interp_univ_decl_optenvudeclinletl=ifpolythen(* Separate declarations so that A B : Type puts A and B in different levels. *)List.fold_right(fun(is_coe,(idl,c))acc->List.fold_right(funidacc->(is_coe,([id],c))::acc)idlacc)l[]elselin(* We interpret all declarations in the same evar_map, i.e. as a telescope. *)let(sigma,_,_),l=List.fold_left_map(fun(sigma,env,ienv)(is_coe,(idl,c))->letsigma,t,imps=interp_assumption~program_modeenvsigmaienv[]cinletr=Retyping.relevance_of_typeenvsigmatinletenv=EConstr.push_named_context(List.map(fun{CAst.v=id}->LocalAssum(make_annotidr,t))idl)envinletienv=List.fold_right(fun{CAst.v=id}ienv->letimpls=compute_internalization_dataenvsigmaidVariabletimpsinId.Map.addidimplsienv)idlienvin((sigma,env,ienv),((is_coe,idl),t,imps)))(sigma,env,empty_internalization_env)linletsigma=solve_remaining_evarsall_and_fail_flagsenvsigmain(* The universe constraints come from the whole telescope. *)letsigma=Evd.minimize_universessigmainletnf_evarc=EConstr.to_constrsigmacinletuvars,l=List.fold_left_map(funuvars(coe,t,imps)->lett=nf_evartinletuvars=Univ.Level.Set.unionuvars(Vars.universes_of_constrt)inuvars,(coe,t,imps))Univ.Level.Set.emptylin(* XXX: Using `Declare.prepare_parameter` here directly is not
possible as we indeed declare several parameters; however,
restrict_universe_context should be called in a centralized place
IMO, thus I think we should adapt `prepare_parameter` to handle
this case too. *)letsigma=Evd.restrict_universe_contextsigmauvarsinletunivs=Evd.check_univ_decl~polysigmaudeclindeclare_assumptions~poly~scope~kindunivsnllletcontext_substsubst(name,b,t,impl)=name,Option.map(Vars.substlsubst)b,Vars.substlsubstt,implletcontext_insectionsigma~polyctx=letuctx=Evd.evar_universe_contextsigmainletunivs=UState.univ_entry~polyuctxinletfnisubst(name,_,_,_asd)=letd=context_substsubstdinletunivs=ifi=0thenunivselseempty_univ_entry~polyinlet()=matchdwith|name,None,t,impl->letkind=Decls.Contextindeclare_variableNoCoercion~kindtunivs[]impl(CAst.makename)|name,Someb,t,impl->letentry=Declare.definition_entry~univs~types:tbin(* XXX Fixme: Use Declare.prepare_definition *)letkind=Decls.(IsDefinitionDefinition)inlet_:GlobRef.t=Declare.declare_entry~name~scope:Locality.Discharge~kind~impargs:[]~uctxentryin()inConstr.mkVarname::substinlet_:Vars.substl=List.fold_left_ifn0[]ctxin()letcontext_nosectionsigma~polyctx=let(univ_entry,ubindersasunivs)=Evd.univ_entry~polysigmainletfnisubstd=let(name,b,t,_impl)=context_substsubstdinletkind=Decls.(IsAssumptionLogical)inletlocal=ifLib.is_modtype()thenLocality.ImportDefaultBehaviorelseLocality.ImportNeedQualifiedin(* Multiple monomorphic axioms: declare universes only on the first declaration *)letunivs=ifi=0thenunivselseclear_univs(Locality.Globallocal)univsinletdecl=matchbwith|None->letentry=Declare.parameter_entry~univs:(univ_entry,ubinders)tinDeclare.ParameterEntryentry|Someb->letentry=Declare.definition_entry~univs~types:tbinDeclare.DefinitionEntryentryinletcst=Declare.declare_constant~name~kind~localdeclinlet()=Declare.assumption_messagenameinletenv=Global.env()in(* why local when is_modtype? *)letlocality=ifLib.is_modtype()thenHints.LocalelseHints.SuperGlobalinlet()=ifLib.is_modtype()||Option.is_emptybthenClasses.declare_instanceenvsigmaNonelocality(GlobRef.ConstRefcst)inConstr.mkConstU(cst,instance_of_univ_entryuniv_entry)::substinlet_:Vars.substl=List.fold_left_ifn0[]ctxin()letinterp_contextenvsigmal=letsigma,(_,((_env,ctx),impls))=interp_context_evars~program_mode:falseenvsigmalin(* Note, we must use the normalized evar from now on! *)letcet=Pretyping.check_evarsenvsigmatinlet()=List.iter(fundecl->Context.Rel.Declaration.iter_constrcedecl)ctxinletsigma,ctx=Evarutil.finalizesigma(funnf->List.map(RelDecl.map_constr_hetnf)ctx)in(* reorder, evar-normalize and add implicit status *)letctx=List.rev_map(fund->let{binder_name=name},b,t=RelDecl.to_tupledinletname=matchnamewith|Anonymous->user_errPp.(str"Anonymous variables not allowed in contexts.")|Nameid->idinletimpl=letopenGlob_terminletsearchx=matchx.CAst.vwith|Some(Nameid',max)whenId.equalnameid'->Some(ifmaxthenMaxImplicitelseNonMaxImplicit)|_->NoneintryCList.find_mapsearchimplswithNot_found->Explicitinname,b,t,impl)ctxinsigma,ctxletdo_context~polyl=letenv=Global.env()inletsigma=Evd.from_envenvinletsigma,ctx=interp_contextenvsigmalinifGlobal.sections_are_opened()thencontext_insectionsigma~polyctxelsecontext_nosectionsigma~polyctx