1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377(************************************************************************)(* * 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) *)(************************************************************************)openUtilopenPpopenNamesopenGenargopenTac2envopenTac2expropenTac2entries.PltacopenProofview.Notationsletltac2_plugin="coq-core.plugins.ltac2"letconstr_flags=letopenPretypingin{use_coercions=true;use_typeclasses=Pretyping.UseTC;solve_unification_constraints=true;fail_evar=true;expand_evars=true;program_mode=false;polymorphic=false;}letopen_constr_no_classes_flags=letopenPretypingin{use_coercions=true;use_typeclasses=Pretyping.NoUseTC;solve_unification_constraints=true;fail_evar=false;expand_evars=true;program_mode=false;polymorphic=false;}letpreterm_flags=letopenPretypingin{use_coercions=true;use_typeclasses=Pretyping.NoUseTC;solve_unification_constraints=true;fail_evar=false;expand_evars=false;program_mode=false;polymorphic=false;}(** Standard values *)moduleValue=Tac2ffiopenValueletval_format=Tac2print.val_formatletformat=repr_extval_formatletcore_prefixpathn=KerName.makepath(Label.of_id(Id.of_string_softn))letstd_coren=core_prefixTac2env.std_prefixnletcoq_coren=core_prefixTac2env.coq_prefixnletltac1_coren=core_prefixTac2env.ltac1_prefixnmoduleCore=structlett_int=coq_core"int"lett_string=coq_core"string"lett_array=coq_core"array"lett_unit=coq_core"unit"lett_list=coq_core"list"lett_constr=coq_core"constr"lett_preterm=coq_core"preterm"lett_pattern=coq_core"pattern"lett_ident=coq_core"ident"lett_option=coq_core"option"lett_exn=coq_core"exn"lett_reference=std_core"reference"lett_ltac1=ltac1_core"t"letc_nil=coq_core"[]"letc_cons=coq_core"::"letc_none=coq_core"None"letc_some=coq_core"Some"letc_true=coq_core"true"letc_false=coq_core"false"endopenCoreletv_unit=Value.of_unit()letv_blk=Valexpr.make_blockletof_relevance=function|Sorts.Relevant->ValInt0|Sorts.Irrelevant->ValInt1|Sorts.RelevanceVarq->ValInt0(* FIXME ? *)letto_relevance=function|ValInt0->Sorts.Relevant|ValInt1->Sorts.Irrelevant|_->assertfalseletrelevance=make_reprof_relevanceto_relevanceletof_binderb=Value.of_extValue.val_binderbletto_binderb=Value.to_extValue.val_binderbletof_instanceu=letu=Univ.Instance.to_array(EConstr.Unsafe.to_instanceu)inValue.of_array(funv->Value.of_extValue.val_univv)uletto_instanceu=letu=Value.to_array(funv->Value.to_extValue.val_univv)uinEConstr.EInstance.make(Univ.Instance.of_arrayu)letof_rec_declaration(nas,ts,cs)=letbinders=Array.map2(funnat->(na,t))nastsin(Value.of_arrayof_binderbinders,Value.of_arrayValue.of_constrcs)letto_rec_declaration(nas,cs)=letnas=Value.to_arrayto_bindernasin(Array.mapfstnas,Array.mapsndnas,Value.to_arrayValue.to_constrcs)letof_case_invert=letopenConstrinfunction|NoInvert->ValInt0|CaseInvert{indices}->v_blk0[|of_arrayof_constrindices|]letto_case_invert=letopenConstrinfunction|ValInt0->NoInvert|ValBlk(0,[|indices|])->letindices=to_arrayto_constrindicesinCaseInvert{indices}|_->CErrors.anomalyPp.(str"unexpected value shape")letof_resultf=function|Inlc->v_blk0[|fc|]|Inre->v_blk1[|Value.of_exne|](** Stdlib exceptions *)leterr_notfocussed=Tac2interp.LtacError(coq_core"Not_focussed",[||])leterr_outofbounds=Tac2interp.LtacError(coq_core"Out_of_bounds",[||])leterr_notfound=Tac2interp.LtacError(coq_core"Not_found",[||])leterr_matchfailure=Tac2interp.LtacError(coq_core"Match_failure",[||])leterr_division_by_zero=Tac2interp.LtacError(coq_core"Division_by_zero",[||])(** Helper functions *)letthawf=Tac2ffi.applyf[v_unit]letfatal_flag:unitExninfo.t=Exninfo.make()lethas_fatal_flaginfo=matchExninfo.getinfofatal_flagwith|None->false|Some()->trueletset_btinfo=if!Tac2bt.print_ltac2_backtracethenTac2bt.get_backtrace>>=funbt->Proofview.tclUNIT(Exninfo.addinfoTac2bt.backtracebt)elseProofview.tclUNITinfoletthrow?(info=Exninfo.null)e=set_btinfo>>=funinfo->letinfo=Exninfo.addinfofatal_flag()inProofview.tclLIFT(Proofview.NonLogical.raise(e,info))letfail?(info=Exninfo.null)e=set_btinfo>>=funinfo->Proofview.tclZERO~infoeletreturnx=Proofview.tclUNITxletpname?(plugin=ltac2_plugin)s={mltac_plugin=plugin;mltac_tactic=s}letwrapf=return()>>=fun()->return(f())letwrap_unitf=return()>>=fun()->f();returnv_unitletcatchable_exception=function|Logic_monad.Exception_->false|e->CErrors.noncriticale(* Adds ltac2 backtrace
With [passthrough:false], acts like [Proofview.wrap_exceptions] + Ltac2 backtrace handling
*)letwrap_exceptions?(passthrough=false)f=tryf()withe->lete,info=Exninfo.captureeinset_btinfo>>=funinfo->ifnotpassthrough&&catchable_exceptionethenbeginifhas_fatal_flaginfothenProofview.tclLIFT(Proofview.NonLogical.raise(e,info))elseProofview.tclZERO~infoeendelseExninfo.iraise(e,info)letassert_focussed=Proofview.Goal.goals>>=fungls->matchglswith|[_]->Proofview.tclUNIT()|[]|_::_::_->throwerr_notfocussedletpf_apply?(catch_exceptions=false)f=letfenvsigma=wrap_exceptions~passthrough:(notcatch_exceptions)(fun()->fenvsigma)inProofview.Goal.goals>>=function|[]->Proofview.tclENV>>=funenv->Proofview.tclEVARMAP>>=funsigma->fenvsigma|[gl]->gl>>=fungl->f(Proofview.Goal.envgl)(Tacmach.projectgl)|_::_::_->throwerr_notfocussed(** Primitives *)letdefine_primitive?pluginnamearityf=Tac2env.define_primitive(pname?pluginname)(mk_closure_valarityf)letdefineval?pluginnamev=Tac2env.define_primitive(pname?pluginname)vletdefine0?pluginnamef=define_primitive?pluginnamearity_one(fun_->f)letdefine1namer0f=define_primitivenamearity_onebeginfunx->f(Value.repr_tor0x)endletdefine2namer0r1f=define_primitivename(arity_sucarity_one)beginfunxy->f(Value.repr_tor0x)(Value.repr_tor1y)endletdefine_equalitynamereq=define2namerrbeginfunxy->return(Value.of_bool(eqxy))endletdefine3namer0r1r2f=define_primitivename(arity_suc(arity_sucarity_one))beginfunxyz->f(Value.repr_tor0x)(Value.repr_tor1y)(Value.repr_tor2z)endletdefine4namer0r1r2r3f=define_primitivename(arity_suc(arity_suc(arity_sucarity_one)))beginfunx0x1x2x3->f(Value.repr_tor0x0)(Value.repr_tor1x1)(Value.repr_tor2x2)(Value.repr_tor3x3)endletdefine5namer0r1r2r3r4f=define_primitivename(arity_suc(arity_suc(arity_suc(arity_sucarity_one))))beginfunx0x1x2x3x4->f(Value.repr_tor0x0)(Value.repr_tor1x1)(Value.repr_tor2x2)(Value.repr_tor3x3)(Value.repr_tor4x4)end(** Printing *)let()=define1"print"ppbeginfunpp->wrap_unit(fun()->Feedback.msg_noticepp)endlet()=define1"message_of_int"intbeginfunn->return(Value.of_pp(Pp.intn))endlet()=define1"message_of_string"stringbeginfuns->return(Value.of_pp(strs))endlet()=define1"message_to_string"ppbeginfunpp->return(Value.of_string(Pp.string_of_ppcmdspp))endlet()=define1"message_of_constr"constrbeginfunc->pf_applybeginfunenvsigma->letpp=Printer.pr_econstr_envenvsigmacinreturn(Value.of_pppp)endendlet()=define1"message_of_ident"identbeginfunc->letpp=Id.printcinreturn(Value.of_pppp)endlet()=define1"message_of_exn"valexprbeginfunv->Proofview.tclENV>>=funenv->Proofview.tclEVARMAP>>=funsigma->letpp=Tac2print.pr_valexprenvsigmav(GTypRef(OtherCore.t_exn,[]))inreturn(Value.of_pppp)endlet()=define2"message_concat"ppppbeginfunm1m2->return(Value.of_pp(Pp.appm1m2))endlet()=define0"format_stop"beginreturn(Value.of_extval_format[])endlet()=define1"format_string"formatbeginfuns->return(Value.of_extval_format(Tac2print.FmtString::s))endlet()=define1"format_int"formatbeginfuns->return(Value.of_extval_format(Tac2print.FmtInt::s))endlet()=define1"format_constr"formatbeginfuns->return(Value.of_extval_format(Tac2print.FmtConstr::s))endlet()=define1"format_ident"formatbeginfuns->return(Value.of_extval_format(Tac2print.FmtIdent::s))endlet()=define2"format_literal"stringformatbeginfunlits->return(Value.of_extval_format(Tac2print.FmtLiterallit::s))endlet()=define1"format_alpha"formatbeginfuns->return(Value.of_extval_format(Tac2print.FmtAlpha::s))endlet()=define2"format_kfprintf"closureformatbeginfunkfmt->letopenTac2printinletfoldaccu=function|FmtLiteral_->accu|FmtString|FmtInt|FmtConstr|FmtIdent->1+accu|FmtAlpha->2+accuinletpop1l=matchlwith[]->assertfalse|x::l->(x,l)inletpop2l=matchlwith[]|[_]->assertfalse|x::y::l->(x,y,l)inletarity=List.fold_leftfold0fmtinletrecevalaccuargsfmt=matchfmtwith|[]->applyk[of_ppaccu]|tag::fmt->matchtagwith|FmtLiterals->eval(Pp.appaccu(Pp.strs))argsfmt|FmtString->let(s,args)=pop1argsinletpp=Pp.str(to_strings)ineval(Pp.appaccupp)argsfmt|FmtInt->let(i,args)=pop1argsinletpp=Pp.int(to_inti)ineval(Pp.appaccupp)argsfmt|FmtConstr->let(c,args)=pop1argsinletc=to_constrcinpf_applybeginfunenvsigma->letpp=Printer.pr_econstr_envenvsigmacineval(Pp.appaccupp)argsfmtend|FmtIdent->let(i,args)=pop1argsinletpp=Id.print(to_identi)ineval(Pp.appaccupp)argsfmt|FmtAlpha->let(f,x,args)=pop2argsinTac2ffi.apply(to_closuref)[of_unit();x]>>=funpp->eval(Pp.appaccu(to_pppp))argsfmtinletevalv=eval(Pp.mt())vfmtinifInt.equalarity0theneval[]elsereturn(Tac2ffi.of_closure(Tac2ffi.abstractarityeval))end(** Array *)let()=define0"array_empty"beginreturn(v_blk0(Array.of_list[]))endlet()=define2"array_make"intvalexprbeginfunnx->ifn<0||n>Sys.max_array_lengththenthrowerr_outofboundselsewrap(fun()->v_blk0(Array.makenx))endlet()=define1"array_length"blockbeginfun(_,v)->return(Value.of_int(Array.lengthv))endlet()=define3"array_set"blockintvalexprbeginfun(_,v)nx->ifn<0||n>=Array.lengthvthenthrowerr_outofboundselsewrap_unit(fun()->v.(n)<-x)endlet()=define2"array_get"blockintbeginfun(_,v)n->ifn<0||n>=Array.lengthvthenthrowerr_outofboundselsewrap(fun()->v.(n))endlet()=define5"array_blit"blockintblockintintbeginfun(_,v0)s0(_,v1)s1l->ifs0<0||s0+l>Array.lengthv0||s1<0||s1+l>Array.lengthv1||l<0thenthrowerr_outofboundselsewrap_unit(fun()->Array.blitv0s0v1s1l)endlet()=define4"array_fill"blockintintvalexprbeginfun(_,d)slv->ifs<0||s+l>Array.lengthd||l<0thenthrowerr_outofboundselsewrap_unit(fun()->Array.filldslv)endlet()=define1"array_concat"(listblock)beginfunl->wrap(fun()->v_blk0(Array.concat(List.mapsndl)))end(** Ident *)let()=define2"ident_equal"identidentbeginfunid1id2->return(Value.of_bool(Id.equalid1id2))endlet()=define1"ident_to_string"identbeginfunid->return(Value.of_string(Id.to_stringid))endlet()=define1"ident_of_string"stringbeginfuns->letid=trySome(Id.of_strings)with_->Noneinreturn(Value.of_optionValue.of_identid)end(** Int *)let()=define2"int_equal"intintbeginfunmn->return(Value.of_bool(m==n))endletunopnf=define1nintbeginfunm->return(Value.of_int(fm))endletbinopnf=define2nintintbeginfunmn->return(Value.of_int(fmn))endlet()=binop"int_compare"Int.comparelet()=binop"int_add"(+)let()=binop"int_sub"(-)let()=binop"int_mul"(*)let()=define2"int_div"intintbeginfunmn->ifn==0thenthrowerr_division_by_zeroelsereturn(Value.of_int(m/n))endlet()=define2"int_mod"intintbeginfunmn->ifn==0thenthrowerr_division_by_zeroelsereturn(Value.of_int(mmodn))endlet()=unop"int_neg"(~-)let()=unop"int_abs"abslet()=binop"int_asr"(asr)let()=binop"int_lsl"(lsl)let()=binop"int_lsr"(lsr)let()=binop"int_land"(land)let()=binop"int_lor"(lor)let()=binop"int_lxor"(lxor)let()=unop"int_lnot"lnot(** Char *)let()=define1"char_of_int"intbeginfunn->wrap(fun()->Value.of_char(Char.chrn))endlet()=define1"char_to_int"charbeginfunn->wrap(fun()->Value.of_int(Char.coden))end(** String *)let()=define2"string_make"intcharbeginfunnc->ifn<0||n>Sys.max_string_lengththenthrowerr_outofboundselsewrap(fun()->Value.of_bytes(Bytes.makenc))endlet()=define1"string_length"bytesbeginfuns->return(Value.of_int(Bytes.lengths))endlet()=define3"string_set"bytesintcharbeginfunsnc->ifn<0||n>=Bytes.lengthsthenthrowerr_outofboundselsewrap_unit(fun()->Bytes.setsnc)endlet()=define2"string_get"bytesintbeginfunsn->ifn<0||n>=Bytes.lengthsthenthrowerr_outofboundselsewrap(fun()->Value.of_char(Bytes.getsn))endlet()=define2"string_concat"bytes(listbytes)beginfunsepl->return(Value.of_bytes(Bytes.concatsepl))endlet()=define2"string_app"bytesbytesbeginfunab->return(Value.of_bytes(Bytes.concatBytes.empty[a;b]))endlet()=define2"string_equal"bytesbytesbeginfunab->return(Value.of_bool(Bytes.equalab))endlet()=define2"string_compare"bytesbytesbeginfunab->return(Value.of_int(Bytes.compareab))end(** Terms *)(** constr -> constr *)let()=define1"constr_type"constrbeginfunc->letget_typeenvsigma=let(sigma,t)=Typing.type_ofenvsigmacinlett=Value.of_constrtinProofview.Unsafe.tclEVARSsigma<*>Proofview.tclUNITtinpf_apply~catch_exceptions:trueget_typeend(** constr -> constr *)let()=define2"constr_equal"constrconstrbeginfunc1c2->Proofview.tclEVARMAP>>=funsigma->letb=EConstr.eq_constrsigmac1c2inProofview.tclUNIT(Value.of_boolb)endlet()=define1"constr_kind"constrbeginfunc->letopenConstrinProofview.tclEVARMAP>>=funsigma->Proofview.tclENV>>=funenv->returnbeginmatchEConstr.kindsigmacwith|Reln->v_blk0[|Value.of_intn|]|Varid->v_blk1[|Value.of_identid|]|Metan->v_blk2[|Value.of_intn|]|Evar(evk,args)->letargs=Evd.expand_existentialsigma(evk,args)inv_blk3[|Value.of_evarevk;Value.of_arrayValue.of_constr(Array.of_listargs);|]|Sorts->v_blk4[|Value.of_extValue.val_sorts|]|Cast(c,k,t)->v_blk5[|Value.of_constrc;Value.of_extValue.val_castk;Value.of_constrt;|]|Prod(na,t,u)->v_blk6[|of_binder(na,t);Value.of_constru;|]|Lambda(na,t,c)->v_blk7[|of_binder(na,t);Value.of_constrc;|]|LetIn(na,b,t,c)->v_blk8[|of_binder(na,t);Value.of_constrb;Value.of_constrc;|]|App(c,cl)->v_blk9[|Value.of_constrc;Value.of_arrayValue.of_constrcl;|]|Const(cst,u)->v_blk10[|Value.of_constantcst;of_instanceu;|]|Ind(ind,u)->v_blk11[|Value.of_extValue.val_inductiveind;of_instanceu;|]|Construct(cstr,u)->v_blk12[|Value.of_extValue.val_constructorcstr;of_instanceu;|]|Case(ci,u,pms,c,iv,t,bl)->(* FIXME: also change representation Ltac2-side? *)let(ci,c,iv,t,bl)=EConstr.expand_caseenvsigma(ci,u,pms,c,iv,t,bl)inv_blk13[|Value.of_extValue.val_caseci;Value.of_constrc;of_case_invertiv;Value.of_constrt;Value.of_arrayValue.of_constrbl;|]|Fix((recs,i),def)->let(nas,cs)=of_rec_declarationdefinv_blk14[|Value.of_arrayValue.of_intrecs;Value.of_inti;nas;cs;|]|CoFix(i,def)->let(nas,cs)=of_rec_declarationdefinv_blk15[|Value.of_inti;nas;cs;|]|Proj(p,c)->v_blk16[|Value.of_extValue.val_projectionp;Value.of_constrc;|]|Intn->v_blk17[|Value.of_uint63n|]|Floatf->v_blk18[|Value.of_floatf|]|Array(u,t,def,ty)->v_blk19[|of_instanceu;Value.of_arrayValue.of_constrt;Value.of_constrdef;Value.of_constrty|]endendlet()=define1"constr_make"valexprbeginfunknd->Proofview.tclEVARMAP>>=funsigma->Proofview.tclENV>>=funenv->letc=matchTac2ffi.to_blockkndwith|(0,[|n|])->letn=Value.to_intninEConstr.mkReln|(1,[|id|])->letid=Value.to_identidinEConstr.mkVarid|(2,[|n|])->letn=Value.to_intninEConstr.mkMetan|(3,[|evk;args|])->letevk=to_evarevkinletargs=Value.to_arrayValue.to_constrargsinEConstr.mkLEvarsigma(evk,Array.to_listargs)|(4,[|s|])->lets=Value.to_extValue.val_sortsinEConstr.mkSorts|(5,[|c;k;t|])->letc=Value.to_constrcinletk=Value.to_extValue.val_castkinlett=Value.to_constrtinEConstr.mkCast(c,k,t)|(6,[|na;u|])->let(na,t)=to_bindernainletu=Value.to_construinEConstr.mkProd(na,t,u)|(7,[|na;c|])->let(na,t)=to_bindernainletu=Value.to_constrcinEConstr.mkLambda(na,t,u)|(8,[|na;b;c|])->let(na,t)=to_bindernainletb=Value.to_constrbinletc=Value.to_constrcinEConstr.mkLetIn(na,b,t,c)|(9,[|c;cl|])->letc=Value.to_constrcinletcl=Value.to_arrayValue.to_constrclinEConstr.mkApp(c,cl)|(10,[|cst;u|])->letcst=Value.to_constantcstinletu=to_instanceuinEConstr.mkConstU(cst,u)|(11,[|ind;u|])->letind=Value.to_extValue.val_inductiveindinletu=to_instanceuinEConstr.mkIndU(ind,u)|(12,[|cstr;u|])->letcstr=Value.to_extValue.val_constructorcstrinletu=to_instanceuinEConstr.mkConstructU(cstr,u)|(13,[|ci;c;iv;t;bl|])->letci=Value.to_extValue.val_caseciinletc=Value.to_constrcinletiv=to_case_invertivinlett=Value.to_constrtinletbl=Value.to_arrayValue.to_constrblinEConstr.mkCase(EConstr.contract_caseenvsigma(ci,c,iv,t,bl))|(14,[|recs;i;nas;cs|])->letrecs=Value.to_arrayValue.to_intrecsinleti=Value.to_intiinletdef=to_rec_declaration(nas,cs)inEConstr.mkFix((recs,i),def)|(15,[|i;nas;cs|])->leti=Value.to_intiinletdef=to_rec_declaration(nas,cs)inEConstr.mkCoFix(i,def)|(16,[|p;c|])->letp=Value.to_extValue.val_projectionpinletc=Value.to_constrcinEConstr.mkProj(p,c)|(17,[|n|])->letn=Value.to_uint63ninEConstr.mkIntn|(18,[|f|])->letf=Value.to_floatfinEConstr.mkFloatf|(19,[|u;t;def;ty|])->lett=Value.to_arrayValue.to_constrtinletdef=Value.to_constrdefinletty=Value.to_constrtyinletu=to_instanceuinEConstr.mkArray(u,t,def,ty)|_->assertfalseinreturn(Value.of_constrc)endlet()=define1"constr_check"constrbeginfunc->pf_applybeginfunenvsigma->trylet(sigma,_)=Typing.type_ofenvsigmacinProofview.Unsafe.tclEVARSsigma>>=fun()->return(of_resultValue.of_constr(Inlc))withewhenCErrors.noncriticale->lete=Exninfo.captureeinreturn(of_resultValue.of_constr(Inre))endendlet()=define3"constr_liftn"intintconstrbeginfunnkc->letans=EConstr.Vars.liftnnkcinreturn(Value.of_constrans)endlet()=define3"constr_substnl"(listconstr)intconstrbeginfunsubstkc->letans=EConstr.Vars.substnlsubstkcinreturn(Value.of_constrans)endlet()=define3"constr_closenl"(listident)intconstrbeginfunidskc->Proofview.tclEVARMAP>>=funsigma->letans=EConstr.Vars.substn_varssigmakidscinreturn(Value.of_constrans)endlet()=define2"constr_closedn"intconstrbeginfunnc->Proofview.tclEVARMAP>>=funsigma->letans=EConstr.Vars.closednsigmancinreturn(Value.of_boolans)endlet()=define3"constr_occur_between"intintconstrbeginfunnmc->Proofview.tclEVARMAP>>=funsigma->letans=EConstr.Vars.noccur_betweensigmanmcinreturn(Value.of_bool(notans))endlet()=define1"constr_case"(repr_extval_inductive)beginfunind->Proofview.tclENV>>=funenv->tryletans=Inductiveops.make_case_infoenvindSorts.RelevantConstr.RegularStyleinreturn(Value.of_extValue.val_caseans)withewhenCErrors.noncriticale->throwerr_notfoundendlet()=defineval"constr_cast_default"(of_castDEFAULTcast)let()=defineval"constr_cast_vm"(of_castVMcast)let()=defineval"constr_cast_native"(of_castNATIVEcast)let()=define2"constr_constructor"(repr_extval_inductive)intbeginfun(ind,i)k->Proofview.tclENV>>=funenv->tryletopenDeclarationsinletans=Environ.lookup_mindindenvinlet_=ans.mind_packets.(i).mind_consnames.(k)inreturn(Value.of_extval_constructor((ind,i),(k+1)))withewhenCErrors.noncriticale->throwerr_notfoundendlet()=define3"constr_in_context"identconstrclosurebeginfunidtc->Proofview.Goal.goals>>=function|[gl]->gl>>=fungl->letenv=Proofview.Goal.envglinletsigma=Proofview.Goal.sigmaglinlethas_var=trylet_=Environ.lookup_namedidenvintruewithNot_found->falseinifhas_varthenTacticals.tclZEROMSG(str"Variable already exists")elseletopenContext.Named.Declarationinletsigma,t_rel=lett_ty=Retyping.get_type_ofenvsigmatin(* If the user passed eg ['_] for the type we force it to indeed be a type *)letsigma,j=Typing.type_judgmentenvsigma{uj_val=t;uj_type=t_ty}insigma,EConstr.ESorts.relevance_of_sortsigmaj.utj_typeinletnenv=EConstr.push_named(LocalAssum(Context.make_annotidt_rel,t))envinlet(sigma,(evt,_))=Evarutil.new_type_evarnenvsigmaEvd.univ_flexibleinlet(sigma,evk)=Evarutil.new_pure_evar(Environ.named_context_valnenv)sigmaevtinProofview.Unsafe.tclEVARSsigma>>=fun()->Proofview.Unsafe.tclSETGOALS[Proofview.with_empty_stateevk]>>=fun()->thawc>>=fun_->Proofview.Unsafe.tclSETGOALS[Proofview.with_empty_state(Proofview.Goal.goalgl)]>>=fun()->letargs=EConstr.identity_subst_val(Environ.named_context_valenv)inletargs=SList.cons(EConstr.mkRel1)argsinletans=EConstr.mkEvar(evk,args)inletans=EConstr.mkLambda(Context.make_annot(Nameid)t_rel,t,ans)inreturn(Value.of_constrans)|_->throwerr_notfocussedend(** preterm -> constr *)let()=define1"constr_pretype"(repr_extval_preterm)beginfunc->letopenPretypinginletopenLtac_pretypeinletpretypeenvsigma=(* For now there are no primitives to create preterms with a non-empty
closure. I do not know whether [closed_glob_constr] is really the type
we want but it does not hurt in the meantime. *)let{closure;term}=cinletvars={ltac_constrs=closure.typed;ltac_uconstrs=closure.untyped;ltac_idents=closure.idents;ltac_genargs=closure.genargs;}inletflags=constr_flagsinletsigma,t=understand_ltacflagsenvsigmavarsWithoutTypeConstraintterminlett=Value.of_constrtinProofview.Unsafe.tclEVARSsigma<*>Proofview.tclUNITtinpf_apply~catch_exceptions:truepretypeendlet()=define2"constr_binder_make"(optionident)constrbeginfunnaty->pf_applybeginfunenvsigma->matchRetyping.relevance_of_typeenvsigmatywith|rel->letna=matchnawithNone->Anonymous|Someid->Nameidinreturn(Value.of_extval_binder(Context.make_annotnarel,ty))|exception(Retyping.RetypeError_ase)->lete,info=Exninfo.captureeinfail~info(CErrors.UserErrorPp.(str"Not a type."))endendlet()=define3"constr_binder_unsafe_make"(optionident)relevanceconstrbeginfunnarelty->letna=matchnawithNone->Anonymous|Someid->Nameidinreturn(Value.of_extval_binder(Context.make_annotnarel,ty))endlet()=define1"constr_binder_name"(repr_extval_binder)beginfun(bnd,_)->letna=matchbnd.Context.binder_namewithAnonymous->None|Nameid->Someidinreturn(Value.of_optionValue.of_identna)endlet()=define1"constr_binder_type"(repr_extval_binder)beginfun(bnd,ty)->return(of_constrty)endlet()=define1"constr_has_evar"constrbeginfunc->Proofview.tclEVARMAP>>=funsigma->letb=Evarutil.has_undefined_evarssigmacinProofview.tclUNIT(Value.of_boolb)end(** Extra equalities *)let()=define_equality"evar_equal"evarEvar.equallet()=define_equality"float_equal"floatFloat64.equallet()=define_equality"uint63_equal"uint63Uint63.equallet()=define_equality"meta_equal"intInt.equallet()=define_equality"constr_cast_equal"castGlob_ops.cast_kind_eqlet()=define_equality"constant_equal"constantConstant.UserOrd.equallet()=define_equality"constr_case_equal"(repr_extval_case)beginfunxy->Ind.UserOrd.equalx.ci_indy.ci_ind&&Sorts.relevance_equalx.ci_relevancey.ci_relevanceendlet()=define_equality"constructor_equal"(repr_extval_constructor)Construct.UserOrd.equallet()=define_equality"projection_equal"(repr_extval_projection)Projection.UserOrd.equal(** Patterns *)letempty_context=Constr_matching.empty_contextlet()=define0"pattern_empty_context"beginreturn(Value.of_extval_matching_contextempty_context)endlet()=define2"pattern_matches"patternconstrbeginfunpatc->pf_applybeginfunenvsigma->letans=trySome(Constr_matching.matchesenvsigmapatc)withConstr_matching.PatternMatchingFailure->Noneinbeginmatchanswith|None->failerr_matchfailure|Someans->letans=Id.Map.bindingsansinletof_pair(id,c)=Value.of_tuple[|Value.of_identid;Value.of_constrc|]inreturn(Value.of_listof_pairans)endendendlet()=define2"pattern_matches_subterm"patternconstrbeginfunpatc->letopenConstr_matchinginletrecof_anss=matchIStream.peekswith|IStream.Nil->failerr_matchfailure|IStream.Cons({m_sub=(_,sub);m_ctx},s)->letans=Id.Map.bindingssubinletof_pair(id,c)=Value.of_tuple[|Value.of_identid;Value.of_constrc|]inletans=Value.of_tuple[|Value.of_extval_matching_contextm_ctx;Value.of_listof_pairans|]inProofview.tclOR(returnans)(fun_->of_anss)inpf_applybeginfunenvsigma->letpat=Constr_matching.instantiate_patternenvsigmaId.Map.emptypatinletans=Constr_matching.match_subtermenvsigma(Id.Set.empty,pat)cinof_ansansendendlet()=define2"pattern_matches_vect"patternconstrbeginfunpatc->pf_applybeginfunenvsigma->letans=trySome(Constr_matching.matchesenvsigmapatc)withConstr_matching.PatternMatchingFailure->Noneinbeginmatchanswith|None->failerr_matchfailure|Someans->letans=Id.Map.bindingsansinletans=Array.map_of_listsndansinreturn(Value.of_arrayValue.of_constrans)endendendlet()=define2"pattern_matches_subterm_vect"patternconstrbeginfunpatc->letopenConstr_matchinginletrecof_anss=matchIStream.peekswith|IStream.Nil->failerr_matchfailure|IStream.Cons({m_sub=(_,sub);m_ctx},s)->letans=Id.Map.bindingssubinletans=Array.map_of_listsndansinletans=Value.of_tuple[|Value.of_extval_matching_contextm_ctx;Value.of_arrayValue.of_constrans|]inProofview.tclOR(returnans)(fun_->of_anss)inpf_applybeginfunenvsigma->letpat=Constr_matching.instantiate_patternenvsigmaId.Map.emptypatinletans=Constr_matching.match_subtermenvsigma(Id.Set.empty,pat)cinof_ansansendendletmatch_pattern=map_repr(fun(b,pat)->ifbthenTac2match.MatchPatternpatelseTac2match.MatchContextpat)(functionTac2match.MatchPatternpat->(true,pat)|MatchContextpat->(false,pat))(pairboolpattern)let()=define3"pattern_matches_goal"bool(list(pair(optionmatch_pattern)match_pattern))match_patternbeginfunrevhpcp->assert_focussed>>=fun()->Proofview.Goal.enter_onebeginfungl->letenv=Proofview.Goal.envglinletsigma=Proofview.Goal.sigmaglinletconcl=Proofview.Goal.conclglinTac2match.match_goalenvsigmaconcl~rev(hp,cp)>>=fun(hyps,ctx,subst)->letof_ctxoptctx=Value.of_extval_matching_context(Option.defaultempty_contextctx)inlethids=Value.of_arrayValue.of_ident(Array.map_of_listpi1hyps)inlethbctx=Value.of_arrayof_ctxopt(Array.of_list(CList.filter_map(fun(_,bctx,_)->bctx)hyps))inlethctx=Value.of_arrayof_ctxopt(Array.map_of_listpi3hyps)inletsubs=Value.of_arrayValue.of_constr(Array.map_of_listsnd(Id.Map.bindingssubst))inletcctx=of_ctxoptctxinletans=Value.of_tuple[|hids;hbctx;hctx;subs;cctx|]inProofview.tclUNITansendendlet()=define2"pattern_instantiate"(repr_extval_matching_context)constrbeginfunctxc->letans=Constr_matching.instantiate_contextctxcinreturn(Value.of_constrans)end(** Error *)let()=define1"throw"exnbeginfun(e,info)->throw~infoeend(** Control *)(** exn -> 'a *)let()=define1"zero"exnbeginfun(e,info)->fail~infoeend(** (unit -> 'a) -> (exn -> 'a) -> 'a *)let()=define2"plus"closureclosurebeginfunxk->Proofview.tclOR(thawx)(fune->Tac2ffi.applyk[Value.of_exne])end(** (unit -> 'a) -> 'a *)let()=define1"once"closurebeginfunf->Proofview.tclONCE(thawf)end(** (unit -> unit) list -> unit *)let()=define1"dispatch"(listclosure)beginfunl->letl=List.map(funf->Proofview.tclIGNORE(thawf))linProofview.tclDISPATCHl>>=fun()->returnv_unitend(** (unit -> unit) list -> (unit -> unit) -> (unit -> unit) list -> unit *)let()=define3"extend"(listclosure)closure(listclosure)beginfunlfttacrgt->letlft=List.map(funf->Proofview.tclIGNORE(thawf))lftinlettac=Proofview.tclIGNORE(thawtac)inletrgt=List.map(funf->Proofview.tclIGNORE(thawf))rgtinProofview.tclEXTENDlfttacrgt>>=fun()->returnv_unitend(** (unit -> unit) -> unit *)let()=define1"enter"closurebeginfunf->letf=Proofview.tclIGNORE(thawf)inProofview.tclINDEPENDENTf>>=fun()->returnv_unitend(** (unit -> 'a) -> ('a * ('exn -> 'a)) result *)let()=define1"case"closurebeginfunf->Proofview.tclCASE(thawf)>>=beginfunction|Proofview.Next(x,k)->letk=Tac2ffi.mk_closurearity_onebeginfune->let(e,info)=Value.to_exneinset_btinfo>>=funinfo->k(e,info)endinreturn(v_blk0[|Value.of_tuple[|x;Value.of_closurek|]|])|Proofview.Faile->return(v_blk1[|Value.of_exne|])endend(** int -> int -> (unit -> 'a) -> 'a *)let()=define3"focus"intintclosurebeginfunijtac->Proofview.tclFOCUSij(thawtac)end(** unit -> unit *)let()=define0"shelve"beginProofview.shelve>>=fun()->returnv_unitend(** unit -> unit *)let()=define0"shelve_unifiable"beginProofview.shelve_unifiable>>=fun()->returnv_unitendlet()=define1"new_goal"evarbeginfunev->Proofview.tclEVARMAP>>=funsigma->ifEvd.memsigmaevthenProofview.Unsafe.tclNEWGOALS[Proofview.with_empty_stateev]<*>Proofview.tclUNITv_unitelsethrowerr_notfoundend(** unit -> constr *)let()=define0"goal"beginassert_focussed>>=fun()->Proofview.Goal.enter_onebeginfungl->letconcl=Tacmach.pf_nf_conclglinreturn(Value.of_constrconcl)endend(** ident -> constr *)let()=define1"hyp"identbeginfunid->pf_applybeginfunenv_->letmem=tryignore(Environ.lookup_namedidenv);truewithNot_found->falseinifmemthenreturn(Value.of_constr(EConstr.mkVarid))elseTacticals.tclZEROMSG(str"Hypothesis "++quote(Id.printid)++str" not found")(* FIXME: Do something more sensible *)endendlet()=define0"hyps"beginpf_applybeginfunenv_->letopenContextinletopenNamed.Declarationinlethyps=List.rev(Environ.named_contextenv)inletmap=function|LocalAssum(id,t)->lett=EConstr.of_constrtinValue.of_tuple[|Value.of_identid.binder_name;Value.of_optionValue.of_constrNone;Value.of_constrt|]|LocalDef(id,c,t)->letc=EConstr.of_constrcinlett=EConstr.of_constrtinValue.of_tuple[|Value.of_identid.binder_name;Value.of_optionValue.of_constr(Somec);Value.of_constrt|]inreturn(Value.of_listmaphyps)endend(** (unit -> constr) -> unit *)let()=define1"refine"closurebeginfunc->letc=thawc>>=func->Proofview.tclUNIT((),Value.to_constrc)inProofview.Goal.enterbeginfungl->Refine.generic_refine~typecheck:truecglend>>=fun()->returnv_unitendlet()=define2"with_holes"closureclosurebeginfunxf->Proofview.tclEVARMAP>>=funsigma0->thawx>>=funans->Proofview.tclEVARMAP>>=funsigma->Proofview.Unsafe.tclEVARSsigma0>>=fun()->Tacticals.tclWITHHOLESfalse(Tac2ffi.applyf[ans])sigmaendlet()=define1"progress"closurebeginfunf->Proofview.tclPROGRESS(thawf)endlet()=define2"abstract"(optionident)closurebeginfunidf->Abstract.tclABSTRACTid(Proofview.tclIGNORE(thawf))>>=fun()->returnv_unitendlet()=define2"time"(optionstring)closurebeginfunsf->Proofview.tclTIMEs(thawf)endlet()=define0"check_interrupt"beginProofview.tclCHECKINTERRUPT>>=fun()->returnv_unitend(** Fresh *)let()=define2"fresh_free_union"(repr_extval_free)(repr_extval_free)beginfunset1set2->letans=Id.Set.unionset1set2inreturn(Value.of_extValue.val_freeans)endlet()=define1"fresh_free_of_ids"(listident)beginfunids->letfree=List.fold_rightId.Set.addidsId.Set.emptyinreturn(Value.of_extValue.val_freefree)endlet()=define1"fresh_free_of_constr"constrbeginfunc->Proofview.tclEVARMAP>>=funsigma->letrecfoldaccuc=matchEConstr.kindsigmacwith|Constr.Varid->Id.Set.addidaccu|_->EConstr.foldsigmafoldaccucinletans=foldId.Set.emptycinreturn(Value.of_extValue.val_freeans)endlet()=define2"fresh_fresh"(repr_extval_free)identbeginfunavoidid->letnid=Namegen.next_ident_away_fromid(funid->Id.Set.memidavoid)inreturn(Value.of_identnid)end(** Env *)let()=define1"env_get"(listident)beginfunids->letr=matchidswith|[]->None|_::_asids->let(id,path)=List.sep_lastidsinletpath=DirPath.make(List.revpath)inletfp=Libnames.make_pathpathidintrySome(Nametab.global_of_pathfp)withNot_found->Noneinreturn(Value.of_optionValue.of_referencer)endlet()=define1"env_expand"(listident)beginfunids->letr=matchidswith|[]->[]|_::_asids->let(id,path)=List.sep_lastidsinletpath=DirPath.make(List.revpath)inletqid=Libnames.make_qualidpathidinNametab.locate_allqidinreturn(Value.of_listValue.of_referencer)endlet()=define1"env_path"referencebeginfunr->matchNametab.path_of_globalrwith|fp->let(path,id)=Libnames.repr_pathfpinletpath=DirPath.reprpathinreturn(Value.of_listValue.of_ident(List.rev_appendpath[id]))|exceptionNot_found->throwerr_notfoundendlet()=define1"env_instantiate"referencebeginfunr->Proofview.tclENV>>=funenv->Proofview.tclEVARMAP>>=funsigma->let(sigma,c)=Evd.fresh_globalenvsigmarinProofview.Unsafe.tclEVARSsigma>>=fun()->return(Value.of_constrc)end(** Ind *)let()=define2"ind_equal"(repr_extval_inductive)(repr_extval_inductive)beginfunind1ind2->return(Value.of_bool(Ind.UserOrd.equalind1ind2))endlet()=define1"ind_data"(repr_extval_inductive)beginfunind->Proofview.tclENV>>=funenv->ifEnviron.mem_mind(fstind)envthenletmib=Environ.lookup_mind(fstind)envinreturn(Value.of_extval_ind_data(ind,mib))elsethrowerr_notfoundendlet()=define1"ind_repr"(repr_extval_ind_data)beginfun(ind,_)->return(Value.of_extval_inductiveind)endlet()=define1"ind_index"(repr_extval_inductive)beginfun(ind,n)->return(Value.of_intn)endlet()=define1"ind_nblocks"(repr_extval_ind_data)beginfun(ind,mib)->return(Value.of_int(Array.lengthmib.Declarations.mind_packets))endlet()=define1"ind_nconstructors"(repr_extval_ind_data)beginfun((_,n),mib)->letopenDeclarationsinreturn(Value.of_int(Array.lengthmib.mind_packets.(n).mind_consnames))endlet()=define2"ind_get_block"(repr_extval_ind_data)intbeginfun(ind,mib)n->if0<=n&&n<Array.lengthmib.Declarations.mind_packetsthenreturn(Value.of_extval_ind_data((fstind,n),mib))elsethrowerr_notfoundendlet()=define2"ind_get_constructor"(repr_extval_ind_data)intbeginfun((mind,n),mib)i->letopenDeclarationsinletncons=Array.lengthmib.mind_packets.(n).mind_consnamesinif0<=i&&i<nconsthen(* WARNING: In the ML API constructors are indexed from 1 for historical
reasons, but Ltac2 uses 0-indexing instead. *)return(Value.of_extval_constructor((mind,n),i+1))elsethrowerr_notfoundend(** Ltac1 in Ltac2 *)letltac1=Tac2ffi.repr_extValue.val_ltac1letof_ltac1v=Value.of_extValue.val_ltac1vlet()=define1"ltac1_ref"(listident)beginfunids->letopenLtac_plugininletr=matchidswith|[]->raiseNot_found|_::_asids->let(id,path)=List.sep_lastidsinletpath=DirPath.make(List.revpath)inletfp=Libnames.make_pathpathidinifTacenv.exists_tacticfpthenList.hd(Tacenv.locate_extended_all_tactic(Libnames.qualid_of_pathfp))elseraiseNot_foundinlettac=Tacinterp.Value.of_closure(Tacinterp.default_ist())(Tacenv.interp_ltacr)inreturn(Value.of_extval_ltac1tac)endlet()=define1"ltac1_run"ltac1beginfunv->letopenLtac_plugininTacinterp.tactic_of_value(Tacinterp.default_ist())v>>=fun()->returnv_unitendlet()=define3"ltac1_apply"ltac1(listltac1)closurebeginfunfargsk->letopenLtac_plugininletopenTacexprinletopenLocusinletkret=Proofview.tclIGNORE(Tac2ffi.applyk[Value.of_extval_ltac1ret])inletfoldarg(i,vars,lfun)=letid=Id.of_string("x"^string_of_inti)inletx=Reference(ArgVarCAst.(makeid))in(succi,x::vars,Id.Map.addidarglfun)inlet(_,args,lfun)=List.fold_rightfoldargs(0,[],Id.Map.empty)inletlfun=Id.Map.add(Id.of_string"F")flfuninletist={(Tacinterp.default_ist())withTacinterp.lfun=lfun;}inlettac=CAst.make@@TacArg(TacCall(CAst.make(ArgVarCAst.(make@@Id.of_string"F"),args)))inTacinterp.val_interpisttack>>=fun()->returnv_unitendlet()=define1"ltac1_of_constr"constrbeginfunc->letopenLtac_plugininreturn(Value.of_extval_ltac1(Tacinterp.Value.of_constrc))endlet()=define1"ltac1_to_constr"ltac1beginfunv->letopenLtac_plugininreturn(Value.of_optionValue.of_constr(Tacinterp.Value.to_constrv))endlet()=define1"ltac1_of_ident"identbeginfunc->letopenLtac_plugininreturn(Value.of_extval_ltac1(Taccoerce.Value.of_identc))endlet()=define1"ltac1_to_ident"ltac1beginfunv->letopenLtac_plugininreturn(Value.of_optionValue.of_ident(Taccoerce.Value.to_identv))endlet()=define1"ltac1_of_list"(listltac1)beginfunl->letopenGeninterp.Valinreturn(Value.of_extval_ltac1(inject(Basetyp_list)l))endlet()=define1"ltac1_to_list"ltac1beginfunv->letopenLtac_plugininreturn(Value.of_option(Value.of_listof_ltac1)(Tacinterp.Value.to_listv))endmoduleMapTagDyn=Dyn.Make()type('a,'set,'map)map_tag=('a*'set*'map)MapTagDyn.tagtypeany_map_tag=Any:_map_tag->any_map_tagtypetagged_set=TaggedSet:(_,'set,_)map_tag*'set->tagged_settypetagged_map=TaggedMap:(_,_,'map)map_tag*'map->tagged_mapletmap_tag_ext:any_map_tagTac2dyn.Val.tag=Tac2dyn.Val.create"fmap_tag"letmap_tag_repr=Value.repr_extmap_tag_extletset_ext:tagged_setTac2dyn.Val.tag=Tac2dyn.Val.create"fset"letset_repr=Value.repr_extset_extlettag_settags=Value.repr_ofset_repr(TaggedSet(tag,s))letmap_ext:tagged_mapTac2dyn.Val.tag=Tac2dyn.Val.create"fmap"letmap_repr=Value.repr_extmap_extlettag_maptagm=Value.repr_ofmap_repr(TaggedMap(tag,m))moduletypeMapType=sig(* to have less boilerplate we use S.elt rather than declaring a toplevel type t *)moduleS:CSig.SetSmoduleM:CMap.ExtSwithtypekey=S.eltandmoduleSet:=Stypevalmapvalvalmap_eq:(valmap,valexprM.t)Util.eqvalrepr:S.eltValue.reprendmoduleMapTypeV=structtype_t=Map:(moduleMapTypewithtypeS.elt='tandtypeS.t='setandtypevalmap='map)->('t*'set*'map)tendmoduleMapMap=MapTagDyn.Map(MapTypeV)letmaps=refMapMap.emptyletregister_map?(plugin=ltac2_plugin)~tag_namex=lettag=MapTagDyn.create(plugin^":"^tag_name)inlet()=maps:=MapMap.addtag(Mapx)!mapsinlet()=defineval~plugintag_name(repr_ofmap_tag_repr(Anytag))intagletget_map(typetsm)(tag:(t,s,m)map_tag):(moduleMapTypewithtypeS.elt=tandtypeS.t=sandtypevalmap=m)=letMapv=MapMap.findtag!mapsinvletmap_tag_eq(typeabca'b'c')(t1:(a,b,c)map_tag)(t2:(a',b',c')map_tag):(a*b*c,a'*b'*c')Util.eqoption=MapTagDyn.eqt1t2letassert_map_tag_eqt1t2=matchmap_tag_eqt1t2with|Somev->v|None->assertfalseletident_map_tag:_map_tag=register_map~tag_name:"fmap_ident_tag"(modulestructmoduleS=Id.SetmoduleM=Id.Mapletrepr=Value.identtypevalmap=valexprM.tletvalmap_eq=Reflend)letint_map_tag:_map_tag=register_map~tag_name:"fmap_int_tag"(modulestructmoduleS=Int.SetmoduleM=Int.Mapletrepr=Value.inttypevalmap=valexprM.tletvalmap_eq=Reflend)letstring_map_tag:_map_tag=register_map~tag_name:"fmap_string_tag"(modulestructmoduleS=String.SetmoduleM=String.Mapletrepr=Value.stringtypevalmap=valexprM.tletvalmap_eq=Reflend)letinductive_map_tag:_map_tag=register_map~tag_name:"fmap_inductive_tag"(modulestructmoduleS=Indset_envmoduleM=Indmap_envletrepr=Value.(repr_extval_inductive)typevalmap=valexprM.tletvalmap_eq=Reflend)letconstructor_map_tag:_map_tag=register_map~tag_name:"fmap_constructor_tag"(modulestructmoduleS=Constrset_envmoduleM=Constrmap_envletrepr=Value.(repr_extval_constructor)typevalmap=valexprM.tletvalmap_eq=Reflend)letconstant_map_tag:_map_tag=register_map~tag_name:"fmap_constant_tag"(modulestructmoduleS=Cset_envmoduleM=Cmap_envletrepr=Value.(repr_extval_constant)typevalmap=valexprM.tletvalmap_eq=Reflend)let()=define1"fset_empty"map_tag_reprbeginfun(Anytag)->letmoduleV=(valget_maptag)inletopenVinreturn(tag_settagS.empty)endlet()=define1"fset_is_empty"set_reprbeginfun(TaggedSet(tag,s))->letmoduleV=(valget_maptag)inletopenVinreturn(Value.of_bool(S.is_emptys))endlet()=define2"fset_mem"valexprset_reprbeginfunx(TaggedSet(tag,s))->letmoduleV=(valget_maptag)inletopenVinletx=repr_toreprxinreturn(Value.of_bool(S.memxs))endlet()=define2"fset_add"valexprset_reprbeginfunx(TaggedSet(tag,s))->letmoduleV=(valget_maptag)inletopenVinletx=repr_toreprxinreturn(tag_settag(S.addxs))endlet()=define2"fset_remove"valexprset_reprbeginfunx(TaggedSet(tag,s))->letmoduleV=(valget_maptag)inletopenVinletx=repr_toreprxinreturn(tag_settag(S.removexs))endlet()=define2"fset_union"set_reprset_reprbeginfun(TaggedSet(tag,s1))(TaggedSet(tag',s2))->letRefl=assert_map_tag_eqtagtag'inletmoduleV=(valget_maptag)inletopenVinreturn(tag_settag(S.unions1s2))endlet()=define2"fset_inter"set_reprset_reprbeginfun(TaggedSet(tag,s1))(TaggedSet(tag',s2))->letRefl=assert_map_tag_eqtagtag'inletmoduleV=(valget_maptag)inletopenVinreturn(tag_settag(S.inters1s2))endlet()=define2"fset_diff"set_reprset_reprbeginfun(TaggedSet(tag,s1))(TaggedSet(tag',s2))->letRefl=assert_map_tag_eqtagtag'inletmoduleV=(valget_maptag)inletopenVinreturn(tag_settag(S.diffs1s2))endlet()=define2"fset_equal"set_reprset_reprbeginfun(TaggedSet(tag,s1))(TaggedSet(tag',s2))->letRefl=assert_map_tag_eqtagtag'inletmoduleV=(valget_maptag)inletopenVinreturn(Value.of_bool(S.equals1s2))endlet()=define2"fset_subset"set_reprset_reprbeginfun(TaggedSet(tag,s1))(TaggedSet(tag',s2))->letRefl=assert_map_tag_eqtagtag'inletmoduleV=(valget_maptag)inletopenVinreturn(Value.of_bool(S.subsets1s2))endlet()=define1"fset_cardinal"set_reprbeginfun(TaggedSet(tag,s))->letmoduleV=(valget_maptag)inletopenVinreturn(Value.of_int(S.cardinals))endlet()=define1"fset_elements"set_reprbeginfun(TaggedSet(tag,s))->letmoduleV=(valget_maptag)inletopenVinreturn(Value.of_list(repr_ofrepr)(S.elementss))endlet()=define1"fmap_empty"map_tag_reprbeginfun(Any(tag))->letmoduleV=(valget_maptag)inletopenVinletRefl=valmap_eqinreturn(tag_maptagM.empty)endlet()=define1"fmap_is_empty"map_reprbeginfun(TaggedMap(tag,m))->letmoduleV=(valget_maptag)inletopenVinletRefl=valmap_eqinreturn(Value.of_bool(M.is_emptym))endlet()=define2"fmap_mem"valexprmap_reprbeginfunx(TaggedMap(tag,m))->letmoduleV=(valget_maptag)inletopenVinletRefl=valmap_eqinletx=repr_toreprxinreturn(Value.of_bool(M.memxm))endlet()=define3"fmap_add"valexprvalexprmap_reprbeginfunxv(TaggedMap(tag,m))->letmoduleV=(valget_maptag)inletopenVinletRefl=valmap_eqinletx=repr_toreprxinreturn(tag_maptag(M.addxvm))endlet()=define2"fmap_remove"valexprmap_reprbeginfunx(TaggedMap(tag,m))->letmoduleV=(valget_maptag)inletopenVinletRefl=valmap_eqinletx=repr_toreprxinreturn(tag_maptag(M.removexm))endlet()=define2"fmap_find_opt"valexprmap_reprbeginfunx(TaggedMap(tag,m))->letmoduleV=(valget_maptag)inletopenVinletRefl=valmap_eqinletx=repr_toreprxinreturn(Value.of_option(funv->v)(M.find_optxm))endlet()=define2"fmap_mapi"closuremap_reprbeginfunf(TaggedMap(tag,m))->letmoduleV=(valget_maptag)inletopenVinletRefl=valmap_eqinletmoduleMonadic=M.Monad(Proofview.Monad)inMonadic.mapi(funkv->applyf[repr_ofreprk;v])m>>=funm->return(tag_maptagm)endlet()=define3"fmap_fold"closuremap_reprvalexprbeginfunf(TaggedMap(tag,m))acc->letmoduleV=(valget_maptag)inletopenVinletRefl=valmap_eqinletmoduleMonadic=M.Monad(Proofview.Monad)inMonadic.fold(funkvacc->applyf[repr_ofreprk;v;acc])maccendlet()=define1"fmap_cardinal"map_reprbeginfun(TaggedMap(tag,m))->letmoduleV=(valget_maptag)inletopenVinletRefl=valmap_eqinreturn(Value.of_int(M.cardinalm))endlet()=define1"fmap_bindings"map_reprbeginfun(TaggedMap(tag,m))->letmoduleV=(valget_maptag)inletopenVinletRefl=valmap_eqinreturn(Value.(of_list(of_pair(repr_ofrepr)identity)(M.bindingsm)))endlet()=define1"fmap_domain"map_reprbeginfun(TaggedMap(tag,m))->letmoduleV=(valget_maptag)inletopenVinletRefl=valmap_eqinreturn(tag_settag(M.domainm))end(** ML types *)(** Embed all Ltac2 data into Values *)letto_lvarist=letopenGlob_opsinletlfun=Tac2interp.set_envistId.Map.emptyin{empty_lvarwithLtac_pretype.ltac_genargs=lfun}letgtyprefkn=GTypRef(Otherkn,[])letintern_constrselfistc=let(_,(c,_))=Genintern.internStdarg.wit_constristcinletv=matchDAst.getcwith|GGenarg(GenArg(Glbwittag,v))->beginmatchgenarg_type_eqtagwit_ltac2_var_quotationwith|SomeRefl->beginmatch(fstv)with|ConstrVar->GlbTacexpr(GTacVar(sndv))|_->GlbValcend|None->GlbValcend|_->GlbValcin(v,gtypreft_constr)letinterp_constrflagsistc=letopenPretypinginletist=to_lvaristinpf_apply~catch_exceptions:truebeginfunenvsigma->let(sigma,c)=understand_ltacflagsenvsigmaistWithoutTypeConstraintcinletc=Value.of_constrcinProofview.Unsafe.tclEVARSsigma>>=fun()->Proofview.tclUNITcendlet()=letintern=intern_constrinletinterpistc=interp_constrconstr_flagsistcinletprintenvsigmac=str"constr:("++Printer.pr_lglob_constr_envenvsigmac++str")"inletsubstsubstc=Detyping.subst_glob_constr(Global.env())substcinletobj={ml_intern=intern;ml_subst=subst;ml_interp=interp;ml_print=print;}indefine_ml_objectTac2quote.wit_constrobjlet()=letintern=intern_constrinletinterpistc=interp_constropen_constr_no_classes_flagsistcinletprintenvsigmac=str"open_constr:("++Printer.pr_lglob_constr_envenvsigmac++str")"inletsubstsubstc=Detyping.subst_glob_constr(Global.env())substcinletobj={ml_intern=intern;ml_subst=subst;ml_interp=interp;ml_print=print;}indefine_ml_objectTac2quote.wit_open_constrobjlet()=letinterp_id=return(Value.of_identid)inletprint__id=str"ident:("++Id.printid++str")"inletobj={ml_intern=(fun__id->GlbValid,gtypreft_ident);ml_interp=interp;ml_subst=(fun_id->id);ml_print=print;}indefine_ml_objectTac2quote.wit_identobjlet()=letinternselfistc=letenv=ist.Genintern.genvinletsigma=Evd.from_envenvinletstrict_check=ist.Genintern.strict_checkinlet_,pat=Constrintern.intern_constr_patternenvsigma~strict_check~as_type:falsecinGlbValpat,gtypreft_patterninletsubstsubstc=letenv=Global.env()inletsigma=Evd.from_envenvinPatternops.subst_patternenvsigmasubstcinletprintenvsigmapat=str"pat:("++Printer.pr_lconstr_pattern_envenvsigmapat++str")"inletinterp_c=return(Value.of_patternc)inletobj={ml_intern=intern;ml_interp=interp;ml_subst=subst;ml_print=print;}indefine_ml_objectTac2quote.wit_patternobjlet()=letinternselfistc=let(_,(c,_))=Genintern.internStdarg.wit_constristcin(GlbVal(Id.Set.empty,c),gtypreft_preterm)inletinterpenv(ids,c)=letopenLtac_pretypeinletget_pretermid=matchId.Map.find_optidenv.env_istwith|Some(ValExt(tag,v))->beginmatchTac2dyn.Val.eqtagval_pretermwith|SomeRefl->(v:closed_glob_constr)|None->assertfalseend|_->assertfalseinletclosure={idents=Id.Map.empty;typed=Id.Map.empty;untyped=Id.Map.bindget_pretermids;genargs=Tac2interp.set_envenvId.Map.empty;}inletc={closure;term=c}inreturn(Value.of_extval_pretermc)inletsubstsubst(ids,c)=ids,Detyping.subst_glob_constr(Global.env())substcinletprintenvsigma(ids,c)=letppids=ifId.Set.is_emptyidsthenmt()elseprlist_with_sepspcId.print(Id.Set.elementsids)++spc()++str"|-"++spc()instr"preterm:("++ppids++Printer.pr_lglob_constr_envenvsigmac++str")"inletobj={ml_intern=intern;ml_interp=interp;ml_subst=subst;ml_print=print;}indefine_ml_objectTac2quote.wit_pretermobjlet()=letinternselfistref=matchref.CAst.vwith|Tac2qexpr.QHypothesisid->GlbVal(GlobRef.VarRefid),gtypreft_reference|Tac2qexpr.QReferenceqid->letgr=tryNametab.locateqidwithNot_foundasexn->let_,info=Exninfo.captureexninNametab.error_global_not_found~infoqidinGlbValgr,gtypreft_referenceinletsubstsc=Globnames.subst_global_referencescinletinterp_gr=return(Value.of_referencegr)inletprint__=function|GlobRef.VarRefid->str"reference:("++str"&"++Id.printid++str")"|r->str"reference:("++Printer.pr_globalr++str")"inletobj={ml_intern=intern;ml_subst=subst;ml_interp=interp;ml_print=print;}indefine_ml_objectTac2quote.wit_referenceobjlet()=letinternselfist(ids,tac)=letmap{CAst.v=id}=idinletids=List.mapmapidsin(* Prevent inner calls to Ltac2 values *)letextra=Tac2intern.drop_ltac2_envist.Genintern.extrainletltacvars=List.fold_rightId.Set.addidsist.Genintern.ltacvarsinletist={istwithGenintern.extra;ltacvars}inlet_,tac=Genintern.internLtac_plugin.Tacarg.wit_tacticisttacinletfoldty_=GTypArrow(gtypreft_ltac1,ty)inletty=List.fold_leftfold(gtypreft_unit)idsinGlbVal(ids,tac),tyinletinterp_(ids,tac)=letclosargs=letaddlfunidv=letv=Tac2ffi.to_extval_ltac1vinId.Map.addidvlfuninletlfun=List.fold_left2addId.Map.emptyidsargsinletist={env_ist=Id.Map.empty}inletlfun=Tac2interp.set_envistlfuninletist=Ltac_plugin.Tacinterp.default_ist()inletist={istwithGeninterp.lfun=lfun}inlettac=(Ltac_plugin.Tacinterp.eval_tactic_ististtac:unitProofview.tactic)intac>>=fun()->returnv_unitinletlen=List.lengthidsinifInt.equallen0thenclos[]elsereturn(Tac2ffi.of_closure(Tac2ffi.abstractlenclos))inletsubsts(ids,tac)=(ids,Genintern.substituteLtac_plugin.Tacarg.wit_tacticstac)inletprintenvsigma(ids,tac)=letids=ifList.is_emptyidsthenmt()elsepr_sequenceId.printids++spc()++str"|-"++spc()instr"ltac1:("++ids++Ltac_plugin.Pptactic.pr_glob_tacticenvtac++str")"inletobj={ml_intern=intern;ml_subst=subst;ml_interp=interp;ml_print=print;}indefine_ml_objectTac2quote.wit_ltac1objlet()=letopenLtac_plugininletinternselfist(ids,tac)=letmap{CAst.v=id}=idinletids=List.mapmapidsin(* Prevent inner calls to Ltac2 values *)letextra=Tac2intern.drop_ltac2_envist.Genintern.extrainletltacvars=List.fold_rightId.Set.addidsist.Genintern.ltacvarsinletist={istwithGenintern.extra;ltacvars}inlet_,tac=Genintern.internLtac_plugin.Tacarg.wit_tacticisttacinletfoldty_=GTypArrow(gtypreft_ltac1,ty)inletty=List.fold_leftfold(gtypreft_ltac1)idsinGlbVal(ids,tac),tyinletinterp_(ids,tac)=letclosargs=letaddlfunidv=letv=Tac2ffi.to_extval_ltac1vinId.Map.addidvlfuninletlfun=List.fold_left2addId.Map.emptyidsargsinletist={env_ist=Id.Map.empty}inletlfun=Tac2interp.set_envistlfuninletist=Ltac_plugin.Tacinterp.default_ist()inletist={istwithGeninterp.lfun=lfun}inreturn(Value.of_extval_ltac1(Tacinterp.Value.of_closureisttac))inletlen=List.lengthidsinifInt.equallen0thenclos[]elsereturn(Tac2ffi.of_closure(Tac2ffi.abstractlenclos))inletsubsts(ids,tac)=(ids,Genintern.substituteTacarg.wit_tacticstac)inletprintenvsigma(ids,tac)=letids=ifList.is_emptyidsthenmt()elsepr_sequenceId.printids++str" |- "instr"ltac1val:("++ids++Ltac_plugin.Pptactic.pr_glob_tacticenvtac++str")"inletobj={ml_intern=intern;ml_subst=subst;ml_interp=interp;ml_print=print;}indefine_ml_objectTac2quote.wit_ltac1valobj(** Ltac2 in terms *)let()=letinterp?loc~polyenvsigmatycon(ids,tac)=(* Syntax prevents bound notation variables in constr quotations *)let()=assert(Id.Set.is_emptyids)inletist=Tac2interp.get_env@@GlobEnv.lfunenvinlettac=Proofview.tclIGNORE(Tac2interp.interpisttac)inletname,poly=Id.of_string"ltac2",polyinletsigma,concl=matchtyconwith|Somety->sigma,ty|None->GlobEnv.new_type_evarenvsigma~src:(loc,Evar_kinds.InternalHole)inletc,sigma=Proof.refine_by_tactic~name~poly(GlobEnv.renamed_envenv)sigmaconcltacinletj={Environ.uj_val=EConstr.of_constrc;Environ.uj_type=concl}in(j,sigma)inGlobEnv.register_constr_interp0wit_ltac2_constrinterpletinterp_constr_var_as_constr?locenvsigmatyconid=letist=Tac2interp.get_env@@GlobEnv.lfunenvinletenv=GlobEnv.renamed_envenvinletc=Id.Map.findidist.env_istinletc=Value.to_constrcinlett=Retyping.get_type_ofenvsigmacinletj={Environ.uj_val=c;uj_type=t}inmatchtyconwith|None->j,sigma|Somety->letsigma=tryEvarconv.unify_leq_delayenvsigmattywithEvarconv.UnableToUnify(sigma,e)->Pretype_errors.error_actual_type?locenvsigmajtyein{jwithEnviron.uj_type=ty},sigmaletinterp_preterm_var_as_constr?locenvsigmatyconid=letopenLtac_pretypeinletist=Tac2interp.get_env@@GlobEnv.lfunenvinletenv=GlobEnv.renamed_envenvinletc=Id.Map.findidist.env_istinlet{closure;term}=Value.to_extValue.val_pretermcinletvars={ltac_constrs=closure.typed;ltac_uconstrs=closure.untyped;ltac_idents=closure.idents;ltac_genargs=closure.genargs;}inletflags=preterm_flagsinlettycon=letopenPretypinginmatchtyconwith|Somety->OfTypety|None->WithoutTypeConstraintinletsigma,t,ty=Pretyping.understand_ltac_tyflagsenvsigmavarstyconterminEnviron.make_judgetty,sigmalet()=letinterp?loc~polyenvsigmatycon(kind,id)=letf=matchkindwith|ConstrVar->interp_constr_var_as_constr|PretermVar->interp_preterm_var_as_constrinf?locenvsigmatyconidinGlobEnv.register_constr_interp0wit_ltac2_var_quotationinterplet()=letpr_raw(kind,id)=Genprint.PrinterBasic(fun_env_sigma->letppkind=matchkindwith|None->mt()|Somekind->Id.printkind.CAst.v++str":"instr"$"++ppkind++Id.printid.CAst.v)inletpr_glb(kind,id)=Genprint.PrinterBasic(fun_env_sigma->letppkind=matchkindwith|ConstrVar->mt()|PretermVar->str"preterm:"instr"$"++ppkind++Id.printid)inletpr_topx=Util.Empty.abortxinGenprint.register_print0wit_ltac2_var_quotationpr_rawpr_glbpr_toplet()=letsubsavoidglobs(ids,tac)=(* Let-bind the notation terms inside the tactic *)letfoldidc(rem,accu)=letc=GTacExt(Tac2quote.wit_preterm,(avoid,c))inletrem=Id.Set.removeidreminrem,(Nameid,c)::accuinletrem,bnd=Id.Map.foldfoldglobs(ids,[])inlet()=ifnot@@Id.Set.is_emptyremthen(* FIXME: provide a reasonable middle-ground with the behaviour
introduced by 8d9b66b. We should be able to pass mere syntax to
term notation without facing the wrath of the internalization. *)letplural=ifId.Set.cardinalrem<=1then" "else"s "inCErrors.user_err(str"Missing notation term for variable"++strplural++pr_sequenceId.print(Id.Set.elementsrem)++str", probably an ill-typed expression")inlettac=ifList.is_emptybndthentacelseGTacLet(false,bnd,tac)in(avoid,tac)inGenintern.register_ntn_subst0wit_ltac2_constrsubs(** Ltac2 in Ltac1 *)let()=letcreatenamewit=lete=Tac2entries.Pltac.tac2expr_in_envinletinject(loc,v)=Ltac_plugin.Tacexpr.TacGeneric(Somename,in_gen(rawwitwit)v)inLtac_plugin.Tacentries.create_ltac_quotation~plugin:ltac2_pluginnameinject(e,None)inlet()=create"ltac2"wit_ltac2in1inlet()=create"ltac2val"wit_ltac2in1_valin()(* Ltac1 runtime representation of Ltac2 closures. *)lettyp_ltac2:valexprGeninterp.Val.typ=Geninterp.Val.create"ltac2:ltac2_eval"let()=Genprint.register_val_print0typ_ltac2(funv->TopPrinterBasic(fun()->Pp.str"<ltac2 closure>"))letcast_typ(typea)(tag:aGeninterp.Val.typ)(v:Geninterp.Val.t):a=letGeninterp.Val.Dyn(tag',v)=vinmatchGeninterp.Val.eqtagtag'with|None->assertfalse|SomeRefl->vlet()=letopenLtac_pluginin(* This is a hack similar to Tacentries.ml_val_tactic_extend *)letintern_fun_e=Empty.aborteinletsubst_funsv=vinlet()=Genintern.register_intern0wit_ltac2_valintern_funinlet()=Genintern.register_subst0wit_ltac2_valsubst_funin(* These are bound names and not relevant *)lettac_id=Id.of_string"F"inletarg_id=Id.of_string"X"inletinterp_funist()=lettac=cast_typtyp_ltac2@@Id.Map.gettac_idist.Tacinterp.lfuninletarg=Id.Map.getarg_idist.Tacinterp.lfuninlettac=Tac2ffi.to_closuretacinTac2ffi.applytac[of_ltac1arg]>>=funans->letans=Tac2ffi.to_extval_ltac1ansinFtactic.returnansinlet()=Geninterp.register_interp0wit_ltac2_valinterp_funindefine1"ltac1_lambda"valexprbeginfunf->letbody=Tacexpr.TacGeneric(Someltac2_plugin,in_gen(glbwitwit_ltac2_val)())inletclos=CAst.make(Tacexpr.TacFun([Namearg_id],CAst.make(Tacexpr.TacArgbody)))inletf=Geninterp.Val.inject(Geninterp.Val.Basetyp_ltac2)finletlfun=Id.Map.singletontac_idfinletist={(Tacinterp.default_ist())withTacinterp.lfun}inProofview.tclUNIT(of_ltac1(Tacinterp.Value.of_closureistclos))endletltac2_eval=letopenLtac_plugininletml_name={Tacexpr.mltac_plugin=ltac2_plugin;mltac_tactic="ltac2_eval";}inleteval_funargsist=matchargswith|[]->assertfalse|tac::args->(* By convention the first argument is the tactic being applied, the rest
being the arguments it should be fed with *)lettac=cast_typtyp_ltac2tacinlettac=Tac2ffi.to_closuretacinletargs=List.map(funarg->Tac2ffi.of_extval_ltac1arg)argsinProofview.tclIGNORE(Tac2ffi.applytacargs)inlet()=Tacenv.register_ml_tacticml_name[|eval_fun|]in{Tacexpr.mltac_name=ml_name;mltac_index=0}let()=letopenLtac_plugininletopenTacinterpinletinterpist(ids,tac)=matchidswith|[]->(* Evaluate the Ltac2 quotation eagerly *)letidtac=Value.of_closure{istwithlfun=Id.Map.empty}(CAst.make(Tacexpr.TacId[]))inletist={env_ist=Id.Map.empty}inTac2interp.interpisttac>>=funv->letv=idtacinFtactic.returnv|_::_->(* Return a closure [@f := {blob} |- fun ids => ltac2_eval(f, ids) ] *)(* This name cannot clash with Ltac2 variables which are all lowercase *)letself_id=Id.of_string"F"inletnas=List.map(funid->Nameid)idsinletmk_argid=Tacexpr.Reference(Locus.ArgVar(CAst.makeid))inletargs=List.mapmk_argidsinletclos=CAst.make(Tacexpr.TacFun(nas,CAst.make(Tacexpr.TacML(ltac2_eval,mk_argself_id::args))))inletself=GTacFun(List.map(funid->Nameid)ids,tac)inletself=Tac2interp.interp_value{env_ist=Id.Map.empty}selfinletself=Geninterp.Val.inject(Geninterp.Val.Basetyp_ltac2)selfinletist={istwithlfun=Id.Map.singletonself_idself}inFtactic.return(Value.of_closureistclos)inGeninterp.register_interp0wit_ltac2in1interplet()=letinterpisttac=letist={env_ist=Id.Map.empty}inTac2interp.interpisttac>>=funv->letv=repr_toltac1vinFtactic.returnvinGeninterp.register_interp0wit_ltac2in1_valinterplet()=letpr_raw_=Genprint.PrinterBasic(fun_env_sigma->assertfalse)inletpr_glb(ids,e)=letids=ifList.is_emptyidsthenmt()elsepr_sequenceId.printids++str" |- "inGenprint.PrinterBasicPp.(fun_env_sigma->ids++Tac2print.pr_glbexpre)inletpr_topx=Util.Empty.abortxinGenprint.register_print0wit_ltac2in1pr_rawpr_glbpr_toplet()=letpr_raw_=Genprint.PrinterBasic(fun_env_sigma->assertfalse)inletpr_glb(ids,e)=letids=letids=Id.Set.elementsidsinifList.is_emptyidsthenmt()elsepr_sequenceId.printids++str" |- "inGenprint.PrinterBasicPp.(fun_env_sigma->ids++Tac2print.pr_glbexpre)inletpr_tope=Util.Empty.aborteinGenprint.register_print0wit_ltac2_constrpr_rawpr_glbpr_top(** Built-in notation scopes *)letadd_scopesf=Tac2entries.register_scope(Id.of_strings)fletrecpr_scope=letopenCAstinfunction|SexprStr{v=s}->qstrings|SexprInt{v=n}->Pp.intn|SexprRec(_,{v=na},args)->letna=matchnawith|None->str"_"|Someid->Id.printidinna++str"("++prlist_with_sep(fun()->str", ")pr_scopeargs++str")"letscope_failsargs=letargs=str"("++prlist_with_sep(fun()->str", ")pr_scopeargs++str")"inCErrors.user_err(str"Invalid arguments "++args++str" in scope "++strs)letq_unit=CAst.make@@CTacCst(AbsKn(Tuple0))letadd_generic_scopesentryarg=letparse=function|[]->letscope=Pcoq.Symbol.ntermentryinletactx=CAst.make@@CTacExt(arg,x)inTac2entries.ScopeRule(scope,act)|arg->scope_failsarginadd_scopesparseopenCAstlet()=add_scope"keyword"beginfunction|[SexprStr{loc;v=s}]->letscope=Pcoq.Symbol.token(Tok.PKEYWORDs)inTac2entries.ScopeRule(scope,(fun_->q_unit))|arg->scope_fail"keyword"argendlet()=add_scope"terminal"beginfunction|[SexprStr{loc;v=s}]->letscope=Pcoq.Symbol.token(Pcoq.terminals)inTac2entries.ScopeRule(scope,(fun_->q_unit))|arg->scope_fail"terminal"argendlet()=add_scope"list0"beginfunction|[tok]->letTac2entries.ScopeRule(scope,act)=Tac2entries.parse_scopetokinletscope=Pcoq.Symbol.list0scopeinletactl=Tac2quote.of_listactlinTac2entries.ScopeRule(scope,act)|[tok;SexprStr{v=str}]->letTac2entries.ScopeRule(scope,act)=Tac2entries.parse_scopetokinletsep=Pcoq.Symbol.tokens[Pcoq.TPattern(Pcoq.terminalstr)]inletscope=Pcoq.Symbol.list0sepscopesepfalseinletactl=Tac2quote.of_listactlinTac2entries.ScopeRule(scope,act)|arg->scope_fail"list0"argendlet()=add_scope"list1"beginfunction|[tok]->letTac2entries.ScopeRule(scope,act)=Tac2entries.parse_scopetokinletscope=Pcoq.Symbol.list1scopeinletactl=Tac2quote.of_listactlinTac2entries.ScopeRule(scope,act)|[tok;SexprStr{v=str}]->letTac2entries.ScopeRule(scope,act)=Tac2entries.parse_scopetokinletsep=Pcoq.Symbol.tokens[Pcoq.TPattern(Pcoq.terminalstr)]inletscope=Pcoq.Symbol.list1sepscopesepfalseinletactl=Tac2quote.of_listactlinTac2entries.ScopeRule(scope,act)|arg->scope_fail"list1"argendlet()=add_scope"opt"beginfunction|[tok]->letTac2entries.ScopeRule(scope,act)=Tac2entries.parse_scopetokinletscope=Pcoq.Symbol.optscopeinletactopt=matchoptwith|None->CAst.make@@CTacCst(AbsKn(OtherCore.c_none))|Somex->CAst.make@@CTacApp(CAst.make@@CTacCst(AbsKn(OtherCore.c_some)),[actx])inTac2entries.ScopeRule(scope,act)|arg->scope_fail"opt"argendlet()=add_scope"self"beginfunction|[]->letscope=Pcoq.Symbol.selfinletacttac=tacinTac2entries.ScopeRule(scope,act)|arg->scope_fail"self"argendlet()=add_scope"next"beginfunction|[]->letscope=Pcoq.Symbol.nextinletacttac=tacinTac2entries.ScopeRule(scope,act)|arg->scope_fail"next"argendlet()=add_scope"tactic"beginfunction|[]->(* Default to level 5 parsing *)letscope=Pcoq.Symbol.ntermlltac2_expr"5"inletacttac=tacinTac2entries.ScopeRule(scope,act)|[SexprInt{loc;v=n}]asarg->let()=ifn<0||n>6thenscope_fail"tactic"arginletscope=Pcoq.Symbol.ntermlltac2_expr(string_of_intn)inletacttac=tacinTac2entries.ScopeRule(scope,act)|arg->scope_fail"tactic"argendlet()=add_scope"thunk"beginfunction|[tok]->letTac2entries.ScopeRule(scope,act)=Tac2entries.parse_scopetokinletacte=Tac2quote.thunk(acte)inTac2entries.ScopeRule(scope,act)|arg->scope_fail"thunk"argendlet()=add_scope"constr"(funarg->letdelimiters=List.map(function|SexprRec(_,{v=Somes},[])->s|_->scope_fail"constr"arg)arginletacte=Tac2quote.of_constr~delimiterseinTac2entries.ScopeRule(Pcoq.Symbol.ntermPcoq.Constr.constr,act))let()=add_scope"open_constr"(funarg->letdelimiters=List.map(function|SexprRec(_,{v=Somes},[])->s|_->scope_fail"open_constr"arg)arginletacte=Tac2quote.of_open_constr~delimiterseinTac2entries.ScopeRule(Pcoq.Symbol.ntermPcoq.Constr.constr,act))let()=add_scope"preterm"(funarg->letdelimiters=List.map(function|SexprRec(_,{v=Somes},[])->s|_->scope_fail"preterm"arg)arginletacte=Tac2quote.of_preterm~delimiterseinTac2entries.ScopeRule(Pcoq.Symbol.ntermPcoq.Constr.constr,act))letadd_expr_scopenameentryf=add_scopenamebeginfunction|[]->Tac2entries.ScopeRule(Pcoq.Symbol.ntermentry,f)|arg->scope_failnameargendlet()=add_expr_scope"ident"q_ident(funid->Tac2quote.of_antiTac2quote.of_identid)let()=add_expr_scope"bindings"q_bindingsTac2quote.of_bindingslet()=add_expr_scope"with_bindings"q_with_bindingsTac2quote.of_bindingslet()=add_expr_scope"intropattern"q_intropatternTac2quote.of_intro_patternlet()=add_expr_scope"intropatterns"q_intropatternsTac2quote.of_intro_patternslet()=add_expr_scope"destruction_arg"q_destruction_argTac2quote.of_destruction_arglet()=add_expr_scope"induction_clause"q_induction_clauseTac2quote.of_induction_clauselet()=add_expr_scope"conversion"q_conversionTac2quote.of_conversionlet()=add_expr_scope"rewriting"q_rewritingTac2quote.of_rewritinglet()=add_expr_scope"clause"q_clauseTac2quote.of_clauselet()=add_expr_scope"hintdb"q_hintdbTac2quote.of_hintdblet()=add_expr_scope"occurrences"q_occurrencesTac2quote.of_occurrenceslet()=add_expr_scope"dispatch"q_dispatchTac2quote.of_dispatchlet()=add_expr_scope"strategy"q_strategy_flagTac2quote.of_strategy_flaglet()=add_expr_scope"reference"q_referenceTac2quote.of_referencelet()=add_expr_scope"move_location"q_move_locationTac2quote.of_move_locationlet()=add_expr_scope"pose"q_poseTac2quote.of_poselet()=add_expr_scope"assert"q_assertTac2quote.of_assertionlet()=add_expr_scope"constr_matching"q_constr_matchingTac2quote.of_constr_matchinglet()=add_expr_scope"goal_matching"q_goal_matchingTac2quote.of_goal_matchinglet()=add_expr_scope"format"Pcoq.Prim.lstringTac2quote.of_formatlet()=add_generic_scope"pattern"Pcoq.Constr.constrTac2quote.wit_pattern(** seq scope, a bit hairy *)openPcoqtype_converter=|CvNil:(Loc.t->raw_tacexpr)converter|CvCns:'actconverter*('a->raw_tacexpr)option->('a->'act)converterletrecapply:typea.aconverter->raw_tacexprlist->a=function|CvNil->funacculoc->Tac2quote.of_tuple~locaccu|CvCns(c,None)->funaccux->applycaccu|CvCns(c,Somef)->funaccux->applyc(fx::accu)typeseqrule=|Seqrule:(Tac2expr.raw_tacexpr,Gramlib.Grammar.norec,'act,Loc.t->raw_tacexpr)Rule.t*'actconverter->seqruleletrecmake_seq_rule=function|[]->Seqrule(Pcoq.Rule.stop,CvNil)|tok::rem->letTac2entries.ScopeRule(scope,f)=Tac2entries.parse_scopetokinletscope=matchPcoq.generalize_symbolscopewith|None->CErrors.user_err(str"Recursive symbols (self / next) are not allowed in local rules")|Somescope->scopeinletSeqrule(r,c)=make_seq_rulereminletr=Pcoq.Rule.next_norecrscopeinletf=matchtokwith|SexprStr_->None(* Leave out mere strings *)|_->SomefinSeqrule(r,CvCns(c,f))let()=add_scope"seq"beginfuntoks->letscope=letSeqrule(r,c)=make_seq_rule(List.revtoks)inPcoq.(Symbol.rules[Rules.maker(applyc[])])inTac2entries.ScopeRule(scope,(fune->e))end