123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285(************************************************************************)(* * 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) *)(************************************************************************)openCErrorsopenUtilopenVarsopenNamesopenContextopenConstrinternopenImpargsopenPretypingopenEntriesmoduleRelDecl=Context.Rel.Declaration(* 2| Variable/Hypothesis/Parameter/Axiom declarations *)letdeclare_variableis_coe~kindtypimpsimpl{CAst.v=name}=letkind=Decls.IsAssumptionkindinlet()=Declare.declare_variable~name~kind~typ~implinlet()=Declare.assumption_messagenameinletr=GlobRef.VarRefnameinlet()=maybe_declare_manual_implicitstruerimpsinletenv=Global.env()inletsigma=Evd.from_envenvinlet()=Classes.declare_instanceenvsigmaNoneGoptions.OptLocalrinlet()=ifis_coethenComCoercion.try_add_new_coercionr~local:true~poly:falsein()letinstance_of_univ_entry=function|Polymorphic_entry(_,univs)->Univ.UContext.instanceunivs|Monomorphic_entry_->Univ.Instance.emptyletdeclare_axiomis_coe~poly~local~kindtyp(univs,pl)impsnl{CAst.v=name}=letdo_instance=letopenDeclsinmatchkindwith|Context->true(* The typeclass behaviour of Variable and Context doesn't depend
on section status *)|Definitional|Logical|Conjectural->falseinletinl=letopenDeclaremodsinmatchnlwith|NoInline->None|DefaultInline->Some(Flags.get_inline_level())|InlineAti->Someiinletkind=Decls.IsAssumptionkindinletdecl=Declare.ParameterEntry(None,(typ,univs),inl)inletkn=Declare.declare_constant~name~local~kinddeclinletgr=GlobRef.ConstRefkninlet()=maybe_declare_manual_implicitsfalsegrimpsinlet()=DeclareUniv.declare_univ_bindersgrplinlet()=Declare.assumption_messagenameinletenv=Global.env()inletsigma=Evd.from_envenvinlet()=ifdo_instancethenClasses.declare_instanceenvsigmaNoneGoptions.OptGlobalgrinletlocal=matchlocalwith|Locality.ImportNeedQualified->true|Locality.ImportDefaultBehavior->falseinlet()=ifis_coethenComCoercion.try_add_new_coerciongr~local~polyinletinst=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@impls2(* When monomorphic the universe constraints and universe names are
declared with the first declaration only. *)letnext_univs=letempty_univs=Monomorphic_entryUniv.ContextSet.empty,UnivNames.empty_bindersinfunction|Polymorphic_entry_,_asunivs->univs|Monomorphic_entry_,_->empty_univsletcontext_set_of_entry=function|Polymorphic_entry(_,uctx)->Univ.ContextSet.of_contextuctx|Monomorphic_entryuctx->uctxletdeclare_assumptions~poly~scope~kindunivsnll=let()=matchscopewith|Locality.Discharge->(* declare universes separately for variables *)DeclareUctx.declare_universe_context~poly(context_set_of_entry(fstunivs))|Locality.Global_->()inlet_,_=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~kindtypimpsGlob_term.Explicitid;GlobRef.VarRefid.CAst.v,Univ.Instance.empty|Locality.Globallocal->declare_axiomis_coe~local~poly~kindtypunivsimpsnlidinnext_univsunivs,(id.CAst.v,Constr.mkRefrefu))univsidlinsubst'@subst,next_univsunivs)([],univs)lin()letmaybe_error_many_udecls=function|({CAst.loc;v=id},Some_)->user_err?loc~hdr:"many_universe_declarations"Pp.(str"When declaring multiple axioms in one command, "++str"only the first is allowed a universe binder "++str"(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.LSet.unionuvars(Vars.universes_of_constrt)inuvars,(coe,t,imps))Univ.LSet.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~polysigmaudeclinletubinders=Evd.universe_binderssigmaindeclare_assumptions~poly~scope~kind(univs,ubinders)nllletcontext_substsubst(name,b,t,impl)=name,Option.map(Vars.substlsubst)b,Vars.substlsubstt,implletcontext_insectionsigma~polyctx=letuctx=Evd.universe_context_setsigmainlet()=DeclareUctx.declare_universe_context~polyuctxinletfnsubst(name,_,_,_asd)=letd=context_substsubstdinlet()=matchdwith|name,None,t,impl->letkind=Decls.Contextindeclare_variablefalse~kindt[]impl(CAst.makename)|name,Someb,t,impl->(* We need to get poly right for check_same_poly *)letunivs=ifpolythenPolymorphic_entry([||],Univ.UContext.empty)elseMonomorphic_entryUniv.ContextSet.emptyinletentry=Declare.definition_entry~univs~types:tbin(* XXX Fixme: Use Declare.prepare_definition *)letuctx=Evd.evar_universe_contextsigmainletkind=Decls.(IsDefinitionDefinition)inlet_:GlobRef.t=Declare.declare_entry~name~scope:Locality.Discharge~kind~impargs:[]~uctxentryin()inConstr.mkVarname::substinlet_:Vars.substl=List.fold_leftfn[]ctxin()letcontext_nosectionsigma~polyctx=letunivs=matchctx,polywith|[_],_|_,true->Evd.univ_entry~polysigma|_,false->(* Multiple monomorphic axioms: declare universes separately to
avoid redeclaring them. *)letuctx=Evd.universe_context_setsigmainlet()=DeclareUctx.declare_universe_context~polyuctxinMonomorphic_entryUniv.ContextSet.emptyinletfnsubstd=let(name,b,t,_impl)=context_substsubstdinletkind=Decls.(IsAssumptionLogical)inletdecl=matchbwith|None->Declare.ParameterEntry(None,(t,univs),None)|Someb->letentry=Declare.definition_entry~univs~types:tbinDeclare.DefinitionEntryentryinletlocal=ifLib.is_modtype()thenLocality.ImportDefaultBehaviorelseLocality.ImportNeedQualifiedinletcst=Declare.declare_constant~name~kind~localdeclinlet()=Declare.assumption_messagenameinletenv=Global.env()in(* why local when is_modtype? *)letlocality=ifLib.is_modtype()thenGoptions.OptLocalelseGoptions.OptGlobalinlet()=ifLib.is_modtype()||Option.is_emptybthenClasses.declare_instanceenvsigmaNonelocality(GlobRef.ConstRefcst)inConstr.mkConstU(cst,instance_of_univ_entryunivs)::substinlet_:Vars.substl=List.fold_leftfn[]ctxin()letcontext~polyl=letenv=Global.env()inletsigma=Evd.from_envenvinletsigma,(_,((_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.finalize~abort_on_undefined_evars:falsesigma(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)ctxinifGlobal.sections_are_opened()thencontext_insectionsigma~polyctxelsecontext_nosectionsigma~polyctx