123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167(************************************************************************)(* * 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) *)(************************************************************************)openSortsopenNamesopenConstropenUnivopenUVarstypesort_context_set=(Sorts.QVar.Set.t*Univ.Level.Set.t)*Univ.Constraints.ttype'ain_sort_context_set='a*sort_context_setletempty_sort_context=(QVar.Set.empty,Level.Set.empty),Constraints.emptyletis_empty_sort_context((qs,us),csts)=QVar.Set.is_emptyqs&&Level.Set.is_emptyus&&Constraints.is_emptycstsletsort_context_union((qs,us),csts)((qs',us'),csts')=((QVar.Set.unionqsqs',Level.Set.unionusus'),Constraints.unioncstscsts')letdiff_sort_context((qs,us),csts)((qs',us'),csts')=(QVar.Set.diffqsqs',Level.Set.diffusus'),Constraints.diffcstscsts'typeuniv_length_mismatch={actual:int*int;expect:int*int;}(* Due to an OCaml bug ocaml/ocaml#10027 inlining this record will cause
compliation with -rectypes to crash. *)exceptionUniverseLengthMismatchofuniv_length_mismatchlet()=CErrors.register_handler(function|UniverseLengthMismatch{actual=(aq,au);expect=(eq,eu)}->letppreal,ppexpected=ifaq=0&&eq=0thenPp.(intau,inteu)elsePp.(str"("++intaq++str" | "++intau++str")",str"("++inteq++str" | "++inteu++str")")inSomePp.(str"Universe instance length is "++ppreal++str" but should be "++ppexpected++str".")|_->None)(* Generator of levels *)letnew_univ_id=letcnt=ref0infun()->incrcnt;!cntletnew_univ_global()=lets=ifFlags.async_proofs_is_worker()then!Flags.async_proofs_worker_idelse""inUniv.UGlobal.make(Global.current_dirpath())s(new_univ_id())letfresh_level()=Univ.Level.make(new_univ_global())letnew_sort_id=letcnt=ref0infun()->incrcnt;!cntletnew_sort_global()=lets=ifFlags.async_proofs_is_worker()then!Flags.async_proofs_worker_idelse""inSorts.QVar.make_unifs(new_sort_id())letfresh_instanceauctx:_in_sort_context_set=letqlen,ulen=AbstractContext.sizeauctxinletqinst=Array.initqlen(fun_->Sorts.Quality.QVar(new_sort_global()))inletuinst=Array.initulen(fun_->fresh_level())inletqctx=Array.fold_left(funqctxq->matchqwith|Sorts.Quality.QVarq->Sorts.QVar.Set.addqqctx|_->assertfalse)Sorts.QVar.Set.emptyqinstinletuctx=Array.fold_rightLevel.Set.adduinstLevel.Set.emptyinletinst=Instance.of_array(qinst,uinst)ininst,((qctx,uctx),AbstractContext.instantiateinstauctx)letexisting_instance?locauctxinst=let()=letactual=Instance.lengthinstandexpect=AbstractContext.sizeauctxinifnot(UVars.eq_sizesactualexpect)thenLoc.raise?loc(UniverseLengthMismatch{actual;expect})else()ininst,((Sorts.QVar.Set.empty,Level.Set.empty),AbstractContext.instantiateinstauctx)letfresh_instance_from?locctx=function|Someinst->existing_instance?locctxinst|None->fresh_instancectx(** Fresh universe polymorphic construction *)letfresh_global_instance?loc?namesenvgr=letauctx=Environ.universes_of_globalenvgrinletu,ctx=fresh_instance_from?locauctxnamesinu,ctxletfresh_constant_instanceenvc=letu,ctx=fresh_global_instanceenv(GlobRef.ConstRefc)in(c,u),ctxletfresh_inductive_instanceenvind=letu,ctx=fresh_global_instanceenv(GlobRef.IndRefind)in(ind,u),ctxletfresh_constructor_instanceenvc=letu,ctx=fresh_global_instanceenv(GlobRef.ConstructRefc)in(c,u),ctxletfresh_array_instanceenv=letauctx=CPrimitives.typ_univsCPrimitives.PT_arrayinletu,ctx=fresh_instance_fromauctxNoneinu,ctxletfresh_global_instance?loc?namesenvgr=letu,ctx=fresh_global_instance?loc?namesenvgrinmkRef(gr,u),ctxletconstr_of_monomorphic_globalenvgr=ifnot(Environ.is_polymorphicenvgr)thenfst(fresh_global_instanceenvgr)elseCErrors.user_errPp.(str"globalization of polymorphic reference "++Nametab.pr_global_envId.Set.emptygr++str" would forget universes.")letfresh_sort_in_family=function|InSProp->Sorts.sprop,empty_sort_context|InProp->Sorts.prop,empty_sort_context|InSet->Sorts.set,empty_sort_context|InType|InQSort(* Treat as Type *)->letu=fresh_level()insort_of_univ(Univ.Universe.makeu),((QVar.Set.empty,Level.Set.singletonu),Constraints.empty)letnew_global_univ()=letu=fresh_level()in(Univ.Universe.makeu,ContextSet.singletonu)letfresh_universe_context_set_instancectx=ifContextSet.is_emptyctxthenLevel.Map.empty,ctxelselet(univs,cst)=ContextSet.levelsctx,ContextSet.constraintsctxinletunivs',subst=Level.Set.fold(funu(univs',subst)->letu'=fresh_level()in(Level.Set.addu'univs',Level.Map.adduu'subst))univs(Level.Set.empty,Level.Map.empty)inletcst'=subst_univs_level_constraintssubstcstinsubst,(univs',cst')letfresh_sort_context_instance((qs,us),csts)=letusubst,(us,csts)=fresh_universe_context_set_instance(us,csts)inletqsubst,qs=QVar.Set.fold(funq(qsubst,qs)->letq'=new_sort_global()inQVar.Map.addq(Sorts.Quality.QVarq')qsubst,QVar.Set.addq'qs)qs(QVar.Map.empty,QVar.Set.empty)in(qsubst,usubst),((qs,us),csts)