123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283(************************************************************************)(* * 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) *)|QualifiedUnivofDirPath.t(* global universe introduced by some global value *)|UnqualifiedUniv(* other global universe, todo merge with [QualifiedUniv []] *)typeuniverse_name_decl=universe_source*(Id.t*UGlobal.t)listtypesort_source=|BoundQuality|UnqualifiedQualitytypesort_name_decl={sdecl_src:sort_source;(* global sort introduced by some global value *)sdecl_named:(Id.t*Sorts.QGlobal.t)list;}letcheck_exists_universesp=ifNametab.exists_universespthenraise(AlreadyDeclared(Some"Universe",Libnames.basenamesp))else()letqualify_unividpsrcid=matchsrcwith|BoundUniv|UnqualifiedUniv->i,Libnames.add_path_suffixdpid|QualifiedUnivl->letpath=Libnames.append_pathdplinNametab.map_visibility(funn->n+List.length(DirPath.reprl))i,Libnames.add_path_suffixpathidletdo_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.path_pop_n_suffixesdepthprefix.Libobject.obj_pathinList.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.Libobject.obj_pathsrc)univsletopen_univ_namesi(prefix,(src,univs))=List.iter(do_univ_name~check:false(Nametab.Exactlyi)prefix.Libobject.obj_pathsrc)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=filtered_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.add_path_suffixprefixnainifId.Map.memnanamed||Nametab.exists_universespthenaux(i+1)elsena,(Id.Map.addnaunamed,i+1)inauxcntletcheck_exists_sortsp=ifNametab.Quality.existsspthenraise(AlreadyDeclared(Some"Sort",Libnames.basenamesp))else()letqualify_sortidpid=i,Libnames.add_path_suffixdpidletdo_sort_name~checkidp(id,quality)=leti,sp=qualify_sortidpidinifcheckthencheck_exists_sortsp;Nametab.Quality.pushispqualityletcache_sort_names(prefix,decl)=letdepth=Lib.sections_depth()inletdp=Libnames.path_pop_n_suffixesdepthprefix.Libobject.obj_pathinList.iter(do_sort_name~check:true(Nametab.Until1)dp)decl.sdecl_namedletload_sort_namesi(prefix,decl)=List.iter(do_sort_name~check:false(Nametab.Untili)prefix.Libobject.obj_path)decl.sdecl_namedletopen_sort_namesi(prefix,decl)=List.iter(do_sort_name~check:false(Nametab.Exactlyi)prefix.Libobject.obj_path)decl.sdecl_namedletdischarge_sort_namesdecl=matchdecl.sdecl_srcwith|BoundQuality->None|UnqualifiedQuality->Somedeclletinput_sort_names:sort_name_decl->Libobject.obj=letopenLibobjectindeclare_named_object_gen{(default_object"Global sort name state")withcache_function=cache_sort_names;load_function=load_sort_names;open_function=filtered_openopen_sort_names;discharge_function=discharge_sort_names;classify_function=(funa->Escape)}letinput_sort_names(src,l)=ifCList.is_emptylthen()elseLib.add_leaf(input_sort_names{sdecl_src=src;sdecl_named=l})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 invent names for the rest *)letprefix=Libnames.add_path_suffix(Lib.cwd_except_section())linlet_,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(DirPath.make[l]),univs)letname_mono_section_univsunivs=ifLevel.Set.is_emptyunivsthen()elseletprefix=Lib.cwd()inletsections=letopenLibnamesindrop_dirpath_prefix(dirpath_of_path@@Lib.cwd_except_section())(dirpath_of_pathprefix)inlet_,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{quals=[||];univs=names}(UVars.Instance.of_array([||],us),Constraints.empty)inGlobal.push_section_contextctxletdo_sort~polyl=letin_section=Lib.sections_are_opened()inlet()=ifpoly&¬in_sectionthenCErrors.user_err(Pp.str"Cannot declare polymorphic sorts outside sections.")inletl=List.map(fun{CAst.v=id}->(id,UnivGen.new_sort_globalid))linletsrc=ifpolythenBoundQualityelseUnqualifiedQualityinlet()=input_sort_names(src,l)inmatchpolywith|false->letqs=List.fold_left(funqs(_,qv)->Sorts.QVar.(Set.add(make_globalqv)qs))Sorts.QVar.Set.emptylinGlobal.push_quality_setqs|true->letnames=CArray.map_of_list(fun(na,_)->Namena)linletqs=CArray.map_of_list(fun(_,sg)->Sorts.Quality.globalsg)linletctx=UVars.UContext.make{quals=names;univs=[||]}(UVars.Instance.of_array(qs,[||]),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.makeUVars.empty_bound_names(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)