123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149(************************************************************************)(* * 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) *)(************************************************************************)(* File created around Apr 1994 for CiC V5.10.5 by Chet Murthy collecting
parts of file initial.ml from CoC V4.8, Dec 1988, by Gérard Huet,
Thierry Coquand and Christine Paulin *)(* Hash-consing by Bruno Barras in Feb 1998 *)(* Extra functions for splitting/generation of identifiers by Hugo Herbelin *)(* Restructuration by Jacek Chrzaszcz as part of the implementation of
the module system, Aug 2002 *)(* Abstraction over the type of constant for module inlining by Claudio
Sacerdoti, Nov 2004 *)(* Miscellaneous features or improvements by Hugo Herbelin,
Élie Soubiran, ... *)openPpopenUtil(** {6 Identifiers } *)(** Representation and operations on identifiers. *)moduleId=structtypet=stringletequal=String.equalletcompare=String.comparelethash=String.hashletcheck_valid?(strict=true)x=letiter(fatal,x)=iffatal||strictthenCErrors.user_errPp.(strx)inOption.iteriter(Unicode.ident_refutationx)letis_valids=matchUnicode.ident_refutationswith|None->true|Some_->falseletis_valid_ident_parts=matchUnicode.ident_refutation("x"^s)with|None->true|Some_->falseletof_bytess=lets=Bytes.to_stringsincheck_valids;String.hconssletof_strings=let()=check_validsinString.hconssletof_string_softs=let()=check_valid~strict:falsesinString.hconssletto_stringid=idletprintid=stridmoduleSet=CString.SetmoduleMap=CString.MapmodulePred=CString.PredmoduleList=String.Listlethcons=String.hconsend(** Representation and operations on identifiers that are allowed to be anonymous
(i.e. "_" in concrete syntax). *)moduleName=structtypet=Anonymous(** anonymous identifier *)|NameofId.t(** non-anonymous identifier *)letmk_nameid=Nameidletis_anonymous=function|Anonymous->true|Name_->falseletis_name=is_anonymous%>notletcomparen1n2=matchn1,n2with|Anonymous,Anonymous->0|Nameid1,Nameid2->Id.compareid1id2|Anonymous,Name_->-1|Name_,Anonymous->1letequaln1n2=matchn1,n2with|Anonymous,Anonymous->true|Nameid1,Nameid2->String.equalid1id2|_->falselethash=function|Anonymous->0|Nameid->Id.hashidletprint=function|Anonymous->str"_"|Nameid->Id.printidmoduleSelf_Hashcons=structtypenonrect=ttypeu=Id.t->Id.tlethashconshident=function|Nameid->Name(hidentid)|n->nleteqn1n2=n1==n2||match(n1,n2)with|(Nameid1,Nameid2)->id1==id2|(Anonymous,Anonymous)->true|_->falselethash=hashendmoduleHname=Hashcons.Make(Self_Hashcons)lethcons=Hashcons.simple_hconsHname.generateHname.hconsId.hconsend(** Alias, to import constructors. *)typename=Name.t=Anonymous|NameofId.t(** {6 Various types based on identifiers } *)typevariable=Id.ttypemodule_ident=Id.tmoduleModIdset=Id.SetmoduleModIdmap=Id.Map(** {6 Directory paths = section names paths } *)(** Dirpaths are lists of module identifiers.
The actual representation is reversed to optimise sharing:
Coq.A.B is ["B";"A";"Coq"] *)letdummy_module_name="If you see this, it's a bug"moduleDirPath=structtypet=module_identlistletcompare=List.compareId.compareletequal=List.equalId.equalletrechashaccu=function|[]->accu|id::dp->letaccu=Hashset.Combine.combine(Id.hashid)accuinhashaccudplethashdp=hash0dpletmakex=xletreprx=xletempty=[]letis_empty=List.is_emptyletto_string=function|[]->"<>"|sl->String.concat"."(List.rev_mapId.to_stringsl)letprintdp=str(to_stringdp)letdummy=[dummy_module_name]moduleHdir=Hashcons.Hlist(Id)lethcons=Hashcons.simple_hconsHdir.generateHdir.hconsId.hconsend(** {6 Unique names for bound modules } *)moduleMBId=structtypet=int*Id.t*DirPath.tletgen=letseed=ref0infun()->letans=!seedinlet()=incrseedinansletmakedirs=(gen(),s,dir)letreprmbid=mbidletto_string(_i,s,p)=DirPath.to_stringp^"."^sletdebug_to_string(i,s,p)="<"^DirPath.to_stringp^"#"^s^"#"^string_of_inti^">"letcompare(x:t)(y:t)=ifx==ythen0elsematch(x,y)with|(nl,idl,dpl),(nr,idr,dpr)->letans=Int.comparenlnrinifnot(Int.equalans0)thenanselseletans=Id.compareidlidrinifnot(Int.equalans0)thenanselseDirPath.comparedpldprletequalxy=x==y||let(i1,id1,p1)=xinlet(i2,id2,p2)=yinInt.equali1i2&&Id.equalid1id2&&DirPath.equalp1p2letto_id(_,s,_)=sopenHashset.Combinelethash(i,id,dp)=combine3(Int.hashi)(Id.hashid)(DirPath.hashdp)moduleSelf_Hashcons=structtypenonrect=ttypeu=(Id.t->Id.t)*(DirPath.t->DirPath.t)lethashcons(hid,hdir)(n,s,dir)=(n,hids,hdirdir)leteq((n1,s1,dir1)asx)((n2,s2,dir2)asy)=(x==y)||(Int.equaln1n2&&s1==s2&&dir1==dir2)lethash=hashendmoduleHashMBId=Hashcons.Make(Self_Hashcons)lethcons=Hashcons.simple_hconsHashMBId.generateHashMBId.hcons(Id.hcons,DirPath.hcons)endmoduleMBImap=CMap.Make(MBId)moduleMBIset=Set.Make(MBId)(** {6 Names of structure elements } *)moduleLabel=structincludeIdletmake=Id.of_stringletof_idid=idletto_idid=idend(** {6 The module part of the kernel name } *)moduleModPath=structtypet=|MPfileofDirPath.t|MPboundofMBId.t|MPdotoft*Label.ttypemodule_path=tletrecis_bound=function|MPbound_->true|MPdot(mp,_)->is_boundmp|_->falseletrecto_string=function|MPfilesl->DirPath.to_stringsl|MPbounduid->MBId.to_stringuid|MPdot(mp,l)->to_stringmp^"."^Label.to_stringlletprintmp=str(to_stringmp)letrecdebug_to_string=function|MPfilesl->DirPath.to_stringsl|MPbounduid->MBId.debug_to_stringuid|MPdot(mp,l)->debug_to_stringmp^"."^Label.to_stringl(** we compare labels first if both are MPdots *)letreccomparemp1mp2=ifmp1==mp2then0elsematchmp1,mp2with|MPfilep1,MPfilep2->DirPath.comparep1p2|MPboundid1,MPboundid2->MBId.compareid1id2|MPdot(mp1,l1),MPdot(mp2,l2)->letc=String.comparel1l2inifnot(Int.equalc0)thencelsecomparemp1mp2|MPfile_,_->-1|MPbound_,MPfile_->1|MPbound_,MPdot_->-1|MPdot_,_->1letrecequalmp1mp2=mp1==mp2||matchmp1,mp2with|MPfilep1,MPfilep2->DirPath.equalp1p2|MPboundid1,MPboundid2->MBId.equalid1id2|MPdot(mp1,l1),MPdot(mp2,l2)->String.equall1l2&&equalmp1mp2|(MPfile_|MPbound_|MPdot_),_->falseopenHashset.Combineletrechash=function|MPfiledp->combinesmall1(DirPath.hashdp)|MPboundid->combinesmall2(MBId.hashid)|MPdot(mp,lbl)->combinesmall3(combine(hashmp)(Label.hashlbl))letdummy=MPfileDirPath.dummyletrecdp=function|MPfilesl->sl|MPbound(_,_,dp)->dp|MPdot(mp,_l)->dpmpmoduleSelf_Hashcons=structtypet=module_pathtypeu=(DirPath.t->DirPath.t)*(MBId.t->MBId.t)*(string->string)letrechashcons(hdir,huniqid,hstrashfuns)=function|MPfiledir->MPfile(hdirdir)|MPboundm->MPbound(huniqidm)|MPdot(md,l)->MPdot(hashconshfunsmd,hstrl)leteqd1d2=d1==d2||matchd1,d2with|MPfiledir1,MPfiledir2->dir1==dir2|MPboundm1,MPboundm2->m1==m2|MPdot(mod1,l1),MPdot(mod2,l2)->l1==l2&&equalmod1mod2|_->falselethash=hashendmoduleHashMP=Hashcons.Make(Self_Hashcons)lethcons=Hashcons.simple_hconsHashMP.generateHashMP.hcons(DirPath.hcons,MBId.hcons,String.hcons)endmoduleDPset=Set.Make(DirPath)moduleDPmap=Map.Make(DirPath)moduleMPset=Set.Make(ModPath)moduleMPmap=CMap.Make(ModPath)(** {6 Kernel names } *)moduleKerName=structtypet={modpath:ModPath.t;knlabel:Label.t;refhash:int;(** Lazily computed hash. If unset, it is set to negative values. *)}typekernel_name=tletmakemodpathknlabel=letopenHashset.Combineinletrefhash=combine(ModPath.hashmodpath)(Label.hashknlabel)in(* Truncate for backwards compatibility w.r.t. ordering *)letrefhash=refhashland0x3FFFFFFFin{modpath;knlabel;refhash;}letreprkn=(kn.modpath,kn.knlabel)letmodpathkn=kn.modpathletlabelkn=kn.knlabelletto_string_genmp_to_stringkn=mp_to_stringkn.modpath^"."^Label.to_stringkn.knlabelletto_stringkn=to_string_genModPath.to_stringknletdebug_to_stringkn=to_string_genModPath.debug_to_stringknletprintkn=str(to_stringkn)letdebug_printkn=str(debug_to_stringkn)letcompare(kn1:kernel_name)(kn2:kernel_name)=ifkn1==kn2then0elseletc=String.comparekn1.knlabelkn2.knlabelinifnot(Int.equalc0)thencelseModPath.comparekn1.modpathkn2.modpathletequalkn1kn2=leth1=kn1.refhashinleth2=kn2.refhashinif0<=h1&&0<=h2&¬(Int.equalh1h2)thenfalseelseLabel.equalkn1.knlabelkn2.knlabel&&ModPath.equalkn1.modpathkn2.modpathlethashkn=kn.refhashmoduleSelf_Hashcons=structtypet=kernel_nametypeu=(ModPath.t->ModPath.t)*(DirPath.t->DirPath.t)*(string->string)lethashcons(hmod,_hdir,hstr)kn=let{modpath=mp;knlabel=l;refhash;}=knin{modpath=hmodmp;knlabel=hstrl;refhash;}leteqkn1kn2=kn1.modpath==kn2.modpath&&kn1.knlabel==kn2.knlabellethash=hashendmoduleHashKN=Hashcons.Make(Self_Hashcons)lethcons=Hashcons.simple_hconsHashKN.generateHashKN.hcons(ModPath.hcons,DirPath.hcons,String.hcons)endmoduleKNmap=HMap.Make(KerName)moduleKNpred=Predicate.Make(KerName)moduleKNset=KNmap.Set(** {6 Kernel pairs } *)moduletypeEqType=sigtypetvalcompare:t->t->intvalequal:t->t->boolvalhash:t->intendmoduletypeQNameS=sigtypetmoduleCanOrd:EqTypewithtypet=tmoduleUserOrd:EqTypewithtypet=tmoduleSyntacticOrd:EqTypewithtypet=tvalcanonize:t->tend(** For constant and inductive names, we use a kernel name couple (kn1,kn2)
where kn1 corresponds to the name used at toplevel (i.e. what the user see)
and kn2 corresponds to the canonical kernel name i.e. in the environment
we have {% kn1 \rhd_{\delta}^* kn2 \rhd_{\delta} t %}
Invariants :
- the user and canonical kn may differ only on their [module_path],
the dirpaths and labels should be the same
- when user and canonical parts differ, we cannot be in a section
anymore, hence the dirpath must be empty
- two pairs with the same user part should have the same canonical part
in a given environment (though with backtracking, the hash-table can
contains pairs with same user part but different canonical part from
a previous state of the session)
Note: since most of the time the canonical and user parts are equal,
we handle this case with a particular constructor to spare some memory *)moduleKerPair=structtypet=|SameofKerName.t(** user = canonical *)|DualofKerName.t*KerName.t(** user then canonical *)typekernel_pair=tletcanonical=function|Samekn->kn|Dual(_,kn)->knletuser=function|Samekn->kn|Dual(kn,_)->knletcanonizekp=matchkpwith|Same_->kp|Dual(_,kn)->Sameknletsamekn=Sameknletmakeknuknc=ifKerName.equalknukncthenSamekncelseDual(knu,knc)letmake1=sameletmake2mpl=same(KerName.makempl)letlabelkp=KerName.label(userkp)letmodpathkp=KerName.modpath(userkp)letchange_labelkplbl=let(mp1,l1)=KerName.repr(userkp)and(mp2,l2)=KerName.repr(canonicalkp)inassert(String.equall1l2);ifString.equallbll1thenkpelseletkn=KerName.makemp1lblinifmp1==mp2thensameknelsemakekn(KerName.makemp2lbl)letto_stringkp=KerName.to_string(userkp)letprintkp=str(to_stringkp)letdebug_to_string=function|Samekn->"("^KerName.debug_to_stringkn^")"|Dual(knu,knc)->"("^KerName.debug_to_stringknu^","^KerName.debug_to_stringknc^")"letdebug_printkp=str(debug_to_stringkp)(** For ordering kernel pairs, both user or canonical parts may make
sense, according to your needs: user for the environments, canonical
for other uses (ex: non-logical things). *)moduleUserOrd=structtypet=kernel_pairletcomparexy=KerName.compare(userx)(usery)letequalxy=x==y||KerName.equal(userx)(usery)lethashx=KerName.hash(userx)endmoduleCanOrd=structtypet=kernel_pairletcomparexy=KerName.compare(canonicalx)(canonicaly)letequalxy=x==y||KerName.equal(canonicalx)(canonicaly)lethashx=KerName.hash(canonicalx)endmoduleSyntacticOrd=structtypet=kernel_pairletcomparexy=matchx,ywith|Sameknx,Samekny->KerName.compareknxkny|Dual(knux,kncx),Dual(knuy,kncy)->letc=KerName.compareknuxknuyinifnot(Int.equalc0)thencelseKerName.comparekncxkncy|Same_,_->-1|Dual_,_->1letequalxy=x==y||comparexy=0lethash=function|Samekn->KerName.hashkn|Dual(knu,knc)->Hashset.Combine.combine(KerName.hashknu)(KerName.hashknc)end(** Default (logical) comparison and hash is on the canonical part *)letequal=CanOrd.equallethash=CanOrd.hashmoduleSelf_Hashcons=structtypet=kernel_pairtypeu=KerName.t->KerName.tlethashconshkn=function|Samekn->Same(hknkn)|Dual(knu,knc)->make(hknknu)(hknknc)leteqxy=(* physical comparison on subterms *)x==y||matchx,ywith|Samex,Samey->x==y|Dual(ux,cx),Dual(uy,cy)->ux==uy&&cx==cy|(Same_|Dual_),_->false(** Hash-consing (despite having the same user part implies having
the same canonical part is a logical invariant of the system, it
is not necessarily an invariant in memory, so we treat kernel
names as they are syntactically for hash-consing) *)lethash=function|Samekn->KerName.hashkn|Dual(knu,knc)->Hashset.Combine.combine(KerName.hashknu)(KerName.hashknc)endmoduleHashKP=Hashcons.Make(Self_Hashcons)lethcons=Hashcons.simple_hconsHashKP.generateHashKP.hconsKerName.hconsend(** {6 Constant Names} *)moduleConstant=KerPairmoduleCmap=HMap.Make(Constant.CanOrd)(** A map whose keys are constants (values of the {!Constant.t} type).
Keys are ordered wrt. "canonical form" of the constant. *)moduleCmap_env=HMap.Make(Constant.UserOrd)(** A map whose keys are constants (values of the {!Constant.t} type).
Keys are ordered wrt. "user form" of the constant. *)moduleCpred=Predicate.Make(Constant.CanOrd)moduleCset=Cmap.SetmoduleCset_env=Cmap_env.Set(** {6 Names of mutual inductive types } *)moduleMutInd=KerPairmoduleMindmap=HMap.Make(MutInd.CanOrd)moduleMindset=Mindmap.SetmoduleMindmap_env=HMap.Make(MutInd.UserOrd)moduleInd=struct(** Designation of a (particular) inductive type. *)typet=MutInd.t(* the name of the inductive type *)*int(* the position of this inductive type
within the block of mutually-recursive inductive types.
BEWARE: indexing starts from 0. *)letmodpath(mind,_)=MutInd.modpathmindmoduleCanOrd=structtypenonrect=tletequal(m1,i1)(m2,i2)=Int.equali1i2&&MutInd.CanOrd.equalm1m2letcompare(m1,i1)(m2,i2)=letc=Int.comparei1i2inifInt.equalc0thenMutInd.CanOrd.comparem1m2elseclethash(m,i)=Hashset.Combine.combine(MutInd.CanOrd.hashm)(Int.hashi)endmoduleUserOrd=structtypenonrect=tletequal(m1,i1)(m2,i2)=Int.equali1i2&&MutInd.UserOrd.equalm1m2letcompare(m1,i1)(m2,i2)=letc=Int.comparei1i2inifInt.equalc0thenMutInd.UserOrd.comparem1m2elseclethash(m,i)=Hashset.Combine.combine(MutInd.UserOrd.hashm)(Int.hashi)endmoduleSyntacticOrd=structtypenonrect=tletequal(m1,i1)(m2,i2)=Int.equali1i2&&MutInd.SyntacticOrd.equalm1m2letcompare(m1,i1)(m2,i2)=letc=Int.comparei1i2inifInt.equalc0thenMutInd.SyntacticOrd.comparem1m2elseclethash(m,i)=Hashset.Combine.combine(MutInd.SyntacticOrd.hashm)(Int.hashi)endletcanonize((mind,i)asind)=letmind'=MutInd.canonizemindinifmind'==mindthenindelse(mind',i)endmoduleConstruct=struct(** Designation of a (particular) constructor of a (particular) inductive type. *)typet=Ind.t(* designates the inductive type *)*int(* the index of the constructor
BEWARE: indexing starts from 1. *)letmodpath(ind,_)=Ind.modpathindmoduleCanOrd=structtypenonrect=tletequal(ind1,j1)(ind2,j2)=Int.equalj1j2&&Ind.CanOrd.equalind1ind2letcompare(ind1,j1)(ind2,j2)=letc=Int.comparej1j2inifInt.equalc0thenInd.CanOrd.compareind1ind2elseclethash(ind,i)=Hashset.Combine.combine(Ind.CanOrd.hashind)(Int.hashi)endmoduleUserOrd=structtypenonrect=tletequal(ind1,j1)(ind2,j2)=Int.equalj1j2&&Ind.UserOrd.equalind1ind2letcompare(ind1,j1)(ind2,j2)=letc=Int.comparej1j2inifInt.equalc0thenInd.UserOrd.compareind1ind2elseclethash(ind,i)=Hashset.Combine.combine(Ind.UserOrd.hashind)(Int.hashi)endmoduleSyntacticOrd=structtypenonrect=tletequal(ind1,j1)(ind2,j2)=Int.equalj1j2&&Ind.SyntacticOrd.equalind1ind2letcompare(ind1,j1)(ind2,j2)=letc=Int.comparej1j2inifInt.equalc0thenInd.SyntacticOrd.compareind1ind2elseclethash(ind,i)=Hashset.Combine.combine(Ind.SyntacticOrd.hashind)(Int.hashi)endletcanonize((ind,i)ascstr)=letind'=Ind.canonizeindinifind'==indthencstrelse(ind',i)end(** Designation of a (particular) inductive type. *)typeinductive=Ind.t(** Designation of a (particular) constructor of a (particular) inductive type. *)typeconstructor=Construct.tletith_mutual_inductive(mind,_)i=(mind,i)letith_constructor_of_inductiveindi=(ind,i)letinductive_of_constructor(ind,_i)=indletindex_of_constructor(_ind,i)=imoduleIndset=Set.Make(Ind.CanOrd)moduleIndset_env=Set.Make(Ind.UserOrd)moduleIndmap=Map.Make(Ind.CanOrd)moduleIndmap_env=Map.Make(Ind.UserOrd)moduleConstrset=Set.Make(Construct.CanOrd)moduleConstrset_env=Set.Make(Construct.UserOrd)moduleConstrmap=Map.Make(Construct.CanOrd)moduleConstrmap_env=Map.Make(Construct.UserOrd)(** {6 Hash-consing of name objects } *)moduleHind=Hashcons.Make(structtypet=inductivetypeu=MutInd.t->MutInd.tlethashconshmind(mind,i)=(hmindmind,i)leteq(mind1,i1)(mind2,i2)=mind1==mind2&&Int.equali1i2lethash=Ind.CanOrd.hashend)moduleHconstruct=Hashcons.Make(structtypet=constructortypeu=inductive->inductivelethashconshind(ind,j)=(hindind,j)leteq(ind1,j1)(ind2,j2)=ind1==ind2&&Int.equalj1j2lethash=Construct.CanOrd.hashend)lethcons_con=Constant.hconslethcons_mind=MutInd.hconslethcons_ind=Hashcons.simple_hconsHind.generateHind.hconshcons_mindlethcons_construct=Hashcons.simple_hconsHconstruct.generateHconstruct.hconshcons_ind(*****************)type'atableKey=|ConstKeyof'a|VarKeyofId.t|RelKeyofInt.ttypeinv_rel_key=int(* index in the [rel_context] part of environment
starting by the end, {\em inverse}
of de Bruijn indice *)leteq_table_keyfik1ik2=ifik1==ik2thentrueelsematchik1,ik2with|ConstKeyc1,ConstKeyc2->fc1c2|VarKeyid1,VarKeyid2->Id.equalid1id2|RelKeyk1,RelKeyk2->Int.equalk1k2|_->falselethash_table_keyfik=letopenHashset.Combineinmatchikwith|ConstKeyc->combinesmall1(fc)|VarKeyid->combinesmall2(Id.hashid)|RelKeyi->combinesmall3(Int.hashi)leteq_mind_chk=MutInd.UserOrd.equalleteq_ind_chk(kn1,i1)(kn2,i2)=Int.equali1i2&&eq_mind_chkkn1kn2(*******************************************************************)(** Compatibility layers *)leteq_constant_key=Constant.UserOrd.equal(** Compatibility layer for [ModPath] *)typemodule_path=ModPath.t=|MPfileofDirPath.t|MPboundofMBId.t|MPdotofmodule_path*Label.t(** Compatibility layer for [Constant] *)moduleProjection=structmoduleRepr=structtypet={proj_ind:inductive;proj_npars:int;proj_arg:int;proj_name:Constant.t;(** The only relevant data is the label, the rest is canonically derived
from proj_ind. *)}letmakeproj_ind~proj_npars~proj_argproj_name=letproj_name=KerPair.change_label(fstproj_ind)proj_namein{proj_ind;proj_npars;proj_arg;proj_name}letinductivec=c.proj_indletmindc=fstc.proj_indletconstantc=c.proj_nameletlabelc=Constant.labelc.proj_nameletnparsc=c.proj_nparsletargc=c.proj_arglethashp=Hashset.Combine.combinesmallp.proj_arg(Ind.CanOrd.hashp.proj_ind)letcompare_genab=letc=Int.comparea.proj_argb.proj_arginifc<>0thencelseletc=Int.comparea.proj_nparsb.proj_nparsinifc<>0thencelseLabel.compare(Constant.labela.proj_name)(Constant.labelb.proj_name)moduleSyntacticOrd=structtypenonrect=tletcompareab=letc=Ind.SyntacticOrd.comparea.proj_indb.proj_indinifc<>0thencelsecompare_genabletequalab=compareab==0lethashp=Hashset.Combine.combinesmallp.proj_arg(Ind.CanOrd.hashp.proj_ind)endmoduleCanOrd=structtypenonrect=tletcompareab=letc=Ind.CanOrd.comparea.proj_indb.proj_indinifc<>0thencelsecompare_genabletequalab=compareab==0lethashp=Hashset.Combine.combinesmallp.proj_arg(Ind.CanOrd.hashp.proj_ind)endmoduleUserOrd=structtypenonrect=tletcompareab=letc=Ind.UserOrd.comparea.proj_indb.proj_indinifc<>0thencelsecompare_genabletequalab=compareab==0lethashp=Hashset.Combine.combinesmallp.proj_arg(Ind.UserOrd.hashp.proj_ind)endletequal=CanOrd.equalletcompare=CanOrd.compareletcanonizep=let{proj_ind;proj_npars;proj_arg;proj_name}=pinletproj_ind'=Ind.canonizeproj_indinletproj_name'=Constant.canonizeproj_nameinifproj_ind'==proj_ind&&proj_name'==proj_namethenpelse{proj_ind=proj_ind';proj_name=proj_name';proj_npars;proj_arg}moduleSelf_Hashcons=structtypenonrect=ttypeu=(inductive->inductive)*(Constant.t->Constant.t)lethashcons(hind,hid)p={proj_ind=hindp.proj_ind;proj_npars=p.proj_npars;proj_arg=p.proj_arg;proj_name=hidp.proj_name}leteqpp'=p==p'||(p.proj_ind==p'.proj_ind&&p.proj_npars==p'.proj_npars&&p.proj_arg==p'.proj_arg&&p.proj_name==p'.proj_name)lethash=hashendmoduleHashRepr=Hashcons.Make(Self_Hashcons)lethcons=Hashcons.simple_hconsHashRepr.generateHashRepr.hcons(hcons_ind,Constant.hcons)letmap_nparsfp=letnpars=p.proj_nparsinletnpars'=fnparsinifnpars==npars'thenpelse{pwithproj_npars=npars'}letmapfp=letind=fstp.proj_indinletind'=findinifind==ind'thenpelseletproj_name=KerPair.change_labelind'(labelp)in{pwithproj_ind=(ind',sndp.proj_ind);proj_name}letto_stringp=Constant.to_string(constantp)letprintp=Constant.print(constantp)endtypet=Repr.t*boolletmakecb=(c,b)letmind(c,_)=Repr.mindcletinductive(c,_)=Repr.inductivecletnpars(c,_)=Repr.nparscletarg(c,_)=Repr.argcletconstant(c,_)=Repr.constantcletlabel(c,_)=Repr.labelcletrepr=fstletunfolded=sndletunfold(c,basp)=ifbthenpelse(c,true)letequal(c,b)(c',b')=Repr.equalcc'&&b==b'letrepr_equalpp'=Repr.equal(reprp)(reprp')lethash(c,b)=(ifbthen0else1)+Repr.hashcmoduleSyntacticOrd=structtypenonrect=tletcompare(p,b)(p',b')=letc=Bool.comparebb'inifc<>0thencelseRepr.SyntacticOrd.comparepp'letequal(c,basx)(c',b'asx')=x==x'||b=b'&&Repr.SyntacticOrd.equalcc'lethash(c,b)=(ifbthen0else1)+Repr.SyntacticOrd.hashcendmoduleCanOrd=structtypenonrect=tletcompare(p,b)(p',b')=letc=Bool.comparebb'inifc<>0thencelseRepr.CanOrd.comparepp'letequal(c,basx)(c',b'asx')=x==x'||b=b'&&Repr.CanOrd.equalcc'lethash(c,b)=(ifbthen0else1)+Repr.CanOrd.hashcendmoduleUserOrd=structtypenonrect=tletcompare(p,b)(p',b')=letc=Bool.comparebb'inifc<>0thencelseRepr.UserOrd.comparepp'letequal(c,basx)(c',b'asx')=x==x'||b=b'&&Repr.UserOrd.equalcc'lethash(c,b)=(ifbthen0else1)+Repr.UserOrd.hashcendmoduleSelf_Hashcons=structtypenonrect=ttypeu=Repr.t->Repr.tlethashconshc(c,b)=(hcc,b)leteq((c,b)asx)((c',b')asy)=x==y||(c==c'&&b==b')lethash=hashendletcanonize((r,u)asp)=letr'=Repr.canonizerinifr'==rthenpelse(r',u)moduleHashProjection=Hashcons.Make(Self_Hashcons)lethcons=Hashcons.simple_hconsHashProjection.generateHashProjection.hconsRepr.hconsletcompare(p,b)(p',b')=letc=Bool.comparebb'inifc<>0thencelseRepr.comparepp'letmapf(c,basx)=letc'=Repr.mapfcinifc'==cthenxelse(c',b)letmap_nparsf(c,basx)=letc'=Repr.map_nparsfcinifc'==cthenxelse(c',b)letto_stringp=Constant.to_string(constantp)letprintp=Constant.print(constantp)letdebug_to_stringp=(ifunfoldedpthen"unfolded("else"")^Constant.debug_to_string(constantp)^(ifunfoldedpthen")"else"")letdebug_printp=str(debug_to_stringp)endmodulePRmap=HMap.Make(Projection.Repr.CanOrd)modulePRset=PRmap.SetmodulePRpred=Predicate.Make(Projection.Repr.CanOrd)moduleGlobRefInternal=structtypet=|VarRefofvariable(** A reference to the section-context. *)|ConstRefofConstant.t(** A reference to the environment. *)|IndRefofinductive(** A reference to an inductive type. *)|ConstructRefofconstructor(** A reference to a constructor of an inductive type. *)letequalgr1gr2=gr1==gr2||matchgr1,gr2with|ConstRefcon1,ConstRefcon2->Constant.equalcon1con2|IndRefkn1,IndRefkn2->Ind.CanOrd.equalkn1kn2|ConstructRefkn1,ConstructRefkn2->Construct.CanOrd.equalkn1kn2|VarRefv1,VarRefv2->Id.equalv1v2|(ConstRef_|IndRef_|ConstructRef_|VarRef_),_->falseletglobal_eq_geneq_csteq_indeq_consxy=x==y||matchx,ywith|ConstRefcx,ConstRefcy->eq_cstcxcy|IndRefindx,IndRefindy->eq_indindxindy|ConstructRefconsx,ConstructRefconsy->eq_consconsxconsy|VarRefv1,VarRefv2->Id.equalv1v2|(VarRef_|ConstRef_|IndRef_|ConstructRef_),_->falseletglobal_ord_genord_cstord_indord_consxy=ifx==ythen0elsematchx,ywith|VarRefv1,VarRefv2->Id.comparev1v2|VarRef_,_->-1|_,VarRef_->1|ConstRefcx,ConstRefcy->ord_cstcxcy|ConstRef_,_->-1|_,ConstRef_->1|IndRefindx,IndRefindy->ord_indindxindy|IndRef_,_->-1|_,IndRef_->1|ConstructRefconsx,ConstructRefconsy->ord_consconsxconsyletglobal_hash_genhash_csthash_indhash_consgr=letopenHashset.Combineinmatchgrwith|ConstRefc->combinesmall1(hash_cstc)|IndRefi->combinesmall2(hash_indi)|ConstructRefc->combinesmall3(hash_consc)|VarRefid->combinesmall4(Id.hashid)endmoduleGlobRef=structtypet=GlobRefInternal.t=|VarRefofvariable(** A reference to the section-context. *)|ConstRefofConstant.t(** A reference to the environment. *)|IndRefofinductive(** A reference to an inductive type. *)|ConstructRefofconstructor(** A reference to a constructor of an inductive type. *)letequal=GlobRefInternal.equal(* By default, [global_reference] are ordered on their canonical part *)moduleCanOrd=structtypet=GlobRefInternal.tletcomparegr1gr2=GlobRefInternal.global_ord_genConstant.CanOrd.compareInd.CanOrd.compareConstruct.CanOrd.comparegr1gr2letequalgr1gr2=GlobRefInternal.global_eq_genConstant.CanOrd.equalInd.CanOrd.equalConstruct.CanOrd.equalgr1gr2lethashgr=GlobRefInternal.global_hash_genConstant.CanOrd.hashInd.CanOrd.hashConstruct.CanOrd.hashgrendmoduleUserOrd=structtypet=GlobRefInternal.tletcomparegr1gr2=GlobRefInternal.global_ord_genConstant.UserOrd.compareInd.UserOrd.compareConstruct.UserOrd.comparegr1gr2letequalgr1gr2=GlobRefInternal.global_eq_genConstant.UserOrd.equalInd.UserOrd.equalConstruct.UserOrd.equalgr1gr2lethashgr=GlobRefInternal.global_hash_genConstant.UserOrd.hashInd.UserOrd.hashConstruct.UserOrd.hashgrendmoduleSyntacticOrd=structtypet=GlobRefInternal.tletcomparegr1gr2=GlobRefInternal.global_ord_genConstant.SyntacticOrd.compareInd.SyntacticOrd.compareConstruct.SyntacticOrd.comparegr1gr2letequalgr1gr2=GlobRefInternal.global_eq_genConstant.SyntacticOrd.equalInd.SyntacticOrd.equalConstruct.SyntacticOrd.equalgr1gr2lethashgr=GlobRefInternal.global_hash_genConstant.SyntacticOrd.hashInd.SyntacticOrd.hashConstruct.SyntacticOrd.hashgrendletcanonizegr=matchgrwith|VarRef_->gr|ConstRefc->letc'=Constant.canonizecinifc'==cthengrelseConstRefc'|IndRefind->letind'=Ind.canonizeindinifind'==indthengrelseIndRefind'|ConstructRefc->letc'=Construct.canonizecinifc'==cthengrelseConstructRefc'letis_bound=function|VarRef_->false|ConstRefcst->ModPath.is_bound(Constant.modpathcst)|IndRef(ind,_)|ConstructRef((ind,_),_)->ModPath.is_bound(MutInd.modpathind)moduleMap=HMap.Make(CanOrd)moduleSet=Map.Set(* Alternative sets and maps indexed by the user part of the kernel names *)moduleMap_env=HMap.Make(UserOrd)moduleSet_env=Map_env.Setletprint=function|VarRefx->Id.printx|ConstRefx->Constant.printx|IndRef(m,i)->surround(MutInd.printm++strbrk", "++inti)|ConstructRef((m,i),j)->surround(MutInd.printm++strbrk", "++inti++strbrk", "++intj)end(** Located identifiers and objects with syntax. *)typelident=Id.tCAst.ttypelname=Name.tCAst.ttypelstring=stringCAst.tletlident_eq=CAst.eqId.equal