123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173(************************************************************************)(* * 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) *)(************************************************************************)openNamesopenUniv(* 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={udecl_src:universe_source;udecl_named:(Id.t*UGlobal.t)list;udecl_anon:UGlobal.tlist;}letcheck_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_universeispunivletget_namesdecl=letfoldaccu(id,_)=Id.Set.addidaccuinletnames=List.fold_leftfoldId.Set.emptydecl.udecl_namedin(* create fresh names for anonymous universes *)letfoldu((names,cnt),accu)=letrecauxi=letna=Id.of_string("u"^(string_of_inti))inifId.Set.memnanamesthenaux(i+1)else(na,i)inlet(id,cnt)=auxcntin((Id.Set.addidnames,cnt+1),((id,u)::accu))inlet_,univs=List.fold_rightfolddecl.udecl_anon((names,0),decl.udecl_named)inunivsletcache_univ_names(prefix,decl)=letdepth=Lib.sections_depth()inletdp=Libnames.pop_dirpath_ndepthprefix.Nametab.obj_dirinletnames=get_namesdeclinList.iter(do_univ_name~check:true(Nametab.Until1)dpdecl.udecl_src)namesletload_univ_namesi(prefix,decl)=letnames=get_namesdeclinList.iter(do_univ_name~check:false(Nametab.Untili)prefix.Nametab.obj_dirdecl.udecl_src)namesletopen_univ_namesi(prefix,decl)=letnames=get_namesdeclinList.iter(do_univ_name~check:false(Nametab.Exactlyi)prefix.Nametab.obj_dirdecl.udecl_src)namesletdischarge_univ_namesdecl=matchdecl.udecl_srcwith|BoundUniv->None|(QualifiedUniv_|UnqualifiedUniv)->Somedeclletinput_univ_names:universe_name_decl->Libobject.obj=letopenLibobjectindeclare_named_object_gen{(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->Substitute)}letinput_univ_names(src,l,a)=ifCList.is_emptyl&&CList.is_emptyathen()elseLib.add_leaf(input_univ_names{udecl_src=src;udecl_named=l;udecl_anon=a})letlabel_of=letopenGlobRefinfunction|ConstRefc->Label.to_id@@Constant.labelc|IndRef(c,_)->Label.to_id@@MutInd.labelc|VarRefid->id|ConstructRef_->CErrors.anomaly~label:"declare_univ_binders"Pp.(str"declare_univ_binders on a constructor reference")letdeclare_univ_bindersgr(univs,pl)=letl=label_ofgrinmatchunivswith|UState.Polymorphic_entry_->()|UState.Monomorphic_entry(levels,_)->letqs,pl=plinassert(Id.Map.is_emptyqs);(* First the explicitly named universes *)letnamed,univs=Id.Map.fold(funiduniv(named,univs)->letunivs=matchLevel.nameunivwith|None->assertfalse(* having Prop/Set/Var as binders is nonsense *)|Someuniv->(id,univ)::univsinletnamed=Level.Set.addunivnamedinnamed,univs)pl(Level.Set.empty,[])in(* then keep the anonymous ones *)letfolduaccu=Option.get(Level.nameu)::accuinletanonymous=Level.Set.foldfold(Level.Set.difflevelsnamed)[]ininput_univ_names(QualifiedUnivl,univs,anonymous)letdo_universe~polyl=letin_section=Lib.sections_are_opened()inlet()=ifpoly&¬in_sectionthenCErrors.user_err(Pp.str"Cannot declare polymorphic universes outside sections.")inletl=List.map(fun{CAst.v=id}->(id,UnivGen.new_univ_global()))linletsrc=ifpolythenBoundUnivelseUnqualifiedUnivinlet()=input_univ_names(src,l,[])inmatchpolywith|false->letctx=List.fold_left(functx(_,qid)->Level.Set.add(Level.makeqid)ctx)Level.Set.emptyl,Constraints.emptyinGlobal.push_context_set~strict:truectx|true->letnames=CArray.map_of_list(fun(na,_)->Namena)linletus=CArray.map_of_list(fun(_,l)->Level.makel)linletctx=UVars.UContext.make([||],names)(UVars.Instance.of_array([||],us),Constraints.empty)inGlobal.push_section_contextctxletdo_constraint~polyl=letopenUnivinletevd=Evd.from_env(Global.env())inletconstraints=List.fold_left(funacccst->letcst=Constrintern.interp_univ_constraintevdcstinConstraints.addcstacc)Constraints.emptylinmatchpolywith|false->letuctx=ContextSet.add_constraintsconstraintsContextSet.emptyinGlobal.push_context_set~strict:trueuctx|true->letuctx=UVars.UContext.make([||],[||])(UVars.Instance.empty,constraints)inGlobal.push_section_contextuctx