123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412(************************************************************************)(* * 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) *)(************************************************************************)openUtilopenNamesopenTac2dynopenTac2expropenProofview.Notationstype('a,_)arity0=|OneAty:('a,'a->'aProofview.tactic)arity0|AddAty:('a,'b)arity0->('a,'a->'b)arity0typevalexpr=|ValIntofint(** Immediate integers *)|ValBlkoftag*valexprarray(** Structured blocks *)|ValStrofBytes.t(** Strings *)|ValClsofclosure(** Closures *)|ValOpnofKerName.t*valexprarray(** Open constructors *)|ValExt:'aTac2dyn.Val.tag*'a->valexpr(** Arbitrary data *)|ValUint63ofUint63.t(** Primitive integers *)|ValFloatofFloat64.t(** Primitive floats *)andclosure=MLTactic:(valexpr,'v)arity0*'v->closureletarity_one=OneAtyletarity_suca=AddAtyatype'aarity=(valexpr,'a)arity0letmk_closurearityf=MLTactic(arity,f)moduleValexpr=structtypet=valexprletis_int=function|ValInt_->true|ValBlk_|ValStr_|ValCls_|ValOpn_|ValExt_|ValUint63_|ValFloat_->falselettagv=matchvwith|ValBlk(n,_)->n|ValInt_|ValStr_|ValCls_|ValOpn_|ValExt_|ValUint63_|ValFloat_->CErrors.anomaly(Pp.str"Unexpected value shape")letfieldvn=matchvwith|ValBlk(_,v)->v.(n)|ValInt_|ValStr_|ValCls_|ValOpn_|ValExt_|ValUint63_|ValFloat_->CErrors.anomaly(Pp.str"Unexpected value shape")letset_fieldvnw=matchvwith|ValBlk(_,v)->v.(n)<-w|ValInt_|ValStr_|ValCls_|ValOpn_|ValExt_|ValUint63_|ValFloat_->CErrors.anomaly(Pp.str"Unexpected value shape")letmake_blocktagv=ValBlk(tag,v)letmake_intn=ValIntnendtype'arepr={r_of:'a->valexpr;r_to:valexpr->'a;r_id:bool;}letrepr_ofrx=r.r_ofxletrepr_torx=r.r_toxletmake_reprr_ofr_to={r_of;r_to;r_id=false;}(** Dynamic tags *)letval_exn=Val.create"exn"letval_constr=Val.create"constr"letval_ident=Val.create"ident"letval_pattern=Val.create"pattern"letval_preterm=Val.create"preterm"letval_pp=Val.create"pp"letval_sort=Val.create"sort"letval_cast=Val.create"cast"letval_inductive=Val.create"inductive"letval_constant=Val.create"constant"letval_constructor=Val.create"constructor"letval_projection=Val.create"projection"letval_case=Val.create"case"letval_binder=Val.create"binder"letval_univ=Val.create"universe"letval_free:Names.Id.Set.tVal.tag=Val.create"free"letval_ltac1:Geninterp.Val.tVal.tag=Val.create"ltac1"letval_ind_data:(Names.Ind.t*Declarations.mutual_inductive_body)Val.tag=Val.create"ind_data"letextract_val(typea)(typeb)(tag:aVal.tag)(tag':bVal.tag)(v:b):a=matchVal.eqtagtag'with|None->assertfalse|SomeRefl->v(** Exception *)exceptionLtacErrorofKerName.t*valexprarray(** Conversion functions *)letvalexpr={r_of=(funobj->obj);r_to=(funobj->obj);r_id=true;}letof_unit()=ValInt0letto_unit=function|ValInt0->()|_->assertfalseletunit={r_of=of_unit;r_to=to_unit;r_id=false;}letof_intn=ValIntnletto_int=function|ValIntn->n|_->assertfalseletint={r_of=of_int;r_to=to_int;r_id=false;}letof_boolb=ifbthenValInt0elseValInt1letto_bool=function|ValInt0->true|ValInt1->false|_->assertfalseletbool={r_of=of_bool;r_to=to_bool;r_id=false;}letof_charn=ValInt(Char.coden)letto_char=function|ValIntn->Char.chrn|_->assertfalseletchar={r_of=of_char;r_to=to_char;r_id=false;}letof_strings=ValStrsletto_string=function|ValStrs->s|_->assertfalseletstring={r_of=of_string;r_to=to_string;r_id=false;}letrecof_listf=function|[]->ValInt0|x::l->ValBlk(0,[|fx;of_listfl|])letrecto_listf=function|ValInt0->[]|ValBlk(0,[|v;vl|])->fv::to_listfvl|_->assertfalseletlistr={r_of=(funl->of_listr.r_ofl);r_to=(funl->to_listr.r_tol);r_id=false;}letof_closurecls=ValClsclsletto_closure=function|ValClscls->cls|ValExt_|ValInt_|ValBlk_|ValStr_|ValOpn_|ValUint63_|ValFloat_->assertfalseletclosure={r_of=of_closure;r_to=to_closure;r_id=false;}letof_exttagc=ValExt(tag,c)letto_exttag=function|ValExt(tag',e)->extract_valtagtag'e|_->assertfalseletrepr_exttag={r_of=(fune->of_exttage);r_to=(fune->to_exttage);r_id=false;}letof_constrc=of_extval_constrcletto_constrc=to_extval_constrcletconstr=repr_extval_constrletof_identc=of_extval_identcletto_identc=to_extval_identcletident=repr_extval_identletof_patternc=of_extval_patterncletto_patternc=to_extval_patterncletpattern=repr_extval_patternletinternal_err=letopenNamesinletcoq_prefix=MPfile(DirPath.make(List.mapId.of_string["Init";"Ltac2"]))inKerName.makecoq_prefix(Label.of_id(Id.of_string"Internal"))(** FIXME: handle backtrace in Ltac2 exceptions *)letof_exnc=matchfstcwith|LtacError(kn,c)->ValOpn(kn,c)|_->ValOpn(internal_err,[|of_extval_exnc|])letto_exnc=matchcwith|ValOpn(kn,c)->ifNames.KerName.equalkninternal_errthento_extval_exnc.(0)else(LtacError(kn,c),Exninfo.null)|_->assertfalseletexn={r_of=of_exn;r_to=to_exn;r_id=false;}letof_optionf=function|None->ValInt0|Somec->ValBlk(0,[|fc|])letto_optionf=function|ValInt0->None|ValBlk(0,[|c|])->Some(fc)|_->assertfalseletoptionr={r_of=(funl->of_optionr.r_ofl);r_to=(funl->to_optionr.r_tol);r_id=false;}letof_ppc=of_extval_ppcletto_ppc=to_extval_ppcletpp=repr_extval_ppletof_tuplecl=ValBlk(0,cl)letto_tuple=function|ValBlk(0,cl)->cl|_->assertfalseletof_pairfg(x,y)=ValBlk(0,[|fx;gy|])letto_pairfg=function|ValBlk(0,[|x;y|])->(fx,gy)|_->assertfalseletpairr0r1={r_of=(funp->of_pairr0.r_ofr1.r_ofp);r_to=(funp->to_pairr0.r_tor1.r_top);r_id=false;}letof_arrayfvl=ValBlk(0,Array.mapfvl)letto_arrayf=function|ValBlk(0,vl)->Array.mapfvl|_->assertfalseletarrayr={r_of=(funl->of_arrayr.r_ofl);r_to=(funl->to_arrayr.r_tol);r_id=false;}letof_block(n,args)=ValBlk(n,args)letto_block=function|ValBlk(n,args)->(n,args)|_->assertfalseletblock={r_of=of_block;r_to=to_block;r_id=false;}letof_open(kn,args)=ValOpn(kn,args)letto_open=function|ValOpn(kn,args)->(kn,args)|_->assertfalseletopen_={r_of=of_open;r_to=to_open;r_id=false;}letof_uint63n=ValUint63nletto_uint63=function|ValUint63n->n|_->assertfalseletuint63={r_of=of_uint63;r_to=to_uint63;r_id=false;}letof_floatf=ValFloatfletto_float=function|ValFloatf->f|_->assertfalseletfloat={r_of=of_float;r_to=to_float;r_id=false;}letof_constantc=of_extval_constantcletto_constantc=to_extval_constantcletconstant=repr_extval_constantletof_reference=letopenGlobRefinfunction|VarRefid->ValBlk(0,[|of_identid|])|ConstRefcst->ValBlk(1,[|of_constantcst|])|IndRefind->ValBlk(2,[|of_extval_inductiveind|])|ConstructRefcstr->ValBlk(3,[|of_extval_constructorcstr|])letto_reference=letopenGlobRefinfunction|ValBlk(0,[|id|])->VarRef(to_identid)|ValBlk(1,[|cst|])->ConstRef(to_constantcst)|ValBlk(2,[|ind|])->IndRef(to_extval_inductiveind)|ValBlk(3,[|cstr|])->ConstructRef(to_extval_constructorcstr)|_->assertfalseletreference={r_of=of_reference;r_to=to_reference;r_id=false;}type('a,'b)fun1=closureletfun1(r0:'arepr)(r1:'brepr):('a,'b)fun1repr=closureletto_fun1r0r1f=to_closurefletrecapply:typea.aarity->a->valexprlist->valexprProofview.tactic=funarityfargs->matchargs,aritywith|[],arity->Proofview.tclUNIT(ValCls(MLTactic(arity,f)))(* A few hardcoded cases for efficiency *)|[a0],OneAty->fa0|[a0;a1],AddAtyOneAty->fa0a1|[a0;a1;a2],AddAty(AddAtyOneAty)->fa0a1a2|[a0;a1;a2;a3],AddAty(AddAty(AddAtyOneAty))->fa0a1a2a3(* Generic cases *)|a::args,OneAty->fa>>=funf->letMLTactic(arity,f)=to_closurefinapplyarityfargs|a::args,AddAtyarity->applyarity(fa)argsletapply(MLTactic(arity,f))args=applyarityfargstypen_closure=|NClosure:'aarity*(valexprlist->'a)->n_closureletrecabstractnf=ifInt.equaln1thenNClosure(OneAty,funaccuv->f(List.rev(v::accu)))elseletNClosure(arity,fe)=abstract(n-1)finNClosure(AddAtyarity,funaccuv->fe(v::accu))letabstractnf=let()=assert(n>0)inletNClosure(arity,f)=abstractnfinMLTactic(arity,f[])letapp_fun1clsr0r1x=applycls[r0.r_ofx]>>=funv->Proofview.tclUNIT(r1.r_tov)