123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140(************************************************************************)(* * 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) *)(************************************************************************)openUnivtypet={subst:Universe.toptionLevel.Map.t;algs:Level.Set.t;}letempty={subst=Level.Map.empty;algs=Level.Set.empty;}letis_empty{subst}=Level.Map.is_emptysubstletdomain{subst}=Level.Map.domainsubstletmeml{subst}=Level.Map.memlsubstletfoldf{subst}acc=Level.Map.fold(funlvacc->fl~is_defined:(Option.has_somev)acc)substaccletis_algebraicl{algs}=Level.Set.memlalgsletmake_nonalgebraic_variable{subst;algs}l={subst;algs=Level.Set.removelalgs}letmake_all_undefined_nonalgebraic{subst;algs=_}={subst;algs=Level.Set.empty}letfix_undefined_variablesus=Level.Map.fold(funuv({subst;algs}asacc)->matchvwith|None->{subst=Level.Map.removeusubst;algs=Level.Set.removeualgs}|Some_->acc)us.substusletaddl~algebraic{subst;algs}=letsubst=Level.Map.updatel(function|None->SomeNone|Some_->assertfalse)substinletalgs=ifalgebraicthenLevel.Set.addlalgselsealgsin{subst;algs}letadd_levelslevels~algebraicsubst=Level.Set.fold(funlsubst->addl~algebraicsubst)levelssubstletdefinelv{subst;algs}=(* XXX update algs? *)letsubst=tryLevel.Map.modifyl(fun_old->assert(Option.is_emptyold);Somev)substwithNot_found->assertfalsein{subst;algs}letconstrain_variablesdiffusctx=(* XXX update algs? *)Level.Set.fold(funl((univs,cstrs),{subst;algs}asacc)->matchLevel.Map.find_optlsubstwith|None|SomeNone->acc|Some(Someu)->matchUniverse.leveluwith|None->acc|Someu->((Level.Set.addlunivs,Constraints.add(l,Eq,u)cstrs),{subst=Level.Map.removelsubst;algs}))diff(ctx,us)letbiased_union{subst=lsubst;algs=lalgs}{subst=rsubst;algs=ralgs}=letsubst=Level.Map.union(fun_klr->matchl,rwith|Some_,_->Somel|None,None->Somel|_,_->Somer)lsubstrsubstin{subst;algs=Level.Set.unionlalgsralgs}letnormalize_univ_variable~find=letrecauxcur=findcur|>Option.map(funb->letb'=UnivSubst.subst_univs_universeauxbinifUniverse.equalb'bthenbelseb')inauxletnormalize_univ_variableectx=letfindl=Option.flatten(Univ.Level.Map.find_optlectx.subst)innormalize_univ_variable~findletnormalize_universesubst=letnormlevel=normalize_univ_variablesubstinUnivSubst.subst_univs_universenormlevelletnormalizectx=letnormalize=normalize_universectxinletsubst=Univ.Level.Map.mapi(funu->function|None->None|Somev->Some(normalizev))ctx.substin{subst;algs=ctx.algs}letnormalize_univ_variablesctx=letctx=normalizectxinletdef,subst=Univ.Level.Map.fold(funuv(def,subst)->matchvwith|None->(def,subst)|Someb->(Univ.Level.Set.addudef,Univ.Level.Map.addubsubst))ctx.subst(Univ.Level.Set.empty,Univ.Level.Map.empty)inletsubstl=Level.Map.find_optlsubstinctx,def,substletprprl{subst;algs}=letopenPpinletppsubst=Level.Map.prprl(function|None->mt()|Somex->str" := "++Universe.prprlx)substinstr"ALGEBRAIC UNIVERSES:"++brk(0,1)++h(Level.Set.prprlalgs)++fnl()++str"FLEXIBLE UNIVERSES:"++brk(0,1)++hppsubst