123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289(************************************************************************)(* * 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) *)(************************************************************************)openSortsopenUtilopenConstropenUnivtype'auniverse_map='aLevel.Map.ttypeuniverse_subst=Universe.tuniverse_maptypeuniverse_subst_fn=Level.t->Universe.toptiontypeuniverse_level_subst_fn=Level.t->Level.tletsubst_instancefni=Instance.of_array(Array.Smart.mapfn(Instance.to_arrayi))letsubst_univs_universefnul=letaddnnu=iterateUniverse.supernuinletsubst,nosubst=List.fold_right(fun(u,n)(subst,nosubst)->matchfnuwith|Someu'->leta'=addnnu'in(a'::subst,nosubst)|None->(subst,(u,n)::nosubst))(Universe.reprul)([],[])inmatchsubstwith|[]->ul|u::ul->letsubsts=List.fold_leftUniverse.supusubstinList.fold_left(funacc(u,n)->Universe.supacc(addnn(Universe.makeu)))substsnosubstletenforce_equvc=ifUniverse.equaluvthencelsematchUniverse.levelu,Universe.levelvwith|Someu,Somev->enforce_eq_leveluvc|_->CErrors.anomaly(Pp.str"A universe comparison can only happen between variables.")letconstraint_add_leqvuc=leteq(x,n)(y,m)=Int.equalmn&&Level.equalxyin(* We just discard trivial constraints like u<=u *)ifeqvuthencelsematchv,uwith|(x,n),(y,m)->letj=m-ninifj=-1(* n = m+1, v+1 <= u <-> v < u *)thenConstraints.add(x,Lt,y)celseifj<=-1(* n = m+k, v+k <= u and k>0 *)thenifLevel.equalxythen(* u+k <= u with k>0 *)Constraints.add(x,Lt,x)celseCErrors.anomaly(Pp.str"Unable to handle arbitrary u+k <= v constraints.")elseifj=0thenConstraints.add(x,Le,y)celse(* j >= 1 *)(* m = n + k, u <= v+k *)ifLevel.equalxythenc(* u <= u+k, trivial *)elseifLevel.is_setxthenc(* Prop,Set <= u+S k, trivial *)elseConstraints.add(x,Le,y)c(* u <= v implies u <= v+k *)letcheck_univ_leq_oneuv=letleq(u,n)(v,n')=letcmp=Level.compareuvinifInt.equalcmp0thenn<=n'elsefalseinUniverse.exists(lequ)vletcheck_univ_lequv=Universe.for_all(funu->check_univ_leq_oneuv)uletenforce_lequvc=List.fold_left(funcv->(List.fold_left(funcu->constraint_add_lequvc)cu))cvletenforce_lequvc=ifcheck_univ_lequvthencelseenforce_leq(Universe.repru)(Universe.reprv)cletget_algebraic=function|Prop|SProp|QSort_->assertfalse|Set->Universe.type0|Typeu->uletenforce_eq_sorts1s2cst=matchs1,s2with|(SProp,SProp)|(Prop,Prop)|(Set,Set)->cst|(((Prop|Set|Type_|QSort_)ass1),(Prop|SPropass2))|((Prop|SPropass1),((Prop|Set|Type_|QSort_)ass2))->raise(UGraph.UniverseInconsistency(Eq,s1,s2,None))|(Set|Type_),(Set|Type_)->enforce_eq(get_algebraics1)(get_algebraics2)cst|QSort(q1,u1),QSort(q2,u2)->ifQVar.equalq1q2thenenforce_equ1u2cstelseraise(UGraph.UniverseInconsistency(Eq,s1,s2,None))|(QSort_,(Set|Type_))|((Set|Type_),QSort_)->raise(UGraph.UniverseInconsistency(Eq,s1,s2,None))letenforce_leq_sorts1s2cst=matchs1,s2with|(SProp,SProp)|(Prop,Prop)|(Set,Set)->cst|(Prop,(Set|Type_))->cst|(((Prop|Set|Type_|QSort_)ass1),(Prop|SPropass2))|((SPropass1),((Prop|Set|Type_|QSort_)ass2))->raise(UGraph.UniverseInconsistency(Le,s1,s2,None))|(Set|Type_),(Set|Type_)->enforce_leq(get_algebraics1)(get_algebraics2)cst|QSort(q1,u1),QSort(q2,u2)->ifQVar.equalq1q2thenenforce_lequ1u2cstelseraise(UGraph.UniverseInconsistency(Eq,s1,s2,None))|(QSort_,(Set|Type_))|((Prop|Set|Type_),QSort_)->raise(UGraph.UniverseInconsistency(Eq,s1,s2,None))letenforce_leq_alg_sorts1s2g=matchs1,s2with|(SProp,SProp)|(Prop,Prop)|(Set,Set)->Constraints.empty,g|(Prop,(Set|Type_))->Constraints.empty,g|(((Prop|Set|Type_|QSort_)ass1),(Prop|SPropass2))|((SPropass1),((Prop|Set|Type_|QSort_)ass2))->raise(UGraph.UniverseInconsistency(Le,s1,s2,None))|(Set|Type_),(Set|Type_)->UGraph.enforce_leq_alg(get_algebraics1)(get_algebraics2)g|QSort(q1,u1),QSort(q2,u2)->ifQVar.equalq1q2thenUGraph.enforce_leq_algu1u2gelseraise(UGraph.UniverseInconsistency(Eq,s1,s2,None))|(QSort_,(Set|Type_))|((Prop|Set|Type_),QSort_)->raise(UGraph.UniverseInconsistency(Eq,s1,s2,None))letenforce_univ_constraint(u,d,v)=matchdwith|Eq->enforce_equv|Le->enforce_lequv|Lt->enforce_leq(Universe.superu)vletsubst_univs_constraintfn(u,d,vasc)cstrs=letu'=fnuinletv'=fnvinmatchu',v'with|None,None->Constraints.addccstrs|Someu,None->enforce_univ_constraint(u,d,Universe.makev)cstrs|None,Somev->enforce_univ_constraint(Universe.makeu,d,v)cstrs|Someu,Somev->enforce_univ_constraint(u,d,v)cstrsletsubst_univs_constraintssubstcsts=Constraints.fold(funccstrs->subst_univs_constraintsubstccstrs)cstsConstraints.emptyletlevel_subst_off=funl->matchflwith|None->l|Someu->matchUniverse.leveluwith|None->assertfalse|Somel->lletnormalize_univ_variable~find=letrecauxcur=findcur|>Option.map(funb->letb'=subst_univs_universeauxbinifUniverse.equalb'bthenbelseb')inauxtypeuniverse_opt_subst=Universe.toptionuniverse_mapletnormalize_univ_variable_opt_substectx=letfindl=Option.flatten(Univ.Level.Map.find_optlectx)innormalize_univ_variable~findletnormalize_universe_opt_substsubst=letnormlevel=normalize_univ_variable_opt_substsubstinsubst_univs_universenormlevelletnormalize_opt_substctx=letnormalize=normalize_universe_opt_substctxinUniv.Level.Map.mapi(funu->function|None->None|Somev->Some(normalizev))ctxletnormalize_univ_variablesctx=letctx=normalize_opt_substctxinletdef,subst=Univ.Level.Map.fold(funuv(def,subst)->matchvwith|None->(def,subst)|Someb->(Univ.Level.Set.addudef,Univ.Level.Map.addubsubst))ctx(Univ.Level.Set.empty,Univ.Level.Map.empty)inctx,def,substletsubst_univs_fn_puniversesf(c,uascu)=letu'=subst_instancefuinifu'==uthencuelse(c,u')letnf_binder_annotfrelna=letopenContextinletrel'=frelna.binder_relevanceinifrel'==na.binder_relevancethennaelse{binder_name=na.binder_name;binder_relevance=rel'}letnf_evars_and_universes_opt_substfevarflevelfsortfrelc=letrecauxc=matchkindcwith|Evar(evk,args)->letargs'=SList.Smart.mapauxargsin(matchtryfevar(evk,args')withNot_found->Nonewith|None->ifargs==args'thencelsemkEvar(evk,args')|Somec->auxc)|Constpu->letpu'=subst_univs_fn_puniversesflevelpuinifpu'==puthencelsemkConstUpu'|Indpu->letpu'=subst_univs_fn_puniversesflevelpuinifpu'==puthencelsemkIndUpu'|Constructpu->letpu'=subst_univs_fn_puniversesflevelpuinifpu'==puthencelsemkConstructUpu'|Sorts->lets'=fsortsinifs'==sthencelsemkSorts'|Case(ci,u,pms,p,iv,t,br)->letu'=subst_instancefleveluinletci'=letrel'=frelci.ci_relevanceinifrel'==ci.ci_relevancethencielse{ciwithci_relevance=rel'}inletpms'=Array.Smart.mapauxpmsinletp'=aux_ctxpinletiv'=map_invertauxivinlett'=auxtinletbr'=Array.Smart.mapaux_ctxbrinifci'==ci&&u'==u&&pms'==pms&&p'==p&&iv'==iv&&t'==t&&br'==brthencelsemkCase(ci',u',pms',p',iv',t',br')|Array(u,elems,def,ty)->letu'=subst_instancefleveluinletelems'=CArray.Smart.mapauxelemsinletdef'=auxdefinletty'=auxtyinifu==u'&&elems==elems'&&def==def'&&ty==ty'thencelsemkArray(u',elems',def',ty')|Prod(na,t,u)->letna'=nf_binder_annotfrelnainlett'=auxtinletu'=auxuinifna'==na&&t'==t&&u'==uthencelsemkProd(na',t',u')|Lambda(na,t,u)->letna'=nf_binder_annotfrelnainlett'=auxtinletu'=auxuinifna'==na&&t'==t&&u'==uthencelsemkLambda(na',t',u')|LetIn(na,b,t,u)->letna'=nf_binder_annotfrelnainletb'=auxbinlett'=auxtinletu'=auxuinifna'==na&&b'==b&&t'==t&&u'==uthencelsemkLetIn(na',b',t',u')|Fix(i,rc)->letrc'=aux_recrcinifrc'==rcthencelsemkFix(i,rc')|CoFix(i,rc)->letrc'=aux_recrcinifrc'==rcthencelsemkCoFix(i,rc')|_->Constr.mapauxcandaux_rec((nas,tys,bds)asrc)=letnas'=Array.Smart.map(funna->nf_binder_annotfrelna)nasinlettys'=Array.Smart.mapauxtysinletbds'=Array.Smart.mapauxbdsinifnas'==nas&&tys'==tys&&bds'==bdsthenrcelse(nas',tys',bds')andaux_ctx((nas,c)asp)=letnas'=Array.Smart.map(funna->nf_binder_annotfrelna)nasinletc'=auxcinifnas'==nas&&c'==cthenpelse(nas',c')inauxcletpr_universe_substprl=letopenPpinLevel.Map.prprl(funu->str" := "++Universe.prprlu++spc())