Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file nametab.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694(************************************************************************)(* * 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) *)(************************************************************************)openNamesopenLibnamestypeobject_prefix={obj_dir:DirPath.t;obj_mp:ModPath.t;}leteq_opop1op2=DirPath.equalop1.obj_dirop2.obj_dir&&ModPath.equalop1.obj_mpop2.obj_mp(* to this type are mapped DirPath.t's in the nametab *)moduleGlobDirRef=structtypet=|DirOpenModuleofModPath.t|DirOpenModtypeofModPath.t|DirOpenSectionofDirPath.tletequalr1r2=matchr1,r2with|DirOpenModuleop1,DirOpenModuleop2->ModPath.equalop1op2|DirOpenModtypeop1,DirOpenModtypeop2->ModPath.equalop1op2|DirOpenSectionop1,DirOpenSectionop2->DirPath.equalop1op2|(DirOpenModule_|DirOpenModtype_|DirOpenSection_),_->falseendexceptionGlobalizationErrorofqualidleterror_global_not_found~infoqid=letinfo=Option.cata(Loc.add_locinfo)infoqid.CAst.locinExninfo.iraise(GlobalizationErrorqid,info)(* The visibility can be registered either
- for all suffixes not shorter then a given int - when the object
is loaded inside a module
or
- for a precise suffix, when the module containing (the module
containing ...) the object is open (imported)
*)typevisibility=Untilofint|Exactlyofintletmap_visibilityf=function|Untili->Until(fi)|Exactlyi->Exactly(fi)(* Data structure for nametabs *******************************************)(* This module type will be instantiated by [full_path] of [DirPath.t] *)(* The [repr] function is assumed to return the reversed list of idents. *)moduletypeUserName=sigtypetvalequal:t->t->boolvalto_string:t->stringvalrepr:t->Id.t*module_identlistendmoduletypeEqualityType=sigtypetvalequal:t->t->boolend(* A ['a t] is a map from [user_name] to ['a], with possible lookup by
partially qualified names of type [qualid]. The mapping of
partially qualified names to ['a] is determined by the [visibility]
parameter of [push].
The [shortest_qualid] function given a user_name Coq.A.B.x, tries
to find the shortest among x, B.x, A.B.x and Coq.A.B.x that denotes
the same object.
*)moduletypeNAMETREE=sigtypeelttypettypeuser_namevalempty:tvalpush:visibility->user_name->elt->t->tvallocate:qualid->t->eltvalfind:user_name->t->eltvalremove:user_name->t->tvalexists:user_name->t->boolvaluser_name:qualid->t->user_namevalshortest_qualid_gen:?loc:Loc.t->(Id.t->bool)->user_name->t->qualidvalshortest_qualid:?loc:Loc.t->Id.Set.t->user_name->t->qualidvalfind_prefixes:qualid->t->eltlist(** Matches a prefix of [qualid], useful for completion *)valmatch_prefixes:qualid->t->eltlistendletmasking_absolute=CWarnings.create_warning~from:[Deprecation.Version.v8_8]~name:"masking-absolute-name"()moduleMake(U:UserName)(E:EqualityType):NAMETREEwithtypeuser_name=U.tandtypeelt=E.t=structtypeelt=E.t(* A name became inaccessible, even with absolute qualification.
Example:
Module F (X : S). Module X.
The argument X of the functor F is masked by the inner module X.
*)letwarn_masking_absolute=CWarnings.create_inmasking_absolute(funn->Pp.str("Trying to mask the absolute name \""^U.to_stringn^"\"!"))typeuser_name=U.ttypepath_status=|Relativeofuser_name*elt|Absoluteofuser_name*elt(* Dictionaries of short names *)typenametree={path:path_statuslist;map:nametreeModIdmap.t}letmktreepm={path=p;map=m}letempty_tree=mktree[]ModIdmap.emptyletis_empty_treetree=tree.path=[]&&ModIdmap.is_emptytree.maptypet=nametreeId.Map.tletempty=Id.Map.empty(* [push_until] is used to register [Until vis] visibility.
Example: [push_until Top.X.Y.t o (Until 1) tree [Y;X;Top]] adds the
value [Relative (Top.X.Y.t,o)] to occurrences [Y] and [Y.X] of
the tree, and [Absolute (Top.X.Y.t,o)] to occurrence [Y.X.Top] of
the tree. In particular, the tree now includes the following shape:
{ map := Y |-> {map := X |-> {map := Top |-> {map := ...;
path := Absolute (Top.X.Y.t,o)::...}
...;
path := Relative (Top.X.Y.t,o)::...}
...;
path := Relative (Top.X.Y.t,o)::...}
...;
path := ...}
where ... denotes what was there before.
[push_exactly] is to register [Exactly vis] and [push] chooses
the right one *)letrecpush_untilunameoleveltree=function|modid::path->letmodify_mc=push_untilunameo(level-1)mcpathinletmap=tryModIdmap.modifymodidmodifytree.mapwithNot_found->letptab=modify()empty_treeinModIdmap.addmodidptabtree.mapinletthis=iflevel<=0thenmatchtree.pathwith|Absolute(n,_)::_->(* This is an absolute name, we must keep it
otherwise it may become unaccessible forever *)warn_masking_absoluten;tree.path|current->Relative(uname,o)::currentelsetree.pathinmktreethismap|[]->matchtree.pathwith|Absolute(uname',o')::_->ifE.equalo'othenbeginassert(U.equalunameuname');tree(* we are putting the same thing for the second time :) *)endelse(* This is an absolute name, we must keep it otherwise it may
become unaccessible forever *)(* But ours is also absolute! This is an error! *)CErrors.user_errPp.(str@@"Cannot mask the absolute name \""^U.to_stringuname'^"\"!")|current->mktree(Absolute(uname,o)::current)tree.mapletrecpush_exactlyunameoleveltree=function|[]->CErrors.anomaly(Pp.str"Prefix longer than path! Impossible!")|modid::path->ifInt.equallevel0thenletthis=matchtree.pathwith|Absolute(n,_)::_->(* This is an absolute name, we must keep it
otherwise it may become unaccessible forever *)warn_masking_absoluten;tree.path|current->Relative(uname,o)::currentinmktreethistree.mapelse(* not right level *)letmodify_mc=push_exactlyunameo(level-1)mcpathinletmap=tryModIdmap.modifymodidmodifytree.mapwithNot_found->letptab=modify()empty_treeinModIdmap.addmodidptabtree.mapinmktreetree.pathmapletpushvisibilityunameotab=letid,dir=U.reprunameinletmodify_ptab=matchvisibilitywith|Untili->push_untilunameo(i-1)ptabdir|Exactlyi->push_exactlyunameo(i-1)ptabdirintryId.Map.modifyidmodifytabwithNot_found->letptab=modify()empty_treeinId.Map.addidptabtab(** [remove_path uname tree dir] removes all bindings pointing to
[uname] along the path [dir] in [tree] (i.e. all such bindings are
assumed to be on this path) *)letrecremove_pathunametree=function|modid::path->letupdate=function|None->(* The name was actually not here *)None|Somemc->letmc=remove_pathunamemcpathinifis_empty_treemcthenNoneelseSomemcinletmap=ModIdmap.updatemodidupdatetree.mapinletthis=lettest=functionRelative(uname',_)->not(U.equalunameuname')|_->trueinList.filtertesttree.pathinmktreethismap|[]->letthis=lettest=functionAbsolute(uname',_)->not(U.equalunameuname')|_->trueinList.filtertesttree.pathinmktreethistree.map(** Remove all bindings pointing to [uname] in [tab] *)letremoveunametab=letid,dir=U.reprunameinletmodify_ptab=remove_pathunameptabdirintryId.Map.modifyidmodifytabwithNot_found->tabletrecsearchtree=function|modid::path->search(ModIdmap.findmodidtree.map)path|[]->tree.pathletfind_nodeqidtab=let(dir,id)=repr_qualidqidinsearch(Id.Map.findidtab)(DirPath.reprdir)letlocateqidtab=leto=matchfind_nodeqidtabwith|(Absolute(uname,o)|Relative(uname,o))::_->o|[]->raiseNot_foundinoletuser_nameqidtab=letuname=matchfind_nodeqidtabwith|(Absolute(uname,o)|Relative(uname,o))::_->uname|[]->raiseNot_foundinunameletfindunametab=letid,l=U.reprunameinmatchsearch(Id.Map.findidtab)lwithAbsolute(_,o)::_->o|_->raiseNot_foundletexistsunametab=trylet_=findunametabintruewithNot_found->falseletshortest_qualid_gen?lochiddenunametab=letid,dir=U.reprunameinlethidden=hiddenidinletrecfind_unameposdirtree=letis_empty=matchposwith[]->true|_->falseinmatchtree.pathwith|(Absolute(u,_)|Relative(u,_))::_whenU.equaluuname&¬(is_empty&&hidden)->List.revpos|_->matchdirwith[]->raiseNot_found|id::dir->find_uname(id::pos)dir(ModIdmap.findidtree.map)inletptab=Id.Map.findidtabinletfound_dir=find_uname[]dirptabinmake_qualid?loc(DirPath.makefound_dir)idletshortest_qualid?locctxunametab=shortest_qualid_gen?loc(funid->Id.Set.memidctx)unametabletpush_nodenodel=matchnodewith|(Absolute(_,o)|Relative(_,o))::_whennot(Util.List.mem_fE.equalol)->o::l|_->lletrecflatten_treetreel=letf_treel=flatten_treetreelinModIdmap.foldftree.map(push_nodetree.pathl)letrecsearch_prefixestree=function|modid::path->search_prefixes(ModIdmap.findmodidtree.map)path|[]->List.rev(flatten_treetree[])letfind_prefixesqidtab=trylet(dir,id)=repr_qualidqidinsearch_prefixes(Id.Map.findidtab)(DirPath.reprdir)withNot_found->[]letmatch_prefixes=letcprefixxy=CString.(comparex(suby0(min(lengthx)(lengthy))))infunqidtab->trylet(dir,id)=repr_qualidqidinletid_prefix=cprefixId.(to_stringid)inletmatches=Id.Map.filter_range(funx->id_prefixId.(to_stringx))tabinletmatches=Id.Map.mapi(fun_keytab->search_prefixestab(DirPath.reprdir))matchesin(* Coq's flatten is "magical", so this is not so bad perf-wise *)CList.flatten@@Id.Map.(fold(fun_rl->r::l)matches[])withNot_found->[]end(* Global name tables *************************************************)moduleFullPath=structtypet=full_pathletequal=eq_full_pathletto_string=string_of_pathletreprsp=letdir,id=repr_pathspinid,(DirPath.reprdir)endmoduleExtRefEqual=Globnames.ExtRefOrderedmoduleMPEqual=Names.ModPathmoduleExtRefTab=Make(FullPath)(ExtRefEqual)moduleMPTab=Make(FullPath)(MPEqual)typeccitab=ExtRefTab.tletthe_ccitab=Summary.ref~name:"ccitab"(ExtRefTab.empty:ccitab)moduleDirPath'=structincludeDirPathletreprdir=matchDirPath.reprdirwith|[]->CErrors.anomaly(Pp.str"Empty dirpath.")|id::l->(id,l)endmoduleMPDTab=Make(DirPath')(MPEqual)moduleDirTab=Make(DirPath')(GlobDirRef)moduleUnivTab=Make(FullPath)(Univ.UGlobal)typeunivtab=UnivTab.tletthe_univtab=Summary.ref~name:"univtab"(UnivTab.empty:univtab)(* Reversed name tables ***************************************************)(* This table translates extended_global_references back to section paths *)typeglobrevtab=full_pathGlobnames.ExtRefMap.tletthe_globrevtab=Summary.ref~name:"globrevtab"(Globnames.ExtRefMap.empty:globrevtab)letthe_globwarntab=Summary.ref~name:"globwarntag"Globnames.ExtRefMap.emptytypemprevtab=DirPath.tMPmap.ttypemptrevtab=full_pathMPmap.tmoduleUnivIdMap=HMap.Make(Univ.UGlobal)typeunivrevtab=full_pathUnivIdMap.tletthe_univrevtab=Summary.ref~name:"univrevtab"(UnivIdMap.empty:univrevtab)(** Module-related nametab *)moduleModules=structtypet={modtypetab:MPTab.t;modtab:MPDTab.t;dirtab:DirTab.t;modrevtab:mprevtab;modtyperevtab:mptrevtab;}letinitial={modtypetab=MPTab.empty;modtab=MPDTab.empty;dirtab=DirTab.empty;modrevtab=MPmap.empty;modtyperevtab=MPmap.empty}letnametab,summary_tag=Summary.ref_tag~stage:Summary.Stage.Synterp~name:"MODULES-NAMETAB"initialletfreeze()=!nametabletunfreezev=nametab:=vend(* Push functions *********************************************************)(* This is for permanent constructions (never discharged -- but with
possibly limited visibility, i.e. Theorem, Lemma, Definition, Axiom,
Parameter but also Remark and Fact) *)letpush_xref?user_warnsvisibilityspxref=matchvisibilitywith|Until_->the_ccitab:=ExtRefTab.pushvisibilityspxref!the_ccitab;the_globrevtab:=Globnames.ExtRefMap.addxrefsp!the_globrevtab;user_warns|>Option.iter(funwarn->the_globwarntab:=Globnames.ExtRefMap.addxrefwarn!the_globwarntab)|Exactly_->beginassert(Option.is_emptyuser_warns);the_ccitab:=ExtRefTab.pushvisibilityspxref!the_ccitabendletremove_xrefspxref=the_ccitab:=ExtRefTab.removesp!the_ccitab;the_globrevtab:=Globnames.ExtRefMap.removexref!the_globrevtab;the_globwarntab:=Globnames.ExtRefMap.removexref!the_globwarntabletpush_cci?user_warnsvisibilityspref=push_xref?user_warnsvisibilitysp(TrueGlobalref)(* This is for Syntactic Definitions *)letpush_abbreviation?user_warnsvisibilityspkn=push_xref?user_warnsvisibilitysp(Abbrevkn)letremove_abbreviationspkn=remove_xrefsp(Abbrevkn)letpush=push_cciletpush_modtypevisspkn=letopenModulesinnametab:={!nametabwithmodtypetab=MPTab.pushvisspkn!nametab.modtypetab;modtyperevtab=MPmap.addknsp!nametab.modtyperevtab;}letpush_modulevisdirmp=letopenModulesinnametab:={!nametabwithmodtab=MPDTab.pushvisdirmp!nametab.modtab;modrevtab=MPmap.addmpdir!nametab.modrevtab;}(* This is to remember absolute Section/Module names and to avoid redundancy *)letpush_dirvisdirdir_ref=letopenModulesinnametab:={!nametabwithdirtab=DirTab.pushvisdirdir_ref!Modules.nametab.dirtab;}(* This is for global universe names *)letpush_universevisspuniv=the_univtab:=UnivTab.pushvisspuniv!the_univtab;the_univrevtab:=UnivIdMap.addunivsp!the_univrevtab(* Reverse locate functions ***********************************************)letpath_of_globalref=letopenGlobRefinmatchrefwith|VarRefid->make_pathDirPath.emptyid|_->Globnames.ExtRefMap.find(TrueGlobalref)!the_globrevtabletdirpath_of_globalref=fst(repr_path(path_of_globalref))letbasename_of_globalref=snd(repr_path(path_of_globalref))letpath_of_abbreviationkn=Globnames.ExtRefMap.find(Abbrevkn)!the_globrevtabletdirpath_of_modulemp=MPmap.findmpModules.(!nametab.modrevtab)letpath_of_modtypemp=MPmap.findmpModules.(!nametab.modtyperevtab)letpath_of_universemp=UnivIdMap.findmp!the_univrevtab(* Shortest qualid functions **********************************************)letshortest_qualid_of_global?locctxref=letopenGlobRefinmatchrefwith|VarRefid->make_qualid?locDirPath.emptyid|_->letsp=Globnames.ExtRefMap.find(TrueGlobalref)!the_globrevtabinExtRefTab.shortest_qualid?locctxsp!the_ccitabletshortest_qualid_of_abbreviation?locctxkn=letsp=path_of_abbreviationkninExtRefTab.shortest_qualid?locctxsp!the_ccitabletshortest_qualid_of_module?locmp=letdir=MPmap.findmpModules.(!nametab.modrevtab)inMPDTab.shortest_qualid?locId.Set.emptydirModules.(!nametab.modtab)letshortest_qualid_of_modtype?lockn=letsp=MPmap.findknModules.(!nametab.modtyperevtab)inMPTab.shortest_qualid?locId.Set.emptyspModules.(!nametab.modtypetab)letshortest_qualid_of_universe?locctxkn=letsp=UnivIdMap.findkn!the_univrevtabinUnivTab.shortest_qualid_gen?loc(funid->Id.Map.memidctx)sp!the_univtabletpr_global_envenvref=trypr_qualid(shortest_qualid_of_globalenvref)withNot_foundasexn->letexn,info=Exninfo.captureexninif!Flags.in_debuggerthenGlobRef.printrefelsebeginlet()=ifCDebug.(get_flagmisc)thenFeedback.msg_debug(Pp.str"pr_global_env not found")inExninfo.iraise(exn,info)end(* Locate functions *******************************************************)letpr_depr_xrefxref=letsp=Globnames.ExtRefMap.getxref!the_globrevtabinpr_qualid(ExtRefTab.shortest_qualidId.Set.emptysp!the_ccitab)letpr_depr_refref=pr_depr_xref(TrueGlobalref)letwarn_deprecated_ref=Deprecation.create_warning~object_name:"Reference"~warning_name_if_no_since:"deprecated-reference"pr_depr_refletpr_depr_abbreva=pr_depr_xref(Abbreva)letwarn_deprecated_abbreviation=Deprecation.create_warning~object_name:"Notation"~warning_name_if_no_since:"deprecated-syntactic-definition"pr_depr_abbrevletwarn_deprecated_xref?locdepr=function|Globnames.TrueGlobalref->warn_deprecated_ref?loc(ref,depr)|Abbreva->warn_deprecated_abbreviation?loc(a,depr)letwarn_user_warn=UserWarn.create_warning~warning_name_if_no_cats:"warn-reference"()letis_warned_xrefxref:UserWarn.toption=Globnames.ExtRefMap.find_optxref!the_globwarntabletwarn_user_warn_xref?locuser_warnsxref=user_warns.UserWarn.depr|>Option.iter(fundepr->warn_deprecated_xref?locdeprxref);user_warns.UserWarn.warn|>List.iter(warn_user_warn?loc)letlocate_extended_nowarnqid=letxref=ExtRefTab.locateqid!the_ccitabinxref(* This should be used when abbreviations are allowed *)letlocate_extendedqid=letxref=locate_extended_nowarnqidinletwarn=is_warned_xrefxrefinlet()=warn|>Option.iter(funwarn->warn_user_warn_xref?loc:qid.locwarnxref)inxref(* This should be used when no abbreviations are expected *)letlocateqid=matchlocate_extendedqidwith|TrueGlobalref->ref|Abbrev_->raiseNot_foundletlocate_abbreviationqid=matchlocate_extendedqidwith|TrueGlobal_->raiseNot_found|Abbrevkn->knletlocate_modtypeqid=MPTab.locateqidModules.(!nametab.modtypetab)letfull_name_modtypeqid=MPTab.user_nameqidModules.(!nametab.modtypetab)letlocate_universeqid=UnivTab.locateqid!the_univtabletlocate_dirqid=DirTab.locateqidModules.(!nametab.dirtab)letlocate_moduleqid=MPDTab.locateqidModules.(!nametab.modtab)letfull_name_moduleqid=MPDTab.user_nameqidModules.(!nametab.modtab)letlocate_sectionqid=matchlocate_dirqidwith|GlobDirRef.DirOpenSectiondir->dir|_->raiseNot_found(* Users of locate_all don't seem to need deprecation info *)letlocate_allqid=List.fold_right(funal->matchawith|Globnames.TrueGlobala->a::l|_->l)(ExtRefTab.find_prefixesqid!the_ccitab)[]letlocate_extended_allqid=ExtRefTab.find_prefixesqid!the_ccitabletlocate_extended_all_dirqid=DirTab.find_prefixesqidModules.(!nametab.dirtab)letlocate_extended_all_modtypeqid=MPTab.find_prefixesqidModules.(!nametab.modtypetab)letlocate_extended_all_moduleqid=MPDTab.find_prefixesqidModules.(!nametab.modtab)(* Completion *)letcompletion_canditatesqualid=ExtRefTab.match_prefixesqualid!the_ccitab(* Derived functions *)letlocate_constantqid=letopenGlobRefinmatchlocate_extendedqidwith|TrueGlobal(ConstRefkn)->kn|_->raiseNot_foundletglobal_of_pathsp=matchExtRefTab.findsp!the_ccitabwith|TrueGlobalref->ref|_->raiseNot_foundletextended_global_of_pathsp=ExtRefTab.findsp!the_ccitabletglobalqid=trymatchlocate_extendedqidwith|TrueGlobalref->ref|Abbrev_->CErrors.user_err?loc:qid.CAst.locPp.(str"Unexpected reference to a notation: "++pr_qualidqid++str".")withNot_foundasexn->let_,info=Exninfo.captureexninerror_global_not_found~infoqidletglobal_inductiveqid=letopenGlobRefinmatchglobalqidwith|IndRefind->ind|ref->CErrors.user_err?loc:qid.CAst.locPp.(pr_qualidqid++spc()++str"is not an inductive type.")(* Exists functions ********************************************************)letexists_ccisp=ExtRefTab.existssp!the_ccitabletexists_dirdir=DirTab.existsdirModules.(!nametab.dirtab)letexists_moduledir=MPDTab.existsdirModules.(!nametab.modtab)letexists_modtypesp=MPTab.existsspModules.(!nametab.modtypetab)letexists_universekn=UnivTab.existskn!the_univtab