123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261(************************************************************************)(* * 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) *)(************************************************************************)openSortsopenUtilopenConstropenUnivopenUVarstype'auniverse_map='aLevel.Map.ttypeuniverse_subst=Universe.tuniverse_maptypeuniverse_subst_fn=Level.t->Universe.toptiontypeuniverse_level_subst_fn=Level.t->Level.ttypequality_subst=Quality.tQVar.Map.ttypequality_subst_fn=QVar.t->Quality.tletsubst_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(None,(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(None,(Eq,s1,s2,None)))|(QSort_,(Set|Type_))|((Set|Type_),QSort_)->raise(UGraph.UniverseInconsistency(None,(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(None,(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(None,(Eq,s1,s2,None)))|(QSort_,(Set|Type_))|((Prop|Set|Type_),QSort_)->raise(UGraph.UniverseInconsistency(None,(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(None,(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(None,(Eq,s1,s2,None)))|(QSort_,(Set|Type_))|((Prop|Set|Type_),QSort_)->raise(UGraph.UniverseInconsistency(None,(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->lletsubst_univs_fn_puniversesf(c,uascu)=letu'=Instance.subst_fnfuinifu'==uthencuelse(c,u')letmap_universes_opt_subst_with_bindersnextauxfqualfunivkc=letfrel=Sorts.relevance_subst_fnfqualinletflevel=fqual,level_subst_offunivinletaux_rec((nas,tys,bds)asrc)=letnas'=Array.Smart.map(Context.map_annot_relevance_smartfrel)nasinlettys'=Array.Fun1.Smart.mapauxktysinletk'=iteratenext(Array.lengthtys')kinletbds'=Array.Fun1.Smart.mapauxk'bdsinifnas'==nas&&tys'==tys&&bds'==bdsthenrcelse(nas',tys',bds')inletaux_ctx((nas,c)asp)=letnas'=Array.Smart.map(Context.map_annot_relevance_smartfrel)nasinletk'=iteratenext(Array.lengthnas)kinletc'=auxk'cinifnas'==nas&&c'==cthenpelse(nas',c')inmatchkindcwith|Constpu->letpu'=subst_univs_fn_puniversesflevelpuinifpu'==puthencelsemkConstUpu'|Indpu->letpu'=subst_univs_fn_puniversesflevelpuinifpu'==puthencelsemkIndUpu'|Constructpu->letpu'=subst_univs_fn_puniversesflevelpuinifpu'==puthencelsemkConstructUpu'|Sorts->lets'=Sorts.subst_fn(fqual,subst_univs_universefuniv)sinifs'==sthencelsemkSorts'|Case(ci,u,pms,(p,rel),iv,t,br)->letu'=Instance.subst_fnfleveluinletrel'=frelrelinletpms'=Array.Fun1.Smart.mapauxkpmsinletp'=aux_ctxpinletiv'=map_invert(auxk)ivinlett'=auxktinletbr'=Array.Smart.mapaux_ctxbrinifrel'==rel&&u'==u&&pms'==pms&&p'==p&&iv'==iv&&t'==t&&br'==brthencelsemkCase(ci,u',pms',(p',rel'),iv',t',br')|Array(u,elems,def,ty)->letu'=Instance.subst_fnfleveluinletelems'=CArray.Fun1.Smart.mapauxkelemsinletdef'=auxkdefinletty'=auxktyinifu==u'&&elems==elems'&&def==def'&&ty==ty'thencelsemkArray(u',elems',def',ty')|Prod(na,t,u)->letna'=Context.map_annot_relevance_smartfrelnainlett'=auxktinletu'=aux(nextk)uinifna'==na&&t'==t&&u'==uthencelsemkProd(na',t',u')|Lambda(na,t,u)->letna'=Context.map_annot_relevance_smartfrelnainlett'=auxktinletu'=aux(nextk)uinifna'==na&&t'==t&&u'==uthencelsemkLambda(na',t',u')|LetIn(na,b,t,u)->letna'=Context.map_annot_relevance_smartfrelnainletb'=auxkbinlett'=auxktinletu'=aux(nextk)uinifna'==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')|Proj(p,r,v)->letr'=frelrinletv'=auxkvinifr'==r&&v'==vthencelsemkProj(p,r',v')|_->Constr.map_with_bindersnextauxkcletnf_evars_and_universes_opt_substfevarfqualfunivc=letrecself()c=matchConstr.kindcwith|Evar(evk,args)->letargs'=SList.Smart.map(self())argsinbeginmatchtryfevar(evk,args')withNot_found->Nonewith|None->ifargs==args'thencelsemkEvar(evk,args')|Somec->self()cend|_->map_universes_opt_subst_with_bindersignoreselffqualfuniv()cinself()cletpr_universe_substprl=letopenPpinLevel.Map.prprl(funu->str" := "++Universe.prprlu++spc())