1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582(************************************************************************)(* * 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->'aarrayvalextend: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->boollistoptionend=structtypet=boollistoption(** We guarantee through the interface that if a filter is [Some _] then it
contains at least one [false] somewhere. *)letidentity=Noneletrecequall1l2=matchl1,l2with|[],[]->true|h1::l1,h2::l2->(ifh1thenh2elsenoth2)&&equall1l2|_->falseletequall1l2=matchl1,l2with|None,None->true|Some_,None|None,Some_->false|Somel1,Somel2->equall1l2letrecis_identity=function|[]->true|true::l->is_identityl|false::_->falseletnormalizef=ifis_identityfthenNoneelseSomefletfilter_listfl=matchfwith|None->l|Somef->CList.filter_withflletfilter_arrayfv=matchfwith|None->v|Somef->CArray.filter_withfvletrecextendnl=ifn=0thenlelseextend(predn)(true::l)letextendn=function|None->None|Somef->Some(extendnf)letcomposef1f2=matchf1with|None->f2|Somef1->matchf2with|None->None|Somef2->normalize(CList.filter_withf1f2)letapply_subfilter_arrayfiltersubfilter=(* In both cases we statically know that the argument will contain at
least one [false] *)matchfilterwith|None->Some(Array.to_listsubfilter)|Somef->letlen=Array.lengthsubfilterinletfoldb(i,ans)=ifbthenlet()=assert(0<=i)in(predi,Array.unsafe_getsubfilteri::ans)else(i,false::ans)inSome(snd(List.fold_rightfoldf(predlen,[])))letapply_subfilterfiltersubfilter=apply_subfilter_arrayfilter(Array.of_listsubfilter)letrestrict_uponflenp=letnewfilter=Array.initlenpinifArray.for_all(funid->id)newfilterthenNoneelseSome(apply_subfilter_arrayfnewfilter)letmap_alongffltl=letans=matchfltwith|None->List.map(funx->ftruex)l|Someflt->List.map2ffltlinnormalizeansletmakel=normalizelletreprf=fendmoduleAbstraction=structtypeabstraction=|Abstract|Imitatetypet=abstractionlistletidentity=[]letabstract_lastl=Abstract::lendmoduleIdentity:sigtypetvalmake:econstrlist->tvalnone:unit->tvalrepr:named_context_val->Filter.t->t->econstrlistvalis_identity:econstrlist->t->boolend=structtypet=econstrlistoptionrefletmakes=ref(Somes)letnone()=refNoneletreprsignfilters=match!swith|None->letans=Filter.filter_listfiltersign.env_named_varinlet()=s:=Someansinans|Somes->sletis_identityls=match!swith|None->false|Somes->s==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_identity:Identity.t;}letmake_evarhypsccl={evar_concl=ccl;evar_hyps=hyps;evar_body=Evar_empty;evar_filter=Filter.identity;evar_abstract_arguments=Abstraction.identity;evar_source=Loc.tag@@Evar_kinds.InternalHole;evar_candidates=None;evar_identity=Identity.none();}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_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=matchFilter.repr(evar_filterevi)with|None->evar_envenvevi|Somefilter->letrecmake_envfilterctxt=matchfilter,ctxtwith|[],[]->reset_contextenv|false::filter,_::ctxt->make_envfilterctxt|true::filter,decl::ctxt->letenv=make_envfilterctxtinpush_nameddeclenv|_->instance_mismatch()inmake_envfilter(evar_contextevi)letevar_identity_substevi=Identity.reprevi.evar_hypsevi.evar_filterevi.evar_identityletmap_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_arraytest_idinfoargs=letrecinstrecfilterctxtargs=matchfilter,ctxt,argswith|[],[],[]->[]|false::filter,_::ctxt,args->instrecfilterctxtargs|true::filter,d::ctxt,c::args->iftest_iddctheninstrecfilterctxtargselse(NamedDecl.get_idd,c)::instrecfilterctxtargs|_->instance_mismatch()inmatchFilter.repr(evar_filterinfo)with|None->letrecinstancectxtargs=matchctxt,argswith|[],[]->[]|d::ctxt,c::args->iftest_iddctheninstancectxtargselse(NamedDecl.get_idd,c)::instancectxtargs|_->instance_mismatch()ininstance(evar_contextinfo)args|Somefilter->instrecfilter(evar_contextinfo)argsletmake_evar_instance_arrayinfoargs=ifIdentity.is_identityargsinfo.evar_identitythen[]elseevar_instance_array(NamedDecl.get_id%>isVarId)infoargsletinstantiate_evar_arrayinfocargs=letinst=make_evar_instance_arrayinfoargsinmatchinstwith|[]->c|_->replace_varsinstctype'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.Mapletmetamap_to_listm=Metamap.fold(funnvl->(n,v)::l)m[](*************************)(* 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:sigtypet=private{comb:Evar.tlist;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]. *)}valmap_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={comb:Evar.tlist;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]. *)}typestack=tlistletsetf=function|[]->anomalyPp.(str"future_goals stack should not be empty")|hd::tl->fhd::tlletadd~principalevkstack=letaddfgl=letcomb=evk::fgl.combinletprincipal=ifprincipalthenmatchfgl.principalwith|Some_->CErrors.user_errPp.(str"Only one main goal per instantiation.")|None->Someevkelsefgl.principalin{comb;principal}insetaddstackletremoveestack=letremovefgl=letfiltere'=not(Evar.equalee')inletprincipal=Option.filterfilterfgl.principalinletcomb=List.filterfilterfgl.combin{principal;comb}inList.mapremovestackletempty={principal=None;comb=[];}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_leftfaccfuture_goals.combletfilterffgl=letcomb=List.filterffgl.combinletprincipal=Option.filterffgl.principalin{comb;principal}letmap_filterffgl=letcomb=List.map_filterffgl.combinletprincipal=Option.bindfgl.principalfin{comb;principal}letpr_stackstack=letopenPpinletpr_future_goalsfgl=prlist_with_sepspcEvar.printfgl.comb++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;}letget_is_maybe_typeclass,(is_maybe_typeclass_hook:(evar_map->constr->bool)Hook.t)=Hook.make~default:(funevdc->false)()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_ctrletnew_evarevd?name?typeclass_candidateevi=letevk=new_untyped_evar()inletevd=add_with_nameevd?name?typeclass_candidateevkeviin(evd,evk)letremovede=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}letfindde=tryEvMap.finded.undf_evarswithNot_found->EvMap.finded.defn_evarsletfind_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_arrayinfocargs)|Evar_empty->None(* impossible but w/e *)letexistential_valuedev=matchexistential_opt_valuedevwith|None->raiseNotInstantiatedEvar|Somev->vletexistential_value0=existential_valueletexistential_opt_value0=existential_opt_valueletexistential_typed(n,args)=letinfo=tryfinddnwithNot_found->anomaly(str"Evar "++str(string_of_existentialn)++str" was not declared.")ininstantiate_evar_arrayinfoinfo.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)letevars_reset_evd?(with_conv_pbs=false)?(with_univs=true)evdd=letconv_pbs=ifwith_conv_pbsthenevd.conv_pbselsed.conv_pbsinletlast_mods=ifwith_conv_pbsthenevd.last_modselsed.last_modsinletuniverses=ifnotwith_univsthenevd.universeselseUState.unionevd.universesd.universesin{evdwithmetas=d.metas;last_mods;conv_pbs;universes}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_sourceevkd=(finddevk).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_sourceevk1evd)|_->matchkind(fst(decompose_appt2))with|Evar(evk2,_)->fst(evar_sourceevk2evd)|_->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.shelfletdefine_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_evarsinletid_inst=Filter.filter_listfilterevar_info.evar_hyps.env_named_varinletevar_info'={evar_infowithevar_filter=filter;evar_candidates=candidates;evar_source=(matchsrcwithNone->evar_info.evar_source|Somesrc->src);evar_identity=Identity.makeid_inst;}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=metamap_to_listevd.metasletundefined_metasevd=letfilter=function|(n,Clval(_,_,typ))->None|(n,Cltyp(_,typ))->Someninletm=List.map_filterfilter(meta_listevd)inList.sortInt.comparemletmap_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_definedevdmv=matchMetamap.findmvevd.metaswith|Clval_->true|Cltyp_->falselettry_meta_fvalueevdmv=matchMetamap.findmvevd.metaswith|Clval(_,b,_)->b|Cltyp_->raiseNot_foundletmeta_fvalueevdmv=trytry_meta_fvalueevdmvwithNot_found->anomaly~label:"meta_fvalue"(Pp.str"meta has no value.")letmeta_valueevdmv=(fst(try_meta_fvalueevdmv)).rebusletmeta_ftypeevdmv=matchMetamap.findmvevd.metaswith|Cltyp(_,b)->b|Clval(_,_,b)->bletmeta_typeevdmv=(meta_ftypeevdmv).rebusletmeta_type0=meta_typeletmeta_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_mergeevd1evd2=letmetas=Metamap.foldMetamap.addevd1.metasevd2.metasin{evd2withmetas}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|_->cletkindsigmac=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_valueev=existential_opt_valuesigmaevinUnivSubst.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(List.fold_leftevrecaccl)|_->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)))