123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300(************************************************************************)(* * 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) *)(************************************************************************)openUtilopenTacexpropenMod_substopenGenargopenStdargopenTacargopenTactypesopenTacticsopenGlobnamesopenGenredexpropenPatternops(** Substitution of tactics at module closing time *)(** For generic arguments, we declare and store substitutions
in a table *)letsubst_quantified_hypothesis_x=xletsubst_declared_or_quantified_hypothesis_x=xletsubst_glob_constr_and_exprsubst(c,e)=(Detyping.subst_glob_constr(Global.env())substc,e)letsubst_glob_constr=subst_glob_constr_and_expr(* shortening *)letsubst_bindingsubst=CAst.map(fun(b,c)->subst_quantified_hypothesissubstb,subst_glob_constrsubstc)letsubst_bindingssubst=function|NoBindings->NoBindings|ImplicitBindingsl->ImplicitBindings(List.map(subst_glob_constrsubst)l)|ExplicitBindingsl->ExplicitBindings(List.map(subst_bindingsubst)l)letsubst_glob_with_bindingssubst(c,bl)=(subst_glob_constrsubstc,subst_bindingssubstbl)letsubst_glob_with_bindings_argsubst(clear,c)=(clear,subst_glob_with_bindingssubstc)letrecsubst_intro_patternsubst=CAst.map(function|IntroActionp->IntroAction(subst_intro_pattern_actionsubstp)|IntroNaming_|IntroForthcoming_asx->x)andsubst_intro_pattern_actionsubst=letopenCAstinfunction|IntroApplyOn({loc;v=t},pat)->IntroApplyOn(make?loc@@subst_glob_constrsubstt,subst_intro_patternsubstpat)|IntroOrAndPatternl->IntroOrAndPattern(subst_intro_or_and_patternsubstl)|IntroInjectionl->IntroInjection(List.map(subst_intro_patternsubst)l)|IntroWildcard|IntroRewrite_asx->xandsubst_intro_or_and_patternsubst=function|IntroAndPatternl->IntroAndPattern(List.map(subst_intro_patternsubst)l)|IntroOrPatternll->IntroOrPattern(List.map(List.map(subst_intro_patternsubst))ll)letsubst_destruction_argsubst=function|clear,ElimOnConstrc->clear,ElimOnConstr(subst_glob_with_bindingssubstc)|clear,ElimOnAnonHypnasx->x|clear,ElimOnIdentidasx->xletsubst_and_short_namef(c,n)=(* assert (n=None); *)(* since tacdef are strictly globalized *)(fc,None)letsubst_locatedf=Loc.mapfletsubst_referencesubst=Locusops.or_var_map(subst_located(subst_knsubst))(*CSC: subst_global_reference is used "only" for RefArgType, that propagates
to the syntactic non-terminals "global", used in commands such as
Print. It is also used for non-evaluable references. *)letsubst_global_referencesubst=Locusops.or_var_map(subst_located(subst_global_referencesubst))letsubst_evaluablesubst=letsubst_eval_ref=Tacred.subst_evaluable_referencesubstinLocusops.or_var_map(subst_and_short_namesubst_eval_ref)letsubst_constr_with_occurrencessubst(l,c)=(l,subst_glob_constrsubstc)letsubst_glob_constr_or_patternsubst(bvars,c,p)=letenv=Global.env()inletsigma=Evd.from_envenvin(bvars,subst_glob_constrsubstc,subst_patternenvsigmasubstp)letsubst_glob_red_exprsubst=Redops.map_red_expr_gen(subst_glob_constrsubst)(subst_evaluablesubst)(subst_glob_constrsubst)letsubst_raw_may_evalsubst=function|ConstrEval(r,c)->ConstrEval(subst_glob_red_exprsubstr,subst_glob_constrsubstc)|ConstrContext(locid,c)->ConstrContext(locid,subst_glob_constrsubstc)|ConstrTypeOfc->ConstrTypeOf(subst_glob_constrsubstc)|ConstrTermc->ConstrTerm(subst_glob_constrsubstc)letsubst_match_patternsubst=function|Subterm(ido,pc)->Subterm(ido,(subst_glob_constr_or_patternsubstpc))|Termpc->Term(subst_glob_constr_or_patternsubstpc)letrecsubst_match_goal_hypssubst=function|Hyp(locs,mp)::tl->Hyp(locs,subst_match_patternsubstmp)::subst_match_goal_hypssubsttl|Def(locs,mv,mp)::tl->Def(locs,subst_match_patternsubstmv,subst_match_patternsubstmp)::subst_match_goal_hypssubsttl|[]->[]letrecsubst_atomicsubst(t:glob_atomic_tactic_expr)=matchtwith(* Basic tactics *)|TacIntroPattern(ev,l)->TacIntroPattern(ev,List.map(subst_intro_patternsubst)l)|TacApply(a,ev,cb,cl)->TacApply(a,ev,List.map(subst_glob_with_bindings_argsubst)cb,List.map(on_snd(Option.map(subst_intro_patternsubst)))cl)|TacElim(ev,cb,cbo)->TacElim(ev,subst_glob_with_bindings_argsubstcb,Option.map(subst_glob_with_bindingssubst)cbo)|TacCase(ev,cb)->TacCase(ev,subst_glob_with_bindings_argsubstcb)|TacMutualFix(id,n,l)->TacMutualFix(id,n,List.map(fun(id,n,c)->(id,n,subst_glob_constrsubstc))l)|TacMutualCofix(id,l)->TacMutualCofix(id,List.map(fun(id,c)->(id,subst_glob_constrsubstc))l)|TacAssert(ev,b,otac,na,c)->TacAssert(ev,b,Option.map(Option.map(subst_tacticsubst))otac,na,subst_glob_constrsubstc)|TacGeneralizecl->TacGeneralize(List.map(on_fst(subst_constr_with_occurrencessubst))cl)|TacLetTac(ev,id,c,clp,b,eqpat)->TacLetTac(ev,id,subst_glob_constrsubstc,clp,b,eqpat)(* Derived basic tactics *)|TacInductionDestruct(isrec,ev,(l,el))->letl'=List.map(fun(c,ids,cls)->subst_destruction_argsubstc,ids,cls)linletel'=Option.map(subst_glob_with_bindingssubst)elinTacInductionDestruct(isrec,ev,(l',el'))(* Conversion *)|TacReduce(r,cl)->TacReduce(subst_glob_red_exprsubstr,cl)|TacChange(check,op,c,cl)->TacChange(check,Option.map(subst_glob_constrsubst)op,subst_glob_constrsubstc,cl)(* Equality and inversion *)|TacRewrite(ev,l,cl,by)->TacRewrite(ev,List.map(fun(b,m,c)->b,m,subst_glob_with_bindings_argsubstc)l,cl,Option.map(subst_tacticsubst)by)|TacInversion(DepInversion(k,c,l),hyp)->TacInversion(DepInversion(k,Option.map(subst_glob_constrsubst)c,l),hyp)|TacInversion(NonDepInversion_,_)asx->x|TacInversion(InversionUsing(c,cl),hyp)->TacInversion(InversionUsing(subst_glob_constrsubstc,cl),hyp)andsubst_tacticsubst=CAst.map(function|TacAtomt->TacAtom(subst_atomicsubstt)|TacFuntacfun->TacFun(subst_tactic_funsubsttacfun)|TacLetIn(r,l,u)->letl=List.map(fun(n,b)->(n,subst_tacargsubstb))linTacLetIn(r,l,subst_tacticsubstu)|TacMatchGoal(lz,lr,lmr)->TacMatchGoal(lz,lr,subst_match_rulesubstlmr)|TacMatch(lz,c,lmr)->TacMatch(lz,subst_tacticsubstc,subst_match_rulesubstlmr)|TacId_|TacFail_asx->x|TacProgresstac->TacProgress(subst_tacticsubsttac:glob_tactic_expr)|TacAbstract(tac,s)->TacAbstract(subst_tacticsubsttac,s)|TacThen(t1,t2)->TacThen(subst_tacticsubstt1,subst_tacticsubstt2)|TacDispatchtl->TacDispatch(List.map(subst_tacticsubst)tl)|TacExtendTac(tf,t,tl)->TacExtendTac(Array.map(subst_tacticsubst)tf,subst_tacticsubstt,Array.map(subst_tacticsubst)tl)|TacThens(t,tl)->TacThens(subst_tacticsubstt,List.map(subst_tacticsubst)tl)|TacThens3parts(t1,tf,t2,tl)->TacThens3parts(subst_tacticsubstt1,Array.map(subst_tacticsubst)tf,subst_tacticsubstt2,Array.map(subst_tacticsubst)tl)|TacDo(n,tac)->TacDo(n,subst_tacticsubsttac)|TacTimeout(n,tac)->TacTimeout(n,subst_tacticsubsttac)|TacTime(s,tac)->TacTime(s,subst_tacticsubsttac)|TacTrytac->TacTry(subst_tacticsubsttac)|TacRepeattac->TacRepeat(subst_tacticsubsttac)|TacOr(tac1,tac2)->TacOr(subst_tacticsubsttac1,subst_tacticsubsttac2)|TacOncetac->TacOnce(subst_tacticsubsttac)|TacExactlyOncetac->TacExactlyOnce(subst_tacticsubsttac)|TacIfThenCatch(tac,tact,tace)->TacIfThenCatch(subst_tacticsubsttac,subst_tacticsubsttact,subst_tacticsubsttace)|TacOrelse(tac1,tac2)->TacOrelse(subst_tacticsubsttac1,subst_tacticsubsttac2)|TacFirstl->TacFirst(List.map(subst_tacticsubst)l)|TacSolvel->TacSolve(List.map(subst_tacticsubst)l)|TacArga->TacArg(subst_tacargsubsta)|TacSelect(s,tac)->TacSelect(s,subst_tacticsubsttac)(* For extensions *)|TacAlias(s,l)->lets=subst_knsubstsinTacAlias(s,List.map(subst_tacargsubst)l)|TacML(opn,l)->TacML(opn,List.map(subst_tacargsubst)l))andsubst_tactic_funsubst(var,body)=(var,subst_tacticsubstbody)andsubst_tacargsubst=function|Referencer->Reference(subst_referencesubstr)|ConstrMayEvalc->ConstrMayEval(subst_raw_may_evalsubstc)|TacCall{CAst.loc;v=(f,l)}->TacCallCAst.(make?loc(subst_referencesubstf,List.map(subst_tacargsubst)l))|TacFreshId_asx->x|TacPretypec->TacPretype(subst_glob_constrsubstc)|TacNumgoals->TacNumgoals|Tacexpt->Tacexp(subst_tacticsubstt)|TacGeneric(isquot,arg)->TacGeneric(isquot,subst_genargsubstarg)(* Reads the rules of a Match Context or a Match *)andsubst_match_rulesubst=function|(Alltc)::tl->(All(subst_tacticsubsttc))::(subst_match_rulesubsttl)|(Pat(rl,mp,tc))::tl->lethyps=subst_match_goal_hypssubstrlinletpat=subst_match_patternsubstmpinPat(hyps,pat,subst_tacticsubsttc)::(subst_match_rulesubsttl)|[]->[]andsubst_genargsubst(GenArg(Glbwitwit,x))=matchwitwith|ListArgwit->letmapx=letans=subst_genargsubst(in_gen(glbwitwit)x)inout_gen(glbwitwit)ansinin_gen(glbwit(wit_listwit))(List.mapmapx)|OptArgwit->letans=matchxwith|None->in_gen(glbwit(wit_optwit))None|Somex->lets=out_gen(glbwitwit)(subst_genargsubst(in_gen(glbwitwit)x))inin_gen(glbwit(wit_optwit))(Somes)inans|PairArg(wit1,wit2)->letp,q=xinletp=out_gen(glbwitwit1)(subst_genargsubst(in_gen(glbwitwit1)p))inletq=out_gen(glbwitwit2)(subst_genargsubst(in_gen(glbwitwit2)q))inin_gen(glbwit(wit_pairwit1wit2))(p,q)|ExtraArgs->Gensubst.generic_substitutesubst(in_gen(glbwitwit)x)(** Registering *)let()=Gensubst.register_subst0wit_int_or_var(fun_v->v);Gensubst.register_subst0wit_nat_or_var(fun_v->v);Gensubst.register_subst0wit_refsubst_global_reference;Gensubst.register_subst0wit_smart_globalsubst_global_reference;Gensubst.register_subst0wit_pre_ident(fun_v->v);Gensubst.register_subst0wit_ident(fun_v->v);Gensubst.register_subst0wit_hyp(fun_v->v);Gensubst.register_subst0wit_intropatternsubst_intro_pattern[@warning"-3"];Gensubst.register_subst0wit_simple_intropatternsubst_intro_pattern;Gensubst.register_subst0wit_tacticsubst_tactic;Gensubst.register_subst0wit_ltacsubst_tactic;Gensubst.register_subst0wit_constrsubst_glob_constr;Gensubst.register_subst0wit_clause_dft_concl(fun_v->v);Gensubst.register_subst0wit_uconstr(funsubstc->subst_glob_constrsubstc);Gensubst.register_subst0wit_open_constr(funsubstc->subst_glob_constrsubstc);Gensubst.register_subst0Redexpr.wit_red_exprsubst_glob_red_expr;Gensubst.register_subst0wit_quant_hypsubst_declared_or_quantified_hypothesis;Gensubst.register_subst0wit_bindingssubst_bindings;Gensubst.register_subst0wit_constr_with_bindingssubst_glob_with_bindings;Gensubst.register_subst0wit_destruction_argsubst_destruction_arg;()