12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721(************************************************************************)(* * 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) *)(************************************************************************)openPpopenCErrorsopenSortsopenUtilopenNamesopenNameopsopenConstropenVarsopenEnviron(* module RelDecl = Context.Rel.Declaration *)moduleNamedDecl=Context.Named.Declarationtypeeconstr=constrtypeetypes=types(** Generic filters *)moduleFilter:sigtypetvalequal:t->t->boolvalidentity:tvalfilter_list:t->'alist->'alistvalfilter_array:t->'aarray->'aarrayvalfilter_slist:t->'aSList.t->'aSList.tvalextend:int->t->tvalcompose:t->t->tvalapply_subfilter:t->boollist->tvalrestrict_upon:t->int->(int->bool)->toptionvalmap_along:(bool->'a->bool)->t->'alist->tvalmake:boollist->tvalrepr:t->boollistoptiontypecompact=|Empty|TConsofint*compact|FConsofint*compactvalunfold:t->compactoptionend=structtypecompact=|Empty|TConsofint*compact|FConsofint*compactletreccompactl=matchlwith|[]->Empty|true::l->beginmatchcompactlwith|TCons(n,c)->TCons(n+1,c)|(Empty|FCons_asc)->TCons(1,c)end|false::l->beginmatchcompactlwith|FCons(n,c)->FCons(n+1,c)|(Empty|TCons_asc)->FCons(1,c)endtypet={data:boollistoption;compact:compact;}(** We guarantee through the interface that if a filter is [Some _] then it
contains at least one [false] somewhere. *)letidentity={data=None;compact=Empty}letrecequall1l2=matchl1,l2with|[],[]->true|h1::l1,h2::l2->(ifh1thenh2elsenoth2)&&equall1l2|_->falseletequall1l2=matchl1.data,l2.datawith|None,None->true|Some_,None|None,Some_->false|Somel1,Somel2->equall1l2letrecis_identity=function|[]->true|true::l->is_identityl|false::_->falseletnormalizef=ifis_identityfthenidentityelse{data=Somef;compact=compactf}letfilter_listfl=matchf.datawith|None->l|Somef->CList.filter_withflletfilter_arrayfv=matchf.datawith|None->v|Somef->CArray.filter_withfvletfilter_slistfl=matchf.datawith|None->l|Somef->letrecfilterfl=matchf,SList.viewlwith|[],None->SList.empty|true::f,Some(o,l)->SList.cons_opto(filterfl)|false::f,Some(_,l)->filterfl|_::_,None|[],Some_->invalid_arg"List.filter_with"infilterflletrecextendnl=ifn=0thenlelseextend(predn)(true::l)letextendnf=matchf.datawith|None->identity|Somef0->letcompact=matchf.compactwith|Empty->assertfalse|TCons(m,c)->TCons(n+m,c)|c->TCons(n,c)in{data=Some(extendnf0);compact}letcomposef1f2=matchf1.datawith|None->f2|Somef1->matchf2.datawith|None->identity|Somef2->normalize(CList.filter_withf1f2)letapply_subfilter_arrayfiltersubfilter=(* In both cases we statically know that the argument will contain at
least one [false] *)matchfilter.datawith|None->letl=Array.to_listsubfilterin{data=Somel;compact=compactl}|Somef->letlen=Array.lengthsubfilterinletfoldb(i,ans)=ifbthenlet()=assert(0<=i)in(predi,Array.unsafe_getsubfilteri::ans)else(i,false::ans)inletdata=snd(List.fold_rightfoldf(predlen,[]))in{data=Somedata;compact=compactdata}letapply_subfilterfiltersubfilter=apply_subfilter_arrayfilter(Array.of_listsubfilter)letrestrict_uponflenp=letnewfilter=Array.initlenpinifArray.for_all(funid->id)newfilterthenNoneelseSome(apply_subfilter_arrayfnewfilter)letmap_alongffltl=letans=matchflt.datawith|None->List.map(funx->ftruex)l|Someflt->List.map2ffltlinnormalizeansletmakel=normalizelletreprf=f.dataletunfoldf=matchf.datawith|None->None|Some_->Somef.compactendmoduleAbstraction=structtypeabstraction=|Abstract|Imitatetypet=abstractionlistletidentity=[]letabstract_lastl=Abstract::lend(* The kinds of existential variables are now defined in [Evar_kinds] *)(* The type of mappings for existential variables *)moduleStore=Store.Make()letstring_of_existentialevk="?X"^string_of_int(Evar.reprevk)typeevar_body=|Evar_empty|Evar_definedofconstrtypeevar_info={evar_concl:constr;evar_hyps:named_context_val;evar_body:evar_body;evar_filter:Filter.t;evar_abstract_arguments:Abstraction.t;evar_source:Evar_kinds.tLoc.located;evar_candidates:constrlistoption;(* if not None, list of allowed instances *)evar_relevance:Sorts.relevance;}letinstance_mismatch()=anomaly(Pp.str"Signature and its instance do not match.")letevar_conclevi=evi.evar_conclletevar_filterevi=evi.evar_filterletevar_bodyevi=evi.evar_bodyletevar_contextevi=named_context_of_valevi.evar_hypsletevar_filtered_contextevi=Filter.filter_list(evar_filterevi)(evar_contextevi)letevar_candidatesevi=evi.evar_candidatesletevar_abstract_argumentsevi=evi.evar_abstract_argumentsletevar_relevanceevi=evi.evar_relevanceletevar_hypsevi=evi.evar_hypsletevar_filtered_hypsevi=matchFilter.repr(evar_filterevi)with|None->evar_hypsevi|Somefilter->letrecmake_hypsfilterctxt=matchfilter,ctxtwith|[],[]->empty_named_context_val|false::filter,_::ctxt->make_hypsfilterctxt|true::filter,decl::ctxt->lethyps=make_hypsfilterctxtinpush_named_context_valdeclhyps|_->instance_mismatch()inmake_hypsfilter(evar_contextevi)letevar_envenvevi=Environ.reset_with_named_contextevi.evar_hypsenvletevar_filtered_envenvevi=Environ.reset_with_named_context(evar_filtered_hypsevi)envletevar_identity_substevi=letlen=matchFilter.reprevi.evar_filterwith|None->List.length@@Environ.named_context_of_valevi.evar_hyps|Somef->List.count(funb->b)finSList.defaultnlenSList.emptyletmap_evar_bodyf=function|Evar_empty->Evar_empty|Evar_definedd->Evar_defined(fd)letmap_evar_infofevi={eviwithevar_body=map_evar_bodyfevi.evar_body;evar_hyps=map_named_val(fund->NamedDecl.map_constrfd)evi.evar_hyps;evar_concl=fevi.evar_concl;evar_candidates=Option.map(List.mapf)evi.evar_candidates}(* This exception is raised by *.existential_value *)exceptionNotInstantiatedEvar(* Note: let-in contributes to the instance *)letevar_instance_arrayinfoargs=letrecinstrecposfilterargs=matchfilterwith|Filter.Empty->ifSList.is_emptyargsthen[]elseinstance_mismatch()|Filter.TCons(n,filter)->instpushposnfilterargs|Filter.FCons(n,filter)->instrec(pos+n)filterargsandinstpushposnfilterargs=ifn<=0theninstrecposfilterargselsematchargswith|SList.Nil->assertfalse|SList.Cons(c,args)->letd=Range.getinfo.evar_hyps.env_named_idxposinletid=NamedDecl.get_iddinifisVarIdidctheninstpush(pos+1)(n-1)filterargselse(id,c)::instpush(pos+1)(n-1)filterargs|SList.Default(m,args)->ifm<=ntheninstpush(pos+m)(n-m)filterargselseinstrec(pos+n)filter(SList.defaultn(m-n)args)inmatchFilter.unfold(evar_filterinfo)with|None->letrecinstanceposargs=matchargswith|SList.Nil->[]|SList.Cons(c,args)->letd=Range.getinfo.evar_hyps.env_named_idxposinletid=NamedDecl.get_iddinifisVarIdidctheninstance(pos+1)argselse(id,c)::instance(pos+1)args|SList.Default(n,args)->instance(pos+n)argsininstance0args|Somefilter->instrec0filterargsletmake_evar_instance_arrayinfoargs=ifSList.is_defaultargsthen[]elseevar_instance_arrayinfoargstype'ain_evar_universe_context='a*UState.t(*******************************************************************)(* Metamaps *)(*******************************************************************)(* Constraints for existential variables *)(*******************************************************************)type'afreelisted={rebus:'a;freemetas:Int.Set.t}(* Collects all metavars appearing in a constr *)letmetavars_ofc=letreccollrecaccc=matchkindcwith|Metamv->Int.Set.addmvacc|_->Constr.foldcollrecacccincollrecInt.Set.emptycletmk_freelistedc={rebus=c;freemetas=metavars_ofc}letmap_flfcfl={cflwithrebus=fcfl.rebus}(* Status of an instance found by unification wrt to the meta it solves:
- a supertype of the meta (e.g. the solution to ?X <= T is a supertype of ?X)
- a subtype of the meta (e.g. the solution to T <= ?X is a supertype of ?X)
- a term that can be eta-expanded n times while still being a solution
(e.g. the solution [P] to [?X u v = P u v] can be eta-expanded twice)
*)typeinstance_constraint=IsSuperType|IsSubType|Convleteq_instance_constraintc1c2=c1==c2(* Status of the unification of the type of an instance against the type of
the meta it instantiates:
- CoerceToType means that the unification of types has not been done
and that a coercion can still be inserted: the meta should not be
substituted freely (this happens for instance given via the
"with" binding clause).
- TypeProcessed means that the information obtainable from the
unification of types has been extracted.
- TypeNotProcessed means that the unification of types has not been
done but it is known that no coercion may be inserted: the meta
can be substituted freely.
*)typeinstance_typing_status=CoerceToType|TypeNotProcessed|TypeProcessed(* Status of an instance together with the status of its type unification *)typeinstance_status=instance_constraint*instance_typing_status(* Clausal environments *)typeclbinding=|CltypofName.t*constrfreelisted|ClvalofName.t*(constrfreelisted*instance_status)*constrfreelistedletmap_clbf=function|Cltyp(na,cfl)->Cltyp(na,map_flfcfl)|Clval(na,(cfl1,pb),cfl2)->Clval(na,(map_flfcfl1,pb),map_flfcfl2)(* name of defined is erased (but it is pretty-printed) *)letclb_name=functionCltyp(na,_)->(na,false)|Clval(na,_,_)->(na,true)(***********************)moduleMetaset=Int.SetmoduleMetamap=Int.Map(*************************)(* Unification state *)typeconv_pb=Reduction.conv_pbtypeevar_constraint=conv_pb*Environ.env*constr*constrmoduleEvMap=Evar.MapmoduleEvNames:sigtypetvalempty:tvaladd_name_undefined:Id.toption->Evar.t->evar_info->t->tvalremove_name_defined:Evar.t->t->tvalrename:Evar.t->Id.t->t->tvalreassign_name_defined:Evar.t->Evar.t->t->tvalident:Evar.t->t->Id.toptionvalkey:Id.t->t->Evar.tend=structtypet=Id.tEvMap.t*Evar.tId.Map.tletempty=(EvMap.empty,Id.Map.empty)letadd_name_newly_undefinedidevkevi(evtoid,idtoevasnames)=matchidwith|None->names|Someid->ifId.Map.memididtoevthenuser_err(str"Already an existential evar of name "++Id.printid);(EvMap.addevkidevtoid,Id.Map.addidevkidtoev)letadd_name_undefinednamingevkevi(evtoid,idtoevasevar_names)=ifEvMap.memevkevtoidthenevar_nameselseadd_name_newly_undefinednamingevkevievar_namesletremove_name_definedevk(evtoid,idtoevasnames)=letid=trySome(EvMap.findevkevtoid)withNot_found->Noneinmatchidwith|None->names|Someid->(EvMap.removeevkevtoid,Id.Map.removeididtoev)letrenameevkid(evtoid,idtoev)=letid'=trySome(EvMap.findevkevtoid)withNot_found->Noneinmatchid'with|None->(EvMap.addevkidevtoid,Id.Map.addidevkidtoev)|Someid'->ifId.Map.memididtoevthenanomaly(str"Evar name already in use.");(EvMap.setevkidevtoid(* overwrite old name *),Id.Map.addidevk(Id.Map.removeid'idtoev))letreassign_name_definedevkevk'(evtoid,idtoevasnames)=letid=trySome(EvMap.findevkevtoid)withNot_found->Noneinmatchidwith|None->names(* evk' must not be defined *)|Someid->(EvMap.addevk'id(EvMap.removeevkevtoid),Id.Map.addidevk'(Id.Map.removeididtoev))letidentevk(evtoid,_)=trySome(EvMap.findevkevtoid)withNot_found->Noneletkeyid(_,idtoev)=Id.Map.findididtoevendtypeevar_flags={obligation_evars:Evar.Set.t;aliased_evars:Evar.tEvar.Map.t;typeclass_evars:Evar.Set.t}typeside_effect_role=|Schemaofinductive*stringtypeside_effects={seff_private:Safe_typing.private_constants;seff_roles:side_effect_roleCmap.t;}moduleFutureGoals:sigtypetvalcomb:t->Evar.tlistvalprincipal:t->Evar.toptionvalmap_filter:(Evar.t->Evar.toption)->t->t(** Applies a function on the future goals *)valfilter:(Evar.t->bool)->t->t(** Applies a filter on the future goals *)typestackvalempty_stack:stackvalpush:stack->stackvalpop:stack->t*stackvaladd:principal:bool->Evar.t->stack->stackvalremove:Evar.t->stack->stackvalfold:('a->Evar.t->'a)->'a->stack->'avalpr_stack:stack->Pp.tend=structtypet={uid:int;comb:Evar.tInt.Map.t;revmap:intEvar.Map.t;principal:Evar.toption;(** if [Some e], [e] must be
contained in
[comb]. The evar
[e] will inherit
properties (now: the
name) of the evar which
will be instantiated with
a term containing [e]. *)}letcombg=(* Keys are reversed, highest number is last introduced *)Int.Map.fold(fun_evkaccu->evk::accu)g.comb[]letprincipalg=g.principaltypestack=tlistletsetf=function|[]->anomalyPp.(str"future_goals stack should not be empty")|hd::tl->fhd::tlletadd~principalevkstack=letaddfgl=letcomb=Int.Map.addfgl.uidevkfgl.combinletrevmap=Evar.Map.addevkfgl.uidfgl.revmapinletprincipal=ifprincipalthenmatchfgl.principalwith|Some_->CErrors.user_errPp.(str"Only one main goal per instantiation.")|None->Someevkelsefgl.principalinletuid=fgl.uid+1inlet()=assert(0<=uid)in{comb;revmap;principal;uid}insetaddstackletremoveestack=letremovefgl=letfiltere'=not(Evar.equalee')inletprincipal=Option.filterfilterfgl.principalinletcomb,revmap=matchEvar.Map.findefgl.revmapwith|index->(Int.Map.removeindexfgl.comb,Evar.Map.removeefgl.revmap)|exceptionNot_found->fgl.comb,fgl.revmapin{principal;comb;revmap;uid=fgl.uid}inList.mapremovestackletempty={uid=0;principal=None;comb=Int.Map.empty;revmap=Evar.Map.empty;}letempty_stack=[empty]letpushstack=empty::stackletpopstack=matchstackwith|[]->anomalyPp.(str"future_goals stack should not be empty")|hd::tl->hd,tlletfoldfaccstack=letfuture_goals=List.hdstackinList.fold_leftfacc(combfuture_goals)letfilterffgl=letfoldindexevk(comb,revmap)=iffevkthen(comb,revmap)else(Int.Map.removeindexcomb,Evar.Map.removeevkrevmap)inlet(comb,revmap)=Int.Map.foldfoldfgl.comb(fgl.comb,fgl.revmap)inletprincipal=Option.filterffgl.principalin{comb;principal;revmap;uid=fgl.uid}letmap_filterffgl=letfoldindexevk(comb,revmap)=matchfevkwith|None->(comb,revmap)|Someevk'->(Int.Map.addindexevk'comb,Evar.Map.addevk'indexrevmap)inlet(comb,revmap)=Int.Map.foldfoldfgl.comb(Int.Map.empty,Evar.Map.empty)inletprincipal=Option.bindfgl.principalfin{comb;revmap;principal;uid=fgl.uid}letpr_stackstack=letopenPpinletpr_future_goalsfgl=letcomb=combfglinprlist_with_sepspcEvar.printcomb++pr_opt(funev->str"(principal: "++Evar.printev++str")")fgl.principalinifList.is_emptystackthenstr"(empty stack)"elseprlist_with_sep(fun()->str"||")pr_future_goalsstackendtypeevar_map={(* Existential variables *)defn_evars:evar_infoEvMap.t;undf_evars:evar_infoEvMap.t;evar_names:EvNames.t;(** Universes *)universes:UState.t;(** Conversion problems *)conv_pbs:evar_constraintlist;last_mods:Evar.Set.t;(** Metas *)metas:clbindingMetamap.t;evar_flags:evar_flags;(** Interactive proofs *)effects:side_effects;future_goals:FutureGoals.stack;(** list of newly created evars, to be
eventually turned into goals if not solved.*)given_up:Evar.Set.t;shelf:Evar.tlistlist;extras:Store.t;}letfindde=tryEvMap.finded.undf_evarswithNot_found->EvMap.finded.defn_evarsletrecthin_val=function|[]->[]|(id,c)::tl->matchConstr.kindcwith|Constr.Varv->ifId.equalidvthenthin_valtlelse(id,make_substituendc)::(thin_valtl)|_->(id,make_substituendc)::(thin_valtl)letrecfind_varid=function|[]->raise_notraceNot_found|(idc,c)::subst->ifId.equalididcthencelsefind_varidsubstletreplace_varssigmavar_alistx=letvar_alist=thin_valvar_alistinmatchvar_alistwith|[]->x|_->letrecsubstrecnc=matchConstr.kindcwith|Constr.Varid->beginmatchfind_varidvar_alistwith|var->(lift_substituendnvar)|exceptionNot_found->cend|Constr.Evar(evk,args)->letevi=findsigmaevkinletargs'=substrec_instancen(evar_filtered_contextevi)argsinifargs'==argsthencelseConstr.mkEvar(evk,args')|_->Constr.map_with_binderssuccsubstrecncandsubstrec_instancenctxargs=matchctx,SList.viewargswith|[],None->SList.empty|decl::ctx,Some(c,args)->letc'=matchcwith|None->beginmatchfind_var(NamedDecl.get_iddecl)var_alistwith|var->Some(lift_substituendnvar)|exceptionNot_found->Noneend|Somec->letc'=substrecncinifisVarId(NamedDecl.get_iddecl)c'thenNoneelseSomec'inSList.cons_optc'(substrec_instancenctxargs)|_::_,None|[],Some_->instance_mismatch()insubstrec0xletinstantiate_evar_arraysigmainfocargs=letinst=make_evar_instance_arrayinfoargsinmatchinstwith|[]->c|_->replace_varssigmainstcletexpand_existentialsigma(evk,args)=letevi=findsigmaevkinletrecexpandctxargs=matchctx,SList.viewargswith|[],None->[]|_::ctx,Some(Somec,args)->c::expandctxargs|decl::ctx,Some(None,args)->mkVar(NamedDecl.get_iddecl)::expandctxargs|[],Some_|_::_,None->instance_mismatch()inexpand(evar_filtered_contextevi)argsletexpand_existential0=expand_existentialletget_is_maybe_typeclass,(is_maybe_typeclass_hook:(evar_map->constr->bool)Hook.t)=Hook.make()letis_maybe_typeclasssigmac=Hook.getget_is_maybe_typeclasssigmac(*** Lifting primitive from Evar.Map. ***)letrenameevkidevd={evdwithevar_names=EvNames.renameevkidevd.evar_names}letadd_with_name?name?(typeclass_candidate=true)dei=matchi.evar_bodywith|Evar_empty->letevar_names=EvNames.add_name_undefinednameeid.evar_namesinletevar_flags=iftypeclass_candidate&&is_maybe_typeclassdi.evar_conclthenletflags=d.evar_flagsin{flagswithtypeclass_evars=Evar.Set.addeflags.typeclass_evars}elsed.evar_flagsin{dwithundf_evars=EvMap.addeid.undf_evars;evar_names;evar_flags}|Evar_defined_->letevar_names=EvNames.remove_name_defineded.evar_namesin{dwithdefn_evars=EvMap.addeid.defn_evars;evar_names}(** Evd.add is a low-level function mainly used to update the evar_info
associated to an evar, so we prevent registering its typeclass status. *)letadddei=add_with_name~typeclass_candidate:falsedei(*** Evar flags: typeclasses, aliased or obligation flag *)letget_typeclass_evarsevd=evd.evar_flags.typeclass_evarsletset_typeclass_evarsevdtcs=letflags=evd.evar_flagsin{evdwithevar_flags={flagswithtypeclass_evars=tcs}}letis_typeclass_evarevdevk=letflags=evd.evar_flagsinEvar.Set.memevkflags.typeclass_evarsletget_obligation_evarsevd=evd.evar_flags.obligation_evarsletset_obligation_evarevdevk=letflags=evd.evar_flagsinletevar_flags={flagswithobligation_evars=Evar.Set.addevkflags.obligation_evars}in{evdwithevar_flags}letis_obligation_evarevdevk=letflags=evd.evar_flagsinEvar.Set.memevkflags.obligation_evars(** Inheritance of flags: for evar-evar and restriction cases *)letinherit_evar_flagsevar_flagsevkevk'=letevk_typeclass=Evar.Set.memevkevar_flags.typeclass_evarsinletevk_obligation=Evar.Set.memevkevar_flags.obligation_evarsinletaliased_evars=Evar.Map.addevkevk'evar_flags.aliased_evarsinlettypeclass_evars=ifevk_typeclassthenlettypeclass_evars=Evar.Set.removeevkevar_flags.typeclass_evarsinEvar.Set.addevk'typeclass_evarselseevar_flags.typeclass_evarsinletobligation_evars=ifevk_obligationthenletobligation_evars=Evar.Set.removeevkevar_flags.obligation_evarsinEvar.Set.addevk'obligation_evarselseevar_flags.obligation_evarsin{obligation_evars;aliased_evars;typeclass_evars}(** Removal: in all other cases of definition *)letremove_evar_flagsevkevar_flags={typeclass_evars=Evar.Set.removeevkevar_flags.typeclass_evars;obligation_evars=Evar.Set.removeevkevar_flags.obligation_evars;(* Aliasing information is kept. *)aliased_evars=evar_flags.aliased_evars}(** New evars *)letevar_counter_summary_name="evar counter"(* Generator of existential names *)letevar_ctr,evar_counter_summary_tag=Summary.ref_tag0~name:evar_counter_summary_nameletnew_untyped_evar()=increvar_ctr;Evar.unsafe_of_int!evar_ctrletdefault_source=Loc.tag@@Evar_kinds.InternalHoleletremovede=letundf_evars=EvMap.removeed.undf_evarsinletdefn_evars=EvMap.removeed.defn_evarsinletfuture_goals=FutureGoals.removeed.future_goalsinletevar_flags=remove_evar_flagsed.evar_flagsin{dwithundf_evars;defn_evars;future_goals;evar_flags}letundefinesigmae=letevi=findsigmaeinadd(removesigmae)e{eviwithevar_body=Evar_empty}letfind_undefinedde=EvMap.finded.undf_evarsletmemde=EvMap.memed.undf_evars||EvMap.memed.defn_evarsletundefined_mapd=d.undf_evarsletdrop_all_definedd={dwithdefn_evars=EvMap.empty}(* spiwack: not clear what folding over an evar_map, for now we shall
simply fold over the inner evar_map. *)letfoldfda=EvMap.foldfd.defn_evars(EvMap.foldfd.undf_evarsa)letfold_undefinedfda=EvMap.foldfd.undf_evarsaletraw_mapfd=letfevkinfo=letans=fevkinfoinlet()=matchinfo.evar_body,ans.evar_bodywith|Evar_defined_,Evar_empty|Evar_empty,Evar_defined_->anomaly(str"Unrespectful mapping function.")|_->()inansinletdefn_evars=EvMap.Smart.mapifd.defn_evarsinletundf_evars=EvMap.Smart.mapifd.undf_evarsin{dwithdefn_evars;undf_evars;}letraw_map_undefinedfd=letfevkinfo=letans=fevkinfoinlet()=matchans.evar_bodywith|Evar_defined_->anomaly(str"Unrespectful mapping function.")|_->()inansin{dwithundf_evars=EvMap.Smart.mapifd.undf_evars;}letis_evar=memletis_definedde=EvMap.memed.defn_evarsletis_undefinedde=EvMap.memed.undf_evarsletexistential_opt_valued(n,args)=matchEvMap.find_optnd.defn_evarswith|None->None|Someinfo->matchevar_bodyinfowith|Evar_definedc->Some(instantiate_evar_arraydinfocargs)|Evar_empty->None(* impossible but w/e *)letexistential_valuedev=matchexistential_opt_valuedevwith|None->raiseNotInstantiatedEvar|Somev->vletexistential_value0=existential_valueletexistential_opt_value0=existential_opt_valueletexistential_expand_value0sigma(evk,args)=matchexistential_opt_valuesigma(evk,args)with|None->letargs=expand_existentialsigma(evk,args)inConstr.EvarUndefined(evk,args)|Somec->Constr.EvarDefinedcletmkLEvarsigma(evk,args)=letevi=findsigmaevkinletfolddeclargaccu=ifisVarId(NamedDecl.get_iddecl)argthenSList.defaultaccuelseSList.consargaccuinletargs=List.fold_right2fold(evar_filtered_contextevi)argsSList.emptyinmkEvar(evk,args)letevar_handlersigma=letevar_expandev=existential_expand_value0sigmaevinletevar_relevance(evk,_)=matchfindsigmaevkwith|evi->evi.evar_relevance|exceptionNot_found->Sorts.Relevantinletevar_repackev=mkLEvarsigmaevin{evar_expand;evar_relevance;evar_repack}letexistential_typed(n,args)=letinfo=tryfinddnwithNot_found->anomaly(str"Evar "++str(string_of_existentialn)++str" was not declared.")ininstantiate_evar_arraydinfoinfo.evar_conclargsletexistential_type0=existential_typeletadd_constraintsdc={dwithuniverses=UState.add_constraintsd.universesc}letadd_universe_constraintsdc={dwithuniverses=UState.add_universe_constraintsd.universesc}(*** /Lifting... ***)(* evar_map are considered empty disregarding histories *)letis_emptyd=EvMap.is_emptyd.defn_evars&&EvMap.is_emptyd.undf_evars&&List.is_emptyd.conv_pbs&&Metamap.is_emptyd.metasletcmapfevd={evdwithmetas=Metamap.map(map_clbf)evd.metas;defn_evars=EvMap.map(map_evar_infof)evd.defn_evars;undf_evars=EvMap.map(map_evar_infof)evd.undf_evars}(* spiwack: deprecated *)letcreate_evar_defssigma={sigmawithconv_pbs=[];last_mods=Evar.Set.empty;metas=Metamap.empty}letempty_evar_flags={obligation_evars=Evar.Set.empty;aliased_evars=Evar.Map.empty;typeclass_evars=Evar.Set.empty}letempty_side_effects={seff_private=Safe_typing.empty_private_constants;seff_roles=Cmap.empty;}letempty={defn_evars=EvMap.empty;undf_evars=EvMap.empty;universes=UState.empty;conv_pbs=[];last_mods=Evar.Set.empty;evar_flags=empty_evar_flags;metas=Metamap.empty;effects=empty_side_effects;evar_names=EvNames.empty;(* id<->key for undefined evars *)future_goals=FutureGoals.empty_stack;given_up=Evar.Set.empty;shelf=[[]];extras=Store.empty;}letfrom_env?binderse={emptywithuniverses=UState.from_env?binderse}letfrom_ctxuctx={emptywithuniverses=uctx}lethas_undefinedevd=not(EvMap.is_emptyevd.undf_evars)lethas_given_upevd=not(Evar.Set.is_emptyevd.given_up)lethas_shelvedevd=not(List.for_allList.is_emptyevd.shelf)letmerge_universe_contextevductx'={evdwithuniverses=UState.unionevd.universesuctx'}letset_universe_contextevductx'={evdwithuniverses=uctx'}(* TODO: make unique *)letadd_conv_pb?(tail=false)pbd=iftailthen{dwithconv_pbs=d.conv_pbs@[pb]}else{dwithconv_pbs=pb::d.conv_pbs}letconv_pbsd=d.conv_pbsletevar_sourceevi=evi.evar_sourceletevar_identevkevd=EvNames.identevkevd.evar_namesletevar_keyidevd=EvNames.keyidevd.evar_namesletget_aliased_evarsevd=evd.evar_flags.aliased_evarsletis_aliased_evarevdevk=trySome(Evar.Map.findevkevd.evar_flags.aliased_evars)withNot_found->Noneletdowncastevkcclevd=letevar_info=EvMap.findevkevd.undf_evarsinletevar_info'={evar_infowithevar_concl=ccl}in{evdwithundf_evars=EvMap.addevkevar_info'evd.undf_evars}(* extracts conversion problems that satisfy predicate p *)(* Note: conv_pbs not satisying p are stored back in reverse order *)letextract_conv_pbsevdp=let(pbs,pbs1)=List.fold_left(fun(pbs,pbs1)pb->ifppbthen(pb::pbs,pbs1)else(pbs,pb::pbs1))([],[])evd.conv_pbsin{evdwithconv_pbs=pbs1;last_mods=Evar.Set.empty},pbsletextract_changed_conv_pbsevdp=extract_conv_pbsevd(funpb->pevd.last_modspb)letextract_all_conv_pbsevd=extract_conv_pbsevd(fun_->true)letloc_of_conv_pbevd(pbty,env,t1,t2)=matchkind(fst(decompose_appt1))with|Evar(evk1,_)->fst(evar_source(findevdevk1))|_->matchkind(fst(decompose_appt2))with|Evar(evk2,_)->fst(evar_source(findevdevk2))|_->None(**********************************************************)(* Sort variables *)typerigid=UState.rigid=|UnivRigid|UnivFlexibleofbool(** Is substitution by an algebraic ok? *)letuniv_rigid=UnivRigidletuniv_flexible=UnivFlexiblefalseletuniv_flexible_alg=UnivFlexibletrueletevar_universe_contextd=d.universesletuniverse_context_setd=UState.context_setd.universesletto_universe_contextevd=UState.contextevd.universesletuniv_entry~polyevd=UState.univ_entry~polyevd.universesletcheck_univ_decl~polyevddecl=UState.check_univ_decl~polyevd.universesdeclletrestrict_universe_contextevdvars={evdwithuniverses=UState.restrictevd.universesvars}letuniverse_substevd=UState.substevd.universesletmerge_context_set?loc?(sideff=false)rigidevdctx'={evdwithuniverses=UState.merge?loc~sideffrigidevd.universesctx'}letwith_context_set?locrigidd(a,ctx)=(merge_context_set?locrigiddctx,a)letnew_univ_level_variable?loc?namerigidevd=letuctx',u=UState.new_univ_variable?locrigidnameevd.universesin({evdwithuniverses=uctx'},u)letnew_univ_variable?loc?namerigidevd=letuctx',u=UState.new_univ_variable?locrigidnameevd.universesin({evdwithuniverses=uctx'},Univ.Universe.makeu)letnew_sort_variable?loc?namerigidd=let(d',u)=new_univ_variable?locrigid?namedin(d',Sorts.sort_of_univu)letadd_global_univdu={dwithuniverses=UState.add_global_univd.universesu}letmake_flexible_variableevd~algebraicu={evdwithuniverses=UState.make_flexible_variableevd.universes~algebraicu}letmake_nonalgebraic_variableevdu={evdwithuniverses=UState.make_nonalgebraic_variableevd.universesu}(****************************************)(* Operations on constants *)(****************************************)letfresh_sort_in_family?loc?(rigid=univ_flexible)evds=with_context_set?locrigidevd(UnivGen.fresh_sort_in_familys)letfresh_constant_instance?loc?(rigid=univ_flexible)envevdc=with_context_set?locrigidevd(UnivGen.fresh_constant_instanceenvc)letfresh_inductive_instance?loc?(rigid=univ_flexible)envevdi=with_context_set?locrigidevd(UnivGen.fresh_inductive_instanceenvi)letfresh_constructor_instance?loc?(rigid=univ_flexible)envevdc=with_context_set?locrigidevd(UnivGen.fresh_constructor_instanceenvc)letfresh_array_instance?loc?(rigid=univ_flexible)envevd=with_context_set?locrigidevd(UnivGen.fresh_array_instanceenv)letfresh_global?loc?(rigid=univ_flexible)?namesenvevdgr=with_context_set?locrigidevd(UnivGen.fresh_global_instance?loc?namesenvgr)letis_sort_variableevds=UState.is_sort_variableevd.universessletis_flexible_levelevdl=letuctx=evd.universesinUniv.Level.Map.meml(UState.substuctx)letis_eq_sorts1s2=ifSorts.equals1s2thenNoneelseSome(s1,s2)(* Precondition: l is not defined in the substitution *)letuniverse_rigidityevdl=letuctx=evd.universesinifUniv.Level.Set.meml(Univ.ContextSet.levels(UState.context_setuctx))thenUnivFlexible(Univ.Level.Set.meml(UState.algebraicsuctx))elseUnivRigidletnormalize_universeevd=letvars=UState.substevd.universesinletnormalize=UnivSubst.normalize_universe_opt_substvarsinnormalizeletnormalize_universe_instanceevdl=letvars=UState.substevd.universesinletnormalize=UnivSubst.level_subst_of(UnivSubst.normalize_univ_variable_opt_substvars)inUnivSubst.subst_instancenormalizelletnormalize_sortevarss=matchswith|SProp|Prop|Set->s|Typeu->letu'=normalize_universeevarsuinifu'==uthenselseSorts.sort_of_univu'(* FIXME inefficient *)letset_eq_sortenvds1s2=lets1=normalize_sortds1ands2=normalize_sortds2inmatchis_eq_sorts1s2with|None->d|Some(u1,u2)->ifnot(type_in_typeenv)thenadd_universe_constraintsd(UnivProblem.Set.singleton(UnivProblem.UEq(u1,u2)))elsedletset_eq_leveldu1u2=add_constraintsd(Univ.enforce_eq_levelu1u2Univ.Constraints.empty)letset_leq_leveldu1u2=add_constraintsd(Univ.enforce_leq_levelu1u2Univ.Constraints.empty)letset_eq_instances?(flex=false)du1u2=add_universe_constraintsd(UnivProblem.enforce_eq_instances_univsflexu1u2UnivProblem.Set.empty)letset_leq_sortenvevds1s2=lets1=normalize_sortevds1ands2=normalize_sortevds2inmatchis_eq_sorts1s2with|None->evd|Some(u1,u2)->ifnot(type_in_typeenv)thenadd_universe_constraintsevd(UnivProblem.Set.singleton(UnivProblem.ULe(u1,u2)))elseevdletcheck_eqevdss'=UGraph.check_eq_sort(UState.ugraphevd.universes)ss'letcheck_leqevdss'=UGraph.check_leq_sort(UState.ugraphevd.universes)ss'letcheck_constraintsevdcsts=UGraph.check_constraintscsts(UState.ugraphevd.universes)letfix_undefined_variablesevd={evdwithuniverses=UState.fix_undefined_variablesevd.universes}letnf_univ_variablesevd=letuctx=UState.normalize_variablesevd.universesin{evdwithuniverses=uctx}letminimize_universesevd=letuctx'=UState.normalize_variablesevd.universesinletuctx'=UState.minimizeuctx'in{evdwithuniverses=uctx'}letuniverse_of_nameevds=UState.universe_of_nameevd.universessletuniverse_bindersevd=UState.universe_bindersevd.universesletuniversesevd=UState.ugraphevd.universesletupdate_sigma_univsugraphevd={evdwithuniverses=UState.update_sigma_univsevd.universesugraph}exceptionUniversesDiffer=UState.UniversesDiffer(**********************************************************)(* Side effects *)letconcat_side_effectseffeff'={seff_private=Safe_typing.concat_privateeff.seff_privateeff'.seff_private;seff_roles=Cmap.foldCmap.addeff.seff_roleseff'.seff_roles;}letemit_side_effectseffevd=leteffects=concat_side_effectseffevd.effectsin{evdwitheffects;universes=UState.emit_side_effectseff.seff_privateevd.universes}letdrop_side_effectsevd={evdwitheffects=empty_side_effects;}leteval_side_effectsevd=evd.effects(* Future goals *)letdeclare_future_goalevkevd=letfuture_goals=FutureGoals.add~principal:falseevkevd.future_goalsin{evdwithfuture_goals}letdeclare_principal_goalevkevd=letfuture_goals=FutureGoals.add~principal:trueevkevd.future_goalsin{evdwithfuture_goals}letpush_future_goalsevd={evdwithfuture_goals=FutureGoals.pushevd.future_goals}letpop_future_goalsevd=lethd,future_goals=FutureGoals.popevd.future_goalsinhd,{evdwithfuture_goals}letfold_future_goalsfsigma=FutureGoals.foldfsigmasigma.future_goalsletremove_future_goalevdevk={evdwithfuture_goals=FutureGoals.removeevkevd.future_goals}letpr_future_goals_stackevd=FutureGoals.pr_stackevd.future_goalsletgive_upevevd={evdwithgiven_up=Evar.Set.addevevd.given_up}letpush_shelfevd={evdwithshelf=[]::evd.shelf}letpop_shelfevd=matchevd.shelfwith|[]->anomalyPp.(str"shelf stack should not be empty")|hd::tl->hd,{evdwithshelf=tl}letfilter_shelffevd={evdwithshelf=List.map(List.filterf)evd.shelf}letshelveevdl=matchevd.shelfwith|[]->anomalyPp.(str"shelf stack should not be empty")|hd::tl->{evdwithshelf=(hd@l)::tl}letunshelveevdl={evdwithshelf=List.map(List.filter(funev->not(CList.mem_fEvar.equalevl)))evd.shelf}letgiven_upevd=evd.given_upletshelfevd=List.flattenevd.shelfletpr_shelfevd=letopenPpinifList.is_emptyevd.shelfthenstr"(empty stack)"elseprlist_with_sep(fun()->str"||")(prlist_with_sepspcEvar.print)evd.shelfletnew_pure_evar?(src=default_source)?(filter=Filter.identity)?(relevance=Sorts.Relevant)?(abstract_arguments=Abstraction.identity)?candidates?name?typeclass_candidate?(principal=false)signevdtyp=letevi={evar_hyps=sign;evar_concl=typ;evar_body=Evar_empty;evar_filter=filter;evar_abstract_arguments=abstract_arguments;evar_source=src;evar_candidates=candidates;evar_relevance=relevance;}inlettypeclass_candidate=ifprincipalthenSomefalseelsetypeclass_candidateinletnewevk=new_untyped_evar()inletevd=add_with_nameevd?name?typeclass_candidatenewevkeviinletevd=ifprincipalthendeclare_principal_goalnewevkevdelsedeclare_future_goalnewevkevdin(evd,newevk)letdefine_auxdefundefevkbody=letoldinfo=tryEvMap.findevkundefwithNot_found->ifEvMap.memevkdefthenanomaly~label:"Evd.define"(Pp.str"cannot define an evar twice.")elseanomaly~label:"Evd.define"(Pp.str"cannot define undeclared evar.")inlet()=assert(oldinfo.evar_body==Evar_empty)inletnewinfo={oldinfowithevar_body=Evar_definedbody}inEvMap.addevknewinfodef,EvMap.removeevkundef(* define the existential of section path sp as the constr body *)letdefine_genevkbodyevdevar_flags=letfuture_goals=FutureGoals.removeevkevd.future_goalsinletevd={evdwithfuture_goals}inlet(defn_evars,undf_evars)=define_auxevd.defn_evarsevd.undf_evarsevkbodyinletlast_mods=matchevd.conv_pbswith|[]->evd.last_mods|_->Evar.Set.addevkevd.last_modsinletevar_names=EvNames.remove_name_definedevkevd.evar_namesin{evdwithdefn_evars;undf_evars;last_mods;evar_names;evar_flags}(** By default, the obligation and evar tag of the evar is removed *)letdefineevkbodyevd=letevar_flags=remove_evar_flagsevkevd.evar_flagsindefine_genevkbodyevdevar_flags(** In case of an evar-evar solution, the flags are inherited *)letdefine_with_evarevkbodyevd=letevk'=fst(destEvarbody)inletevar_flags=inherit_evar_flagsevd.evar_flagsevkevk'inletevd=unshelveevd[evk]indefine_genevkbodyevdevar_flags(* In case of restriction, we declare the aliasing and inherit the obligation
and typeclass flags. *)letrestrictevkfilter?candidates?srcevd=letevk'=new_untyped_evar()inletevar_info=EvMap.findevkevd.undf_evarsinletlen=Range.lengthevar_info.evar_hyps.env_named_idxinletid_inst=Filter.filter_slistfilter(SList.defaultnlenSList.empty)inletevar_info'={evar_infowithevar_filter=filter;evar_candidates=candidates;evar_source=(matchsrcwithNone->evar_info.evar_source|Somesrc->src);}inletlast_mods=matchevd.conv_pbswith|[]->evd.last_mods|_->Evar.Set.addevkevd.last_modsinletevar_names=EvNames.reassign_name_definedevkevk'evd.evar_namesinletbody=mkEvar(evk',id_inst)inlet(defn_evars,undf_evars)=define_auxevd.defn_evarsevd.undf_evarsevkbodyinletevar_flags=inherit_evar_flagsevd.evar_flagsevkevk'inletevd={evdwithundf_evars=EvMap.addevk'evar_info'undf_evars;defn_evars;last_mods;evar_names;evar_flags}in(* Mark new evar as future goal, removing previous one,
circumventing Proofview.advance but making Proof.run_tactic catch these. *)letevd=unshelveevd[evk]inletevd=remove_future_goalevdevkinletevd=declare_future_goalevk'evdin(evd,evk')letupdate_sourceevdevksrc=letevar_info=EvMap.findevkevd.undf_evarsinletevar_info'={evar_infowithevar_source=src}in{evdwithundf_evars=EvMap.addevkevar_info'evd.undf_evars}(**********************************************************)(* Accessing metas *)(** We use this function to overcome OCaml compiler limitations and to prevent
the use of costly in-place modifications. *)letset_metasevdmetas={defn_evars=evd.defn_evars;undf_evars=evd.undf_evars;universes=evd.universes;conv_pbs=evd.conv_pbs;last_mods=evd.last_mods;evar_flags=evd.evar_flags;metas;effects=evd.effects;evar_names=evd.evar_names;future_goals=evd.future_goals;given_up=evd.given_up;shelf=evd.shelf;extras=evd.extras;}letmeta_listevd=evd.metasletmap_metas_fvaluefevd=letmap=function|Clval(id,(c,s),typ)->Clval(id,(mk_freelisted(fc.rebus),s),typ)|x->xinset_metasevd(Metamap.Smart.mapmapevd.metas)letmap_metasfevd=letmapcl=map_clbfclinset_metasevd(Metamap.Smart.mapmapevd.metas)letmeta_opt_fvalueevdmv=matchMetamap.findmvevd.metaswith|Clval(_,b,_)->Someb|Cltyp_->Noneletmeta_valueevdmv=matchmeta_opt_fvalueevdmvwith|Some(body,_)->body.rebus|None->raiseNot_foundletmeta_ftypeevdmv=matchMetamap.findmvevd.metaswith|Cltyp(_,b)->b|Clval(_,_,b)->bletmeta_declaremvv?(name=Anonymous)evd=letmetas=Metamap.addmv(Cltyp(name,mk_freelistedv))evd.metasinset_metasevdmetas(* If the meta is defined then forget its name *)letmeta_nameevdmv=tryfst(clb_name(Metamap.findmvevd.metas))withNot_found->Anonymousletevar_source_of_metamvevd=matchmeta_nameevdmvwith|Anonymous->Loc.tagEvar_kinds.GoalEvar|Nameid->Loc.tag@@Evar_kinds.VarInstanceidletuse_meta_sourceevdmvv=matchConstr.kindvwith|Evar(evk,_)->letf=function|None->None|Someeviasx->matchevi.evar_sourcewith|None,Evar_kinds.GoalEvar->Some{eviwithevar_source=evar_source_of_metamvevd}|_->xin{evdwithundf_evars=EvMap.updateevkfevd.undf_evars}|_->evdletmeta_assignmv(v,pb)evd=letmodify_=function|Cltyp(na,ty)->Clval(na,(mk_freelistedv,pb),ty)|_->anomaly~label:"meta_assign"(Pp.str"already defined.")inletmetas=Metamap.modifymvmodifyevd.metasinletevd=use_meta_sourceevdmvvinset_metasevdmetasletmeta_reassignmv(v,pb)evd=letmodify_=function|Clval(na,_,ty)->Clval(na,(mk_freelistedv,pb),ty)|_->anomaly~label:"meta_reassign"(Pp.str"not yet defined.")inletmetas=Metamap.modifymvmodifyevd.metasinset_metasevdmetasletclear_metasevd={evdwithmetas=Metamap.empty}letmeta_mergemetassigma=letmetas=Metamap.foldMetamap.addmetassigma.metasin{sigmawithmetas}typemetabinding=metavariable*constr*instance_statusletretract_coercible_metasevd=letmc=ref[]inletmapnv=matchvwith|Clval(na,(b,(Conv,CoerceToTypeass)),typ)->let()=mc:=(n,b.rebus,s)::!mcinCltyp(na,typ)|v->vinletmetas=Metamap.Smart.mapimapevd.metasin!mc,set_metasevdmetasletdependent_evar_identevevd=letevi=findevdevinmatchevi.evar_sourcewith|(_,Evar_kinds.VarInstanceid)->id|_->anomaly(str"Not an evar resulting of a dependent binding.")(**********************************************************)(* Extra data *)letget_extra_dataevd=evd.extrasletset_extra_dataextrasevd={evdwithextras}(*******************************************************************)typeopen_constr=evar_map*constr(*******************************************************************)(* The type constructor ['a sigma] adds an evar map to an object of
type ['a] *)type'asigma={it:'a;sigma:evar_map}letsig_itx=x.itletsig_sigx=x.sigmaleton_sigsf=letsigma',v=fs.sigmain{swithsigma=sigma'},v(*******************************************************************)(* The state monad with state an evar map. *)moduleMonadR=Monad.Make(structtype+'at=evar_map->evar_map*'aletreturna=funs->(s,a)let(>>=)xf=funs->let(s',a)=xsinfas'let(>>)xy=funs->let(s',())=xsinys'letmapfx=funs->on_sndf(xs)end)moduleMonad=Monad.Make(structtype+'at=evar_map->'a*evar_mapletreturna=funs->(a,s)let(>>=)xf=funs->let(a,s')=xsinfas'let(>>)xy=funs->let((),s')=xsinys'letmapfx=funs->on_fstf(xs)end)(**********************************************************)(* Failure explanation *)typeunsolvability_explanation=SeveralInstancesFoundofintmoduleMiniEConstr=structmoduleESorts=structtypet=Sorts.tletmakes=sletkindsigma=function|Sorts.Typeu->Sorts.sort_of_univ(normalize_universesigmau)|s->sletunsafe_to_sortss=sendmoduleEInstance=structtypet=Univ.Instance.tletmakei=iletkindsigmai=ifUniv.Instance.is_emptyithenielsenormalize_universe_instancesigmailetempty=Univ.Instance.emptyletis_empty=Univ.Instance.is_emptyletunsafe_to_instancet=tendtypet=econstrletrecwhd_evarsigmac=matchConstr.kindcwith|Evarev->beginmatchexistential_opt_valuesigmaevwith|Somec->whd_evarsigmac|None->cend|App(f,args)whenisEvarf->(* Enforce smart constructor invariant on applications *)letev=destEvarfinbeginmatchexistential_opt_valuesigmaevwith|None->c|Somef->whd_evarsigma(mkApp(f,args))end|Cast(c0,k,t)whenisEvarc0->(* Enforce smart constructor invariant on casts. *)letev=destEvarc0inbeginmatchexistential_opt_valuesigmaevwith|None->c|Somec->whd_evarsigma(mkCast(c,k,t))end|_->cletmkLEvar=mkLEvarletreplace_vars=replace_varsletkindsigmac=Constr.kind(whd_evarsigmac)letkind_upto=kindletof_kind=Constr.of_kindletof_constrc=cletof_constr_arrayv=vletunsafe_to_constrc=cletunsafe_to_constr_arrayv=vletunsafe_eq=Reflletto_constr_nochecksigmac=letevar_value((evk,args)asev)=matchEvMap.find_optevksigma.defn_evarswith|None->(* Hack: we fully expand the evar instance *)letrechas_default=function|SList.Nil->false|SList.Cons(_,l)->has_defaultl|SList.Default_->trueinifhas_defaultargsthenletargs=expand_existentialsigmaevinSome(mkEvar(evk,SList.of_full_listargs))elseNone|Someinfo->matchevar_bodyinfowith|Evar_definedc->Some(instantiate_evar_arraysigmainfocargs)|Evar_empty->assertfalseinUnivSubst.nf_evars_and_universes_opt_substevar_value(universe_substsigma)cletto_constr_gensigmac=letsaw_evar=reffalseinletevar_valueev=letv=existential_opt_valuesigmaevinsaw_evar:=!saw_evar||Option.is_emptyv;vinletc=UnivSubst.nf_evars_and_universes_opt_substevar_value(universe_substsigma)cinletsaw_evar=ifnot!saw_evarthenfalseelseletexceptionSawEvarinletreciterc=matchConstr.kindcwith|Evar_->raiseSawEvar|_->Constr.iteritercintryiterc;falsewithSawEvar->trueinsaw_evar,cletto_constr?(abort_on_undefined_evars=true)sigmac=ifnotabort_on_undefined_evarsthento_constr_nochecksigmacelseletsaw_evar,c=to_constr_gensigmacinifsaw_evarthenanomaly~label:"econstr"Pp.(str"grounding a non evar-free term");cletto_constr_optsigmac=letsaw_evar,c=to_constr_gensigmacinifsaw_evarthenNoneelseSomecletof_named_decld=dletunsafe_to_named_decld=dletof_rel_decld=dletunsafe_to_rel_decld=dletto_rel_declsigmad=Context.Rel.Declaration.map_constr(to_constrsigma)dletof_named_contextd=dletof_rel_contextd=dletunsafe_to_case_invertx=xletof_case_invertx=xend(** The following functions return the set of evars immediately
contained in the object *)(* excluding defined evars *)letevars_of_termevdc=letrecevrecaccc=letc=MiniEConstr.whd_evarevdcinmatchkindcwith|Evar(n,l)->Evar.Set.addn(SList.Skip.foldevrecaccl)|_->Constr.foldevrecacccinevrecEvar.Set.emptycletevars_of_named_contextevdnc=Context.Named.fold_outside(NamedDecl.fold_constr(funconstrs->Evar.Set.unions(evars_of_termevdconstr)))nc~init:Evar.Set.emptyletevars_of_filtered_evar_infoevdevi=Evar.Set.union(evars_of_termevdevi.evar_concl)(Evar.Set.union(matchevi.evar_bodywith|Evar_empty->Evar.Set.empty|Evar_definedb->evars_of_termevdb)(evars_of_named_contextevd(evar_filtered_contextevi)))