123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742(************************************************************************)(* * 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) *)(************************************************************************)(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *)openLtac_pluginopenUtilopenNamesopenConstropenContextopenVarsopenLocusopenPrinteropenTermopsopenTacinterpopenSsrmatching_pluginopenSsrmatchingopenSsrastopenSsrprintersopenSsrcommonopenTacticalsopenTacmachletssroldreworder=Summary.ref~name:"SSR:oldreworder"falselet()=Goptions.(declare_bool_option{optkey=["SsrOldRewriteGoalsOrder"];optread=(fun_->!ssroldreworder);optdepr=false;optwrite=(funb->ssroldreworder:=b)})(** The "simpl" tactic *)(* We must avoid zeta-converting any "let"s created by the "in" tactical. *)lettacred_simplenv=letsimpl_expr=Genredexpr.(Simpl(Redops.make_red_flag[FBeta;FMatch;FZeta;FDeltaBut[]],None))inletesimpl,_=Redexpr.reduction_of_red_exprenvsimpl_exprinletesimplesigmac=let(_,t)=esimplesigmacintinletsimplenvsigmac=(esimplenvsigmac)insimplletsafe_simpltacn=ifn=~-1thenProofview.Goal.enterbeginfungl->letenv=Proofview.Goal.envglinletsigma=Proofview.Goal.sigmaglinletconcl=Proofview.Goal.conclglinletcl=red_safe(tacred_simplenv)envsigmaconclinconvert_concl_no_checkclendelsessr_n_tac"simpl"nletsimpltac=function|Simpln->safe_simpltacn|Cutn->Tacticals.New.tclTRY(donetacn)|SimplCut(n,m)->Tacticals.New.tclTHEN(safe_simpltacm)(Tacticals.New.tclTRY(donetacn))|Nop->Tacticals.New.tclIDTACletsimpltacs=Proofview.Goal.enter(fun_->simpltacs)(** The "congr" tactic *)letinterp_congrarg_atistglnrftym=debug_ssr(fun()->Pp.(str"===interp_congrarg_at==="));letcongrn,_=mkSsrRRef"nary_congruence"inletargs1=mkRnatn::mkRHolesn@[ty]inletargs2=mkRHoles(3*n)inletrecloopi=ifi+n>mthenNoneelsetryletrt=mkRAppcongrn(args1@mkRApprf(mkRHolesi)::args2)indebug_ssr(fun()->Pp.(str"rt="++Printer.pr_glob_constr_env(pf_envgl)(projectgl)rt));Some(interp_refineistglrt)with_->loop(i+1)inloop0letpattern_id=mk_internal_id"pattern value"letcongrtac((n,t),ty)istgl=debug_ssr(fun()->(Pp.str"===congr==="));debug_ssr(fun()->Pp.(str"concl="++Printer.pr_econstr_env(pf_envgl)(projectgl)(Tacmach.pf_conclgl)));letsigma,_asit=interp_term(pf_envgl)(projectgl)isttinletgl=pf_merge_uc_ofsigmaglinlet_,f,_,_ucst=pf_abs_evarsglitinletist'={istwithlfun=Id.Map.addpattern_id(Tacinterp.Value.of_constrf)Id.Map.empty}inletrf=mkRltacVarpattern_idinletm=pf_nbargs(pf_envgl)(projectgl)finlet_,cf=ifn>0thenmatchinterp_congrarg_atist'glnrftymwith|Somecf->cf|None->errorstrmPp.(str"No "++intn++str"-congruence with "++pr_termt)elseletrecloopi=ifi>mthenerrorstrmPp.(str"No congruence with "++pr_termt)elsematchinterp_congrarg_atist'glirftymwith|Somecf->cf|None->loop(i+1)inloop1inProofview.V82.of_tacticTacticals.New.(tclTHEN(refine_withcf)(tclTRYTactics.reflexivity))glletpf_typechecktgl=letit=sig_itglinletsigma,_=pf_type_ofgltinre_sig[it]sigmaletnewssrcongrtacargist=letopenProofview.NotationsinProofview.Goal.enter_one~__LOC__beginfun_g->(Ssrcommon.tacMK_SSR_CONST"ssr_congr_arrow")end>>=funarr->Proofview.V82.tacticbeginfungl->debug_ssr(fun()->Pp.(str"===newcongr==="));debug_ssr(fun()->Pp.(str"concl="++Printer.pr_econstr_env(pf_envgl)(projectgl)(pf_conclgl)));(* utils *)letfsglt=Reductionops.nf_evar(projectgl)tinlettclMATCH_GOAL(c,gl_c)projt_okt_failgl=matchtrySome(pf_unify_HOgl_c(pf_conclgl)c)withexnwhenCErrors.noncriticalexn->Nonewith|Somegl_c->tclTHEN(Proofview.V82.of_tactic(convert_concl~check:true(fsgl_cc)))(t_ok(projgl_c))gl|None->t_fail()glinletmk_evarglty=letenv,sigma,si=pf_envgl,projectgl,sig_itglinletsigma=Evd.create_evar_defssigmainlet(sigma,x)=Evarutil.new_evarenvsigmatyinx,re_sigsisigmainletssr_congrlr=EConstr.mkApp(arr,lr)inleteq,gl=pf_fresh_globalCoqlib.(lib_ref"core.eq.type")glin(* here the two cases: simple equality or arrow *)letequality,_,eq_args,gl'=pf_saturategl(EConstr.of_constreq)3intclMATCH_GOAL(equality,gl')(fungl'->fsgl'(List.assoc0eq_args))(funty->congrtac(arg,Detyping.detypeDetyping.NowfalseId.Set.empty(pf_envgl)(projectgl)ty)ist)(fun()->letgl',t_lhs=pfe_new_typeglinletgl',t_rhs=pfe_new_typegl'inletlhs,gl'=mk_evargl't_lhsinletrhs,gl'=mk_evargl't_rhsinletarrow=EConstr.mkArrowlhsSorts.Relevant(EConstr.Vars.lift1rhs)intclMATCH_GOAL(arrow,gl')(fungl'->[|fsgl'lhs;fsgl'rhs|])(funlr->leta=ssr_congrlrintclTHENLIST[pf_typechecka;Proofview.V82.of_tactic(Tactics.applya);congrtac(arg,mkRType)ist])(fun__->errorstrmPp.(str"Conclusion is not an equality nor an arrow")))glend(** 7. Rewriting tactics (rewrite, unlock) *)(** Rewrite rules *)typessrwkind=RWredofssrsimpl|RWdef|RWeqtypessrrule=ssrwkind*ssrterm(** Rewrite arguments *)typessrrwarg=(ssrdir*ssrmult)*((ssrdocc*rpatternoption)*ssrrule)letnotimes=0letnomult=1,Onceletmkoccocc=None,occletnoclr=mkoccNoneletmkclrclr=Someclr,Noneletnodocc=mkclr[]letis_rw_cut=functionRWred(Cut_)->true|_->falseletmk_rwarg(d,(n,_asm))((clr,occasdocc),rx)(rt,_asr):ssrrwarg=ifrt<>RWeqthenbeginifrt=RWredNop&¬(m=nomult&&occ=None&&rx=None)&&(clr=None||clr=Some[])thenanomaly"Improper rewrite clear switch";ifd=R2L&&rt<>RWdefthenCErrors.user_err(Pp.str"Right-to-left switch on simplification");ifn<>1&&is_rw_cutrtthenCErrors.user_err(Pp.str"Bad or useless multiplier");ifocc<>None&&rx=None&&rt<>RWdefthenCErrors.user_err(Pp.str"Missing redex for simplification occurrence")end;(d,m),((docc,rx),r)letnorwmult=L2R,nomultletnorwocc=noclr,Noneletsimplintacoccrdxsim=letsimptacm=Proofview.Goal.enterbeginfungl->ifm<>~-1thenbeginifrdx<>NonethenCErrors.user_err(Pp.str"Custom simpl tactic does not support patterns");ifocc<>NonethenCErrors.user_err(Pp.str"Custom simpl tactic does not support occurrence numbers");simpltac(Simplm)endelseletsigma0,concl0,env0=Proofview.Goal.(sigmagl,conclgl,envgl)inletsimpenvc__=EConstr.Unsafe.to_constr(red_safeTacred.simplenvsigma0(EConstr.of_constrc))inconvert_concl_no_check(EConstr.of_constr(eval_patternenv0sigma0(EConstr.to_constr~abort_on_undefined_evars:falsesigma0concl0)rdxoccsimp))endinletopenTacticals.NewinProofview.Goal.enterbeginfun_->matchsimwith|Simplm->simptacm|SimplCut(n,m)->tclTHEN(simptacm)(tclTRY(donetacn))|_->simpltacsimendletrecget_evalrefenvsigmac=matchEConstr.kindsigmacwith|Varid->Tacred.EvalVarRefid|Const(k,_)->Tacred.EvalConstRefk|App(c',_)->get_evalrefenvsigmac'|Cast(c',_,_)->get_evalrefenvsigmac'|Proj(c,_)->Tacred.EvalConstRef(Projection.constantc)|_->errorstrmPp.(str"The term "++pr_econstr_pat(Global.env())sigmac++str" is not unfoldable")(* Strip a pattern generated by a prenex implicit to its constant. *)letstrip_unfold_term_((sigma,t)asp)kt=matchEConstr.kindsigmatwith|App(f,a)whenkt=NoFlag&&Array.for_all(EConstr.isEvarsigma)a&&EConstr.isConstsigmaf->(sigma,f),true|Const_|Var_->p,true|Proj_->p,true|_->p,falseletsame_projsigmat1t2=matchEConstr.kindsigmat1,EConstr.kindsigmat2with|Proj(c1,_),Proj(c2,_)->Projection.CanOrd.equalc1c2|_->falseletall_ok__=trueletfake_pmatcher_end()=mkProp,L2R,(Evd.empty,UState.empty,mkProp)letunfoldintacoccrdxt(kt,_)=Proofview.V82.tacticbeginfungl->letfssigmax=Reductionops.nf_evarsigmaxinletsigma0,concl0,env0=projectgl,pf_conclgl,pf_envglinlet(sigma,t),const=strip_unfold_termenv0tktinletbodyenvtc=Tacred.unfoldn[AllOccurrences,get_evalrefenvsigmat]envsigma0cinleteasy=occ=None&&rdx=Noneinletred_flags=ifeasythenCClosure.betaiotazetaelseCClosure.betaiotainletbetaenv=Reductionops.clos_norm_flagsred_flagsenvsigma0inletunfold,conclude=matchrdxwith|Some(_,(In_T_|In_X_In_T_))|None->letise=Evd.create_evar_defssigmainletise,u=mk_tpatternenv0sigma0(ise,EConstr.Unsafe.to_constrt)all_okL2R(EConstr.Unsafe.to_constrt)inletfind_T,end_T=mk_tpattern_matcher~raise_NoMatch:truesigma0occ(ise,[u])in(funenvc_h->tryfind_Tenvch~k:(funenvc__->EConstr.Unsafe.to_constr(bodyenvt(EConstr.of_constrc)))withNoMatchwheneasy->c|NoMatch|NoProgress->errorstrmPp.(str"No occurrence of "++pr_econstr_patenvsigma0t++spc()++str"in "++Printer.pr_constr_envenvsigmac)),(fun()->tryend_T()with|NoMatchwheneasy->fake_pmatcher_end()|NoMatch->anomaly"unfoldintac")|_->(funenv(casorig_c)_h->ifconstthenletrecauxc=matchEConstr.kindsigma0cwith|Const_whenEConstr.eq_constrsigma0ct->bodyenvtt|App(f,a)whenEConstr.eq_constrsigma0ft->EConstr.mkApp(bodyenvff,a)|Proj_whensame_projsigma0ct->bodyenvtc|_->letc=Reductionops.whd_betaiotazetaenvsigma0cinmatchEConstr.kindsigma0cwith|Const_whenEConstr.eq_constrsigma0ct->bodyenvtt|App(f,a)whenEConstr.eq_constrsigma0ft->EConstr.mkApp(bodyenvff,a)|Proj_whensame_projsigma0ct->bodyenvtc|Constf->aux(bodyenvcc)|App(f,a)->aux(EConstr.mkApp(bodyenvff,a))|_->errorstrmPp.(str"The term "++pr_constr_envenvsigmaorig_c++str" contains no "++pr_econstr_envenvsigmat++str" even after unfolding")inEConstr.Unsafe.to_constr@@aux(EConstr.of_constrc)elsetryEConstr.Unsafe.to_constr@@bodyenvt(fs(unify_HOenvsigma(EConstr.of_constrc)t)t)with_->errorstrmPp.(str"The term "++pr_constr_envenvsigmac++spc()++str"does not unify with "++pr_econstr_patenvsigmat)),fake_pmatcher_endinletconcl=letconcl0=EConstr.Unsafe.to_constrconcl0intrybetaenv0(EConstr.of_constr(eval_patternenv0sigma0concl0rdxoccunfold))withOption.IsNone->errorstrmPp.(str"Failed to unfold "++pr_econstr_patenv0sigmat)inlet_=conclude()inProofview.V82.of_tactic(convert_concl~check:trueconcl)glendletfoldtacoccrdxft=Proofview.V82.tacticbeginfungl->letsigma0,concl0,env0=projectgl,pf_conclgl,pf_envglinletsigma,t=ftinlett=EConstr.to_constr~abort_on_undefined_evars:falsesigmatinletfold,conclude=matchrdxwith|Some(_,(In_T_|In_X_In_T_))|None->letise=Evd.create_evar_defssigmainletut=EConstr.Unsafe.to_constr(red_product_skip_idenv0sigma(EConstr.of_constrt))inletise,ut=mk_tpatternenv0sigma0(ise,t)all_okL2Rutinletfind_T,end_T=mk_tpattern_matcher~raise_NoMatch:truesigma0occ(ise,[ut])in(funenvc_h->tryfind_Tenvch~k:(funenvt__->t)withNoMatch->c),(fun()->tryend_T()withNoMatch->fake_pmatcher_end())|_->(funenvc_h->tryletsigma=unify_HOenvsigma(EConstr.of_constrc)(EConstr.of_constrt)inEConstr.to_constr~abort_on_undefined_evars:falsesigma(EConstr.of_constrt)with_->errorstrmPp.(str"fold pattern "++pr_constr_patenvsigmat++spc()++str"does not match redex "++pr_constr_patenvsigmac)),fake_pmatcher_endinletconcl0=EConstr.Unsafe.to_constrconcl0inletconcl=eval_patternenv0sigma0concl0rdxoccfoldinlet_=conclude()inProofview.V82.of_tactic(convert_concl~check:true(EConstr.of_constrconcl))glendletconverse_dir=functionL2R->R2L|R2L->L2Rletrw_progressrhslhsise=not(EConstr.eq_constriselhs(Evarutil.nf_evariserhs))(* Coq has a more general form of "equation" (any type with a single *)(* constructor with no arguments with_rect_r elimination lemmas). *)(* However there is no clear way of determining the LHS and RHS of *)(* such a generic Leibniz equation -- short of inspecting the type *)(* of the elimination lemmas. *)letrecstrip_prod_assumc=matchConstr.kindcwith|Prod(_,_,c')->strip_prod_assumc'|LetIn(_,v,_,c')->strip_prod_assum(subst1vc)|Cast(c',_,_)->strip_prod_assumc'|_->cletrule_id=mk_internal_id"rewrite rule"exceptionPRtype_errorof(Environ.env*Evd.evar_map*Pretype_errors.pretype_error)optionletid_map_redex_sigma~before:_~after=sigma,afterletpirrel_rewrite?(under=false)?(map_redex=id_map_redex)predrdxrdx_tynew_rdxdir(sigma,c)c_ty=Proofview.V82.tacticbeginfungl->(* ppdebug(lazy(str"sigma@pirrel_rewrite=" ++ pr_evar_map None sigma)); *)letenv=pf_envglinletbeta=Reductionops.clos_norm_flagsCClosure.betaenvsigmainletsigma,new_rdx=map_redexenvsigma~before:rdx~after:new_rdxinletsigma,p=(* The resulting goal *)Evarutil.new_evarenvsigma(beta(EConstr.Vars.subst1new_rdxpred))inletpred=EConstr.mkNamedLambda(make_annotpattern_idSorts.Relevant)rdx_typredinletsigma,elim=letsort=elimination_sort_of_goalglinmatchEquality.eq_elimination_ref(dir=L2R)sortwith|Somer->Evd.fresh_globalenvsigmar|None->let((kn,i)asind,_),unfolded_c_ty=Tacred.reduce_to_quantified_indenvsigmac_tyinletsort=elimination_sort_of_goalglinletsigma,elim=Evd.fresh_globalenvsigma(Indrec.lookup_eliminatorenvindsort)inifdir=R2Lthensigma,elimelseletelim,_=EConstr.destConstsigmaeliminletmp,l=Constant.repr2(Constant.make1(Constant.canonicalelim))inletl'=Label.of_id(Nameops.add_suffix(Label.to_idl)"_r")inletc1'=Global.constant_of_delta_kn(Constant.canonical(Constant.make2mpl'))insigma,EConstr.of_constr(mkConstc1')inletproof=EConstr.mkApp(elim,[|rdx_ty;new_rdx;pred;p;rdx;c|])in(* We check the proof is well typed *)letsigma,proof_ty=tryTyping.type_ofenvsigmaproofwith|Pretype_errors.PretypeError(env,sigma,te)->raise(PRtype_error(Some(env,sigma,te)))|ewhenCErrors.noncriticale->raise(PRtype_errorNone)indebug_ssr(fun()->Pp.(str"pirrel_rewrite: proof term: "++pr_econstr_envenvsigmaproof));debug_ssr(fun()->Pp.(str"pirrel_rewrite of type: "++pr_econstr_envenvsigmaproof_ty));tryProofview.V82.of_tactic(refine_with~first_goes_last:(not!ssroldreworder||under)~with_evars:under(sigma,proof))glwithewhenCErrors.noncriticale->(* we generate a msg like: "Unable to find an instance for the variable" *)lethd_ty,miss=matchEConstr.kindsigmacwith|App(hd,args)->lethd_ty=Retyping.get_type_ofenvsigmahdinletnames=letrecauxenvt=function0->[]|n->lett=Reductionops.whd_allenvsigmatinletopenEConstrinmatchkind_of_typesigmatwith|ProdType(name,ty,t)->name.binder_name::aux(EConstr.push_rel(Context.Rel.Declaration.LocalAssum(name,ty))env)t(n-1)|_->(* In the case the head is an HO constant it may accept more arguments *)CList.initn(fun_->Names.Name.Anonymous)inauxenvhd_ty(Array.lengthargs)inhd_ty,Util.List.map_filter(fun(t,name)->letevs=Evar.Set.elements(Evarutil.undefined_evars_of_termsigmat)inletopen_evs=List.filter(funk->Sorts.InProp<>Retyping.get_sort_family_ofenvsigma(Evd.evar_concl(Evd.findsigmak)))evsinifopen_evs<>[]thenSomenameelseNone)(List.combine(Array.to_listargs)names)|_->anomaly"rewrite rule not an application"inerrorstrmPp.(Himsg.explain_refiner_errorenvsigma(Logic.UnresolvedBindingsmiss)++(Pp.fnl()++str"Rule's type:"++spc()++pr_econstr_envenvsigmahd_ty))endletpf_merge_uc_ofssigma=Evd.merge_universe_contextsigma(Evd.evar_universe_contexts)letrwcltac?under?map_redexclrdxdirsr=letopenProofview.NotationsinProofview.Goal.enterbeginfungl->letenv=Proofview.Goal.envglinletsigma0=Proofview.Goal.sigmaglinletsr=letsigma,r=srinletsigma=resolve_typeclasses~where:r~fail:falseenvsigmainsigma,rinletn,r_n,_,ucst=abs_evarsenvsigma0srinletr_n'=abs_ctermenvsigma0nr_ninletr'=EConstr.Vars.subst_varpattern_idr_n'inletsigma0=Evd.set_universe_contextsigma0ucstinletrdxt=Retyping.get_type_ofenv(fstsr)rdxin(* ppdebug(lazy(str"sigma@rwcltac=" ++ pr_evar_map None (fst sr))); *)debug_ssr(fun()->Pp.(str"r@rwcltac="++pr_econstr_envenvsigma0(sndsr)));letcvtac,rwtac,sigma0=ifEConstr.Vars.closed0sigma0r'thenletsigma,c,c_eq=fstsr,sndsr,Coqlib.(lib_ref"core.eq.type")inletsigma,c_ty=Typing.type_ofenvsigmacindebug_ssr(fun()->Pp.(str"c_ty@rwcltac="++pr_econstr_envenvsigmac_ty));letopenEConstrinmatchkind_of_typesigma(Reductionops.whd_allenvsigmac_ty)with|AtomicType(e,a)whenSsrcommon.is_ind_refsigmaec_eq->letnew_rdx=ifdir=L2Rthena.(2)elsea.(1)inpirrel_rewrite?under?map_redexclrdxrdxtnew_rdxdir(sigma,c)c_ty,Tacticals.New.tclIDTAC,sigma0|_->letcl'=EConstr.mkApp(EConstr.mkNamedLambda(make_annotpattern_idSorts.Relevant)rdxtcl,[|rdx|])inletsigma,_=Typing.type_ofenvsigmacl'inletsigma0=pf_merge_uc_ofsigmasigma0inconvert_concl~check:truecl',rewritetac?underdirr',sigma0elseletdc,r2=EConstr.decompose_lam_n_assumsigma0nr'inletr3,_,r3t=tryEConstr.destCastsigma0r2with_->errorstrmPp.(str"no cast from "++pr_econstr_patenvsigma0(sndsr)++str" to "++pr_econstr_envenvsigma0r2)inletcl'=EConstr.mkNamedProd(make_annotrule_idSorts.Relevant)(EConstr.it_mkProd_or_LetInr3tdc)(EConstr.Vars.lift1cl)inletcl''=EConstr.mkNamedProd(make_annotpattern_idSorts.Relevant)rdxtcl'inletitacs=[introidpattern_id;introidrule_id]inletcltac=Tactics.clear[pattern_id;rule_id]inletrwtacs=[rewritetac?underdir(EConstr.mkVarrule_id);cltac]inTactics.apply_type~typecheck:truecl''[rdx;EConstr.it_mkLambda_or_LetInr3dc],Tacticals.New.tclTHENLIST(itacs@rwtacs),sigma0inletcvtac'=Proofview.tclORELSEcvtacbeginfunction|(PRtype_errore,_)->leterror=Option.cata(fun(env,sigma,te)->Pp.(fnl()++str"Type error was: "++Himsg.explain_pretype_errorenvsigmate))(Pp.mt())einifoccur_existentialsigma0(Tacmach.New.pf_conclgl)thenTacticals.New.tclZEROMSGPp.(str"Rewriting impacts evars"++error)elseTacticals.New.tclZEROMSGPp.(str"Dependent type error in rewrite of "++pr_econstr_envenvsigma0(EConstr.mkNamedLambda(make_annotpattern_idSorts.Relevant)rdxtcl)++error)|(e,info)->Proofview.tclZERO~infoeendinProofview.Unsafe.tclEVARSsigma0<*>Tacticals.New.tclTHENcvtac'rwtacend[@@@ocaml.warning"-3"]letlz_coq_prod=letprod=lazy(Coqlib.build_prod())infun()->Lazy.forceprodletlz_setoid_relation=letsdir=["Classes";"RelationClasses"]inletlast_srel=refNoneinfunenv->match!last_srelwith|Some(env',srel)whenenv'==env->srel|_->letsrel=trySome(UnivGen.constr_of_monomorphic_global@@Coqlib.find_reference"Class_setoid"("Coq"::sdir)"RewriteRelation"[@ocaml.warning"-3"])with_->Noneinlast_srel:=Some(env,srel);srelletssr_is_setoidenv=matchlz_setoid_relationenvwith|None->fun___->false|Somesrel->funsigmarargs->Rewrite.is_applied_rewrite_relationenvsigma[](EConstr.mkApp(r,args))<>Noneletclosed0_checkenvsigmaclp=ifclosed0clthenerrorstrmPp.(str"No occurrence of redex "++pr_constr_envenvsigmap)letdir_org=functionL2R->1|R2L->2letrwprocess_ruleenvdirrule=letcoq_prod=lz_coq_prod()inletis_setoid=ssr_is_setoidenvinletr_sigma,rules=letrecloopdsigmart0rsred=lett=ifred=1thenTacred.hnf_constrenvsigmat0elseReductionops.whd_betaiotazetaenvsigmat0indebug_ssr(fun()->Pp.(str"rewrule="++pr_econstr_patenvsigmat));matchEConstr.kindsigmatwith|Prod(_,xt,at)->letsigma=Evd.create_evar_defssigmainlet(sigma,x)=Evarutil.new_evarenvsigmaxtinloopdsigmaEConstr.(mkApp(r,[|x|]))(EConstr.Vars.subst1xat)rs0|App(pr,a)whenis_ind_refsigmaprcoq_prod.Coqlib.typ->letsrsigma=matchEConstr.kindsigma(Tacred.hnf_constrenvsigmar)with|App(c,ra)whenis_construct_refsigmaccoq_prod.Coqlib.intro->funi->ra.(i+1),sigma|_->letra=Array.appenda[|r|]infunction1->letsigma,pi1=Evd.fresh_globalenvsigmacoq_prod.Coqlib.proj1inEConstr.mkApp(pi1,ra),sigma|_->letsigma,pi2=Evd.fresh_globalenvsigmacoq_prod.Coqlib.proj2inEConstr.mkApp(pi2,ra),sigmainletsigma,trty=Evd.fresh_globalenvsigmaCoqlib.(lib_ref"core.True.type")inifEConstr.eq_constrsigmaa.(0)trtythenlets,sigma=srsigma2inloop(converse_dird)sigmasa.(1)rs0elselets,sigma=srsigma2inletsigma,rs2=loopdsigmasa.(1)rs0inlets,sigma=srsigma1inloopdsigmasa.(0)rs20|App(r_eq,a)whenHipattern.match_with_equality_typeenvsigmat!=None->let(ind,u)=EConstr.destIndsigmar_eqandrhs=Array.lastainletnp=Inductiveops.inductive_nparamdeclsenvindinletindu=(ind,EConstr.EInstance.kindsigmau)inletind_ct=Inductiveops.type_of_constructorsenvinduinletlhs0=last_argsigma(EConstr.of_constr(strip_prod_assumind_ct.(0)))inletrdesc=matchEConstr.kindsigmalhs0with|Reli->letlhs=a.(np-i)inletlhs,rhs=ifd=L2Rthenlhs,rhselserhs,lhsin(* msgnl (str "RW: " ++ pr_rwdir d ++ str " " ++ pr_constr_pat r ++ str " : "
++ pr_constr_pat lhs ++ str " ~> " ++ pr_constr_pat rhs); *)d,r,lhs,rhs(*
let l_i, r_i = if d = L2R then i, 1 - ndep else 1 - ndep, i in
let lhs = a.(np - l_i) and rhs = a.(np - r_i) in
let a' = Array.copy a in let _ = a'.(np - l_i) <- mkVar pattern_id in
let r' = mkCast (r, DEFAULTcast, mkApp (r_eq, a')) in
(d, r', lhs, rhs)
*)|_->letlhs=EConstr.Vars.substl(array_list_of_tl(Array.suba0np))lhs0inletlhs,rhs=ifd=R2Lthenlhs,rhselserhs,lhsinletd'=ifArray.lengtha=1thendelseconverse_dirdind',r,lhs,rhsinsigma,rdesc::rs|App(s_eq,a)whenis_setoidsigmas_eqa->letnp=Array.lengthaandi=3-dir_orgdinletlhs=a.(np-i)andrhs=a.(np+i-3)inleta'=Array.copyainlet_=a'.(np-i)<-EConstr.mkVarpattern_idinletr'=EConstr.mkCast(r,DEFAULTcast,EConstr.mkApp(s_eq,a'))insigma,(d,r',lhs,rhs)::rs|_->ifred=0thenloopdsigmartrs1elseerrorstrmPp.(str"not a rewritable relation: "++pr_econstr_patenvsigmat++spc()++str"in rule "++pr_econstr_patenvsigma(sndrule))inletsigma,r=ruleinlett=Retyping.get_type_ofenvsigmarinloopdirsigmart[]0inr_sigma,rulesletrwrxtac?under?map_redexoccrdx_patdirrule=Proofview.Goal.enterbeginfungl->letenv=Proofview.Goal.envglinletsigma0=Proofview.Goal.sigmaglinletr_sigma,rules=rwprocess_ruleenvdirruleinletfind_rulerdx=letrecrwtac=function|[]->errorstrmPp.(str"pattern "++pr_econstr_patenvsigma0rdx++str" does not match "++pr_dir_sidedir++str" of "++pr_econstr_patenvsigma0(sndrule))|(d,r,lhs,rhs)::rs->tryletise=unify_HOenv(Evd.create_evar_defsr_sigma)lhsrdxinifnot(rw_progressrhsrdxise)thenraiseNoMatchelsed,(ise,Evd.evar_universe_contextise,Reductionops.nf_evariser)with_->rwtacrsinrwtacrulesinletenv0=envinletconcl0=Proofview.Goal.conclglinletfind_R,conclude=matchrdx_patwith|Some(_,(In_T_|In_X_In_T_))|None->letupats_origin=dir,EConstr.Unsafe.to_constr(sndrule)inletrpatenvsigma0(sigma,pats)(d,r,lhs,rhs)=letsigma,pat=letrw_progressrhstevd=rw_progressrhs(EConstr.of_constrt)evdinmk_tpatternenvsigma0(sigma,EConstr.to_constr~abort_on_undefined_evars:falsesigmar)(rw_progressrhs)d(EConstr.to_constr~abort_on_undefined_evars:falsesigmalhs)insigma,pats@[pat]inletrpats=List.fold_left(rpatenv0sigma0)(r_sigma,[])rulesinletfind_R,end_R=mk_tpattern_matchersigma0occ~upats_originrpatsin(funec_i->find_R~k:(fun___h->mkRelh)eci),funcl->letrdx,d,r=end_R()inclosed0_checkenv0sigma0clrdx;(d,r),rdx|Some(_,(Te|X_In_T(_,e)|E_As_X_In_T(e,_,_)|E_In_X_In_T(e,_,_)))->letr=refNonein(funenvc_h->do_oncer(fun()->find_rule(EConstr.of_constrc),c);mkRelh),(funconcl->closed0_checkenv0sigma0concle;let(d,(ev,ctx,c)),x=assert_donerin(d,(ev,ctx,EConstr.to_constr~abort_on_undefined_evars:falseevc)),x)inletconcl0=EConstr.to_constr~abort_on_undefined_evars:falsesigma0concl0inletconcl=eval_patternenv0sigma0concl0rdx_patoccfind_Rinlet(d,r),rdx=concludeconclinletr=Evd.merge_universe_context(pi1r)(pi2r),EConstr.of_constr(pi3r)inrwcltac?under?map_redex(EConstr.of_constrconcl)(EConstr.of_constrrdx)drendletssrinstancesofruleistdirarg=Proofview.Goal.enterbeginfungl->letenv0=Proofview.Goal.envglinletsigma0=Proofview.Goal.sigmaglinletconcl0=Proofview.Goal.conclglinletrule=interp_termenv0sigma0istarginletr_sigma,rules=rwprocess_ruleenv0dirruleinletfind,conclude=letupats_origin=dir,EConstr.Unsafe.to_constr(sndrule)inletrpatenvsigma0(sigma,pats)(d,r,lhs,rhs)=letsigma,pat=letrw_progressrhstevd=rw_progressrhs(EConstr.of_constrt)evdinmk_tpatternenvsigma0(sigma,EConstr.to_constr~abort_on_undefined_evars:falsesigmar)(rw_progressrhs)d(EConstr.to_constr~abort_on_undefined_evars:falsesigmalhs)insigma,pats@[pat]inletrpats=List.fold_left(rpatenv0sigma0)(r_sigma,[])rulesinmk_tpattern_matcher~all_instances:true~raise_NoMatch:truesigma0None~upats_originrpatsinletprintenvpc_=Feedback.msg_infoPp.(hov1(str"instance:"++spc()++pr_constr_envenvr_sigmap++spc()++str"matches:"++spc()++pr_constr_envenvr_sigmac));cinFeedback.msg_infoPp.(str"BEGIN INSTANCES");trywhiletruedoignore(findenv0(EConstr.to_constr~abort_on_undefined_evars:falsesigma0concl0)1~k:print)done;raiseNoMatchwithNoMatch->Feedback.msg_infoPp.(str"END INSTANCES");Tacticals.New.tclIDTACendletipat_rewriteoccdirc=Proofview.Goal.enterbeginfungl->rwrxtacoccNonedir(Proofview.Goal.sigmagl,c)endletrwargtac?under?map_redexist((dir,mult),(((oclr,occ),grx),(kind,gt)))=letopenProofview.NotationsinProofview.Goal.enterbeginfungl->letenv=Proofview.Goal.envglinletsigma=Proofview.Goal.sigmaglinletfail=reffalseinletinterp_rpatternenvsigmagc=tryinterp_rpatternenvsigmagcwith_whensndmult=May->fail:=true;sigma,TmkPropinletinterpenvsigmagc=tryinterp_termenvsigmaistgcwith_whensndmult=May->fail:=true;(sigma,EConstr.mkProp)inletrwtac=Proofview.Goal.enterbeginfungl->letenv=Proofview.Goal.envglinletsigma=Proofview.Goal.sigmaglinletrx=Option.map(interp_rpatternenvsigma)grxinletsigma=matchrxwith|None->sigma|Some(s,_)->pf_merge_uc_ofssigmainlett=interpenvsigmagtinletsigma=pf_merge_uc_of(fstt)sigmainProofview.Unsafe.tclEVARSsigma<*>(matchkindwith|RWredsim->simplintacoccrxsim|RWdef->ifdir=R2Lthenfoldtacoccrxtelseunfoldintacoccrxtgt|RWeq->rwrxtac?under?map_redexoccrxdirt)endinletctac=cleartac(interp_clrsigma(oclr,(fstgt,snd(interpenvsigmagt))))inif!failthenctacelseTacticals.New.tclTHEN(tclMULTmultrwtac)ctacend(** Rewrite argument sequence *)(* type ssrrwargs = ssrrwarg list *)(** The "rewrite" tactic *)letssrrewritetac?under?map_redexistrwargs=Proofview.Goal.enterbeginfun_->Tacticals.New.tclTHENLIST(List.map(rwargtac?under?map_redexist)rwargs)end(** The "unlock" tactic *)letunfoldtacocckotkt=Proofview.Goal.enterbeginfungl->letenv=Proofview.Goal.envglinletsigma=Proofview.Goal.sigmaglinletconcl=Proofview.Goal.conclglinletconcl=Evarutil.nf_evarsigmaconclinletcl,c=fill_occ_termenvsigmaconclocc(fst(strip_unfold_termenvtkt))inletcl'=EConstr.Vars.subst1(Tacred.unfoldn[OnlyOccurrences[1],get_evalrefenvsigmac]envsigmac)clinletf=ifko=NonethenCClosure.betaiotazetaelseCClosure.betaiotainconvert_concl~check:true(Reductionops.clos_norm_flagsfenvsigmacl')endletunlocktacistargs=letopenProofview.Notationsinletutac(occ,gt)=Proofview.Goal.enterbeginfungl->letenv=Proofview.Goal.envglinletsigma=Proofview.Goal.sigmaglinunfoldtacoccocc(interp_termenvsigmaistgt)(fstgt)endinSsrcommon.tacMK_SSR_CONST"locked">>=funlocked->Ssrcommon.tacMK_SSR_CONST"master_key">>=funkey->letktacs=[(Proofview.tclEVARMAP>>=funsigma->unfoldtacNoneNone(sigma,locked)InParens);Ssrelim.casetackey(fun?seed:_k->k)]inTacticals.New.tclTHENLIST(List.maputacargs@ktacs)