123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125(************************************************************************)(* * 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) *)(************************************************************************)openUtilopenNamesopenProofview.Notationstype('a,_)arity0=|OneAty:('a,'a->'aProofview.tactic)arity0|AddAty:('a,'b)arity0->('a,'a->'b)arity0typetag=inttypevalexpr=|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 *)andclosure=MLTactic:(valexpr,'v)arity0*Tac2expr.frameoption*'v->closureletarity_one=OneAtyletarity_suca=AddAtyatype'aarity=(valexpr,'a)arity0letmk_closurearityf=MLTactic(arity,None,f)letmk_closure_valarityf=ValCls(mk_closurearityf)moduleValexpr=structtypet=valexprletis_int=function|ValInt_->true|ValBlk_|ValStr_|ValCls_|ValOpn_|ValExt_->falselettagv=matchvwith|ValBlk(n,_)->n|ValInt_|ValStr_|ValCls_|ValOpn_|ValExt_->CErrors.anomaly(Pp.str"Unexpected value shape")letfieldvn=matchvwith|ValBlk(_,v)->v.(n)|ValInt_|ValStr_|ValCls_|ValOpn_|ValExt_->CErrors.anomaly(Pp.str"Unexpected value shape")letset_fieldvnw=matchvwith|ValBlk(_,v)->v.(n)<-w|ValInt_|ValStr_|ValCls_|ValOpn_|ValExt_->CErrors.anomaly(Pp.str"Unexpected value shape")letmake_blocktagv=ValBlk(tag,v)letmake_intn=ValIntnendletto_closure=function|ValClscls->cls|ValExt_|ValInt_|ValBlk_|ValStr_|ValOpn_->assertfalseletwrapfrtac=matchfrwith|None->tac|Somefr->Tac2bt.with_framefrtacletrecapply:typea.aarity->_->a->valexprlist->valexprProofview.tactic=funarityfrfargs->matchargs,aritywith|[],arity->Proofview.tclUNIT(ValCls(MLTactic(arity,fr,f)))(* A few hardcoded cases for efficiency *)|[a0],OneAty->wrapfr(fa0)|[a0;a1],AddAtyOneAty->wrapfr(fa0a1)|[a0;a1;a2],AddAty(AddAtyOneAty)->wrapfr(fa0a1a2)|[a0;a1;a2;a3],AddAty(AddAty(AddAtyOneAty))->wrapfr(fa0a1a2a3)(* Generic cases *)|a::args,OneAty->wrapfr(fa)>>=funf->letMLTactic(arity,fr,f)=to_closurefinapplyarityfrfargs|a::args,AddAtyarity->applyarityfr(fa)argsletapply(MLTactic(arity,wrap,f))args=applyaritywrapfargsletapply_valvargs=apply(to_closurev)argstypen_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=matchnwith|1->MLTactic(OneAty,None,funa->f[a])|2->MLTactic(AddAtyOneAty,None,funab->f[a;b])|3->MLTactic(AddAty(AddAtyOneAty),None,funabc->f[a;b;c])|4->MLTactic(AddAty(AddAty(AddAtyOneAty)),None,funabcd->f[a;b;c;d])|_->let()=assert(n>0)inletNClosure(arity,f)=abstractnfinMLTactic(arity,None,f[])letannotate_closurefr(MLTactic(arity,fr0,f))=assert(Option.is_emptyfr0);MLTactic(arity,Somefr,f)