123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154(************************************************************************)(* * 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) *)(************************************************************************)openNamesopenDeclarationsopenUniv(* object_kind , id *)exceptionAlreadyDeclaredof(stringoption*Id.t)let_=CErrors.register_handler(function|AlreadyDeclared(kind,id)->SomePp.(seq[Pp.pr_opt_no_spc(funs->strs++spc())kind;Id.printid;str" already exists."])|_->None)typeuniverse_source=|BoundUniv(* polymorphic universe, bound in a function (this will go away someday) *)|QualifiedUnivofId.t(* global universe introduced by some global value *)|UnqualifiedUniv(* other global universe *)typeuniverse_name_decl=universe_source*(Id.t*Univ.Level.UGlobal.t)listletcheck_exists_universesp=ifNametab.exists_universespthenraise(AlreadyDeclared(Some"Universe",Libnames.basenamesp))else()letqualify_unividpsrcid=matchsrcwith|BoundUniv|UnqualifiedUniv->i,Libnames.make_pathdpid|QualifiedUnivl->letdp=DirPath.reprdpinNametab.map_visibilitysucci,Libnames.make_path(DirPath.make(l::dp))idletdo_univ_name~checkidpsrc(id,univ)=leti,sp=qualify_unividpsrcidinifcheckthencheck_exists_universesp;Nametab.push_universeispunivletcache_univ_names((sp,_),(src,univs))=letdepth=Lib.sections_depth()inletdp=Libnames.pop_dirpath_ndepth(Libnames.dirpathsp)inList.iter(do_univ_name~check:true(Nametab.Until1)dpsrc)univsletload_univ_namesi((sp,_),(src,univs))=List.iter(do_univ_name~check:false(Nametab.Untili)(Libnames.dirpathsp)src)univsletopen_univ_namesi((sp,_),(src,univs))=List.iter(do_univ_name~check:false(Nametab.Exactlyi)(Libnames.dirpathsp)src)univsletdischarge_univ_names=function|_,(BoundUniv,_)->None|_,((QualifiedUniv_|UnqualifiedUniv),_asx)->Somexletinput_univ_names:universe_name_decl->Libobject.obj=letopenLibobjectindeclare_object{(default_object"Global universe name state")withcache_function=cache_univ_names;load_function=load_univ_names;open_function=simple_openopen_univ_names;discharge_function=discharge_univ_names;subst_function=(fun(subst,a)->(* Actually the name is generated once and for all. *)a);classify_function=(funa->Substitutea)}letinput_univ_names(src,l)=ifCList.is_emptylthen()elseLib.add_anonymous_leaf(input_univ_names(src,l))letinvent_name(named,cnt)u=letrecauxi=letna=Id.of_string("u"^(string_of_inti))inifId.Map.memnanamedthenaux(i+1)elsena,(Id.Map.addnaunamed,i+1)inauxcntletlabel_and_univs_of=letopenGlobRefinfunction|ConstRefc->letl=Label.to_id@@Constant.labelcinletunivs=(Global.lookup_constantc).const_universesinl,univs|IndRef(c,_)->letl=Label.to_id@@MutInd.labelcinletunivs=(Global.lookup_mindc).mind_universesinl,univs|VarRefid->CErrors.anomaly~label:"declare_univ_binders"Pp.(str"declare_univ_binders on variable "++Id.printid++str".")|ConstructRef_->CErrors.anomaly~label:"declare_univ_binders"Pp.(str"declare_univ_binders on a constructor reference")letdeclare_univ_bindersgrpl=letl,univs=label_and_univs_ofgrinmatchunivswith|Polymorphic_->()|Monomorphic(levels,_)->(* First the explicitly named universes *)letnamed,univs=Id.Map.fold(funiduniv(named,univs)->letunivs=matchUniv.Level.nameunivwith|None->assertfalse(* having Prop/Set/Var as binders is nonsense *)|Someuniv->(id,univ)::univsinletnamed=LSet.addunivnamedinnamed,univs)pl(LSet.empty,[])in(* then invent names for the rest *)let_,univs=LSet.fold(fununiv(aux,univs)->letid,aux=invent_nameauxunivinletuniv=Option.get(Level.nameuniv)inaux,(id,univ)::univs)(LSet.difflevelsnamed)((pl,0),univs)ininput_univ_names(QualifiedUnivl,univs)letdo_universe~polyl=letin_section=Global.sections_are_opened()inlet()=ifpoly&¬in_sectionthenCErrors.user_err~hdr:"Constraint"(Pp.str"Cannot declare polymorphic universes outside sections")inletl=List.map(fun{CAst.v=id}->(id,UnivGen.new_univ_global()))linletctx=List.fold_left(functx(_,qid)->Univ.LSet.add(Univ.Level.makeqid)ctx)Univ.LSet.emptyl,Univ.Constraint.emptyinletsrc=ifpolythenBoundUnivelseUnqualifiedUnivinlet()=input_univ_names(src,l)inDeclareUctx.declare_universe_context~polyctxletdo_constraint~polyl=letopenUnivinletevd=Evd.from_env(Global.env())inletu_of_idx=Constrintern.interp_known_levelevdxinletconstraints=List.fold_left(funacc(l,d,r)->letlu=u_of_idlandru=u_of_idrinConstraint.add(lu,d,ru)acc)Constraint.emptylinletuctx=ContextSet.add_constraintsconstraintsContextSet.emptyinDeclareUctx.declare_universe_context~polyuctx