123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201(************************************************************************)(* * The Rocq Prover / The Rocq 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.tlist(* global universe introduced by some global value *)|UnqualifiedUniv(* other global universe, todo merge with [QualifiedUniv []] *)typeuniverse_name_decl=universe_source*(Id.t*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_visibility(funn->n+List.lengthl)i,Libnames.make_path(DirPath.make(List.appendldp))idletdo_univ_name~checkidpsrc(id,univ)=leti,sp=qualify_unividpsrcidinifcheckthencheck_exists_universesp;Nametab.push_universeispunivletcache_univ_names(prefix,(src,univs))=letdepth=Lib.sections_depth()inletdp=Libnames.pop_dirpath_ndepthprefix.Nametab.obj_dirinList.iter(do_univ_name~check:true(Nametab.Until1)dpsrc)univsletload_univ_namesi(prefix,(src,univs))=List.iter(do_univ_name~check:false(Nametab.Untili)prefix.Nametab.obj_dirsrc)univsletopen_univ_namesi(prefix,(src,univs))=List.iter(do_univ_name~check:false(Nametab.Exactlyi)prefix.Nametab.obj_dirsrc)univsletdischarge_univ_names=function|BoundUniv,_->None|(QualifiedUniv_|UnqualifiedUniv),_asx->Somexletinput_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;classify_function=(fun_->Escape)}letinput_univ_names(src,l)=ifCList.is_emptylthen()elseLib.add_leaf(input_univ_names(src,l))letinvent_nameprefix(named,cnt)u=letrecauxi=letna=Id.of_string("u"^(string_of_inti))inletsp=Libnames.make_pathprefixnainifId.Map.memnanamed||Nametab.exists_universespthenaux(i+1)elsena,(Id.Map.addnaunamed,i+1)inauxcntletlabel_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 invent names for the rest *)letprefix=DirPath.make(l::DirPath.repr(Lib.cwd_except_section()))inlet_,univs=Level.Set.fold(fununiv(aux,univs)->letid,aux=invent_nameprefixauxunivinletuniv=Option.get(Level.nameuniv)inaux,(id,univ)::univs)(Level.Set.difflevelsnamed)((pl,0),univs)ininput_univ_names(QualifiedUniv[l],univs)letname_mono_section_univsunivs=ifLevel.Set.is_emptyunivsthen()elseletprefix=Lib.cwd()inletsections=DirPath.repr@@Libnames.drop_dirpath_prefix(Lib.cwd_except_section())prefixinlet_,univs=Level.Set.fold(fununiv(aux,univs)->letid,aux=invent_nameprefixauxunivinletuniv=Option.get(Level.nameuniv)inaux,(id,univ)::univs)univs((Id.Map.empty,0),[])ininput_univ_names(QualifiedUnivsections,univs)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_setctx|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_setuctx|true->letuctx=UVars.UContext.make([||],[||])(UVars.Instance.empty,constraints)inGlobal.push_section_contextuctxletconstraint_sources=Summary.ref~name:"univ constraint sources"[]letcache_constraint_sourcex=constraint_sources:=x::!constraint_sourcesletconstraint_sources()=!constraint_sourcesletconstraint_obj=Libobject.declare_object{(Libobject.default_object"univ constraint sources")withcache_function=cache_constraint_source;load_function=(fun_c->cache_constraint_sourcec);discharge_function=(funx->Somex);classify_function=(fun_->Escape);}(* XXX this seems like it could be merged with declare_univ_binders
main issue is the filtering or redundant constraints (needed for perf / smaller vo file sizes) *)letadd_constraint_sourcexctx=let_,csts=ctxinifUniv.Constraints.is_emptycststhen()elseletv=x,cstsinLib.add_leaf(constraint_objv)