123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259(************************************************************************)(* * The Rocq Prover / The Rocq 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) *)(************************************************************************)openConstropenEConstropenTacexpropenCErrorsopenUtilopenTactypesopenTacticsopenProofview.Notationsletassert_succeedstac=letopenProofviewinletexceptionSucceededintclORELSE(tclONCEtac<*>tclZEROSucceeded)(function|Succeeded,_->tclUNIT()|exn,info->tclZERO~infoexn)letmytclWithHolestacwith_evarsc=Proofview.Goal.enterbeginfungl->letenv=Proofview.Goal.envglinletsigma=Proofview.Goal.sigmaglinletsigma',c=Tactics.force_destruction_argwith_evarsenvsigmacinTacticals.tclWITHHOLESwith_evars(tacwith_evars(Somec))sigma'end(**********************************************************************)(* replace, discriminate, injection, simplify_eq *)(* dependent rewrite *)letwith_delayed_uconstristctac=letflags=Pretyping.{use_coercions=true;use_typeclasses=NoUseTC;solve_unification_constraints=true;fail_evar=false;expand_evars=true;program_mode=false;poly=PolyFlags.default;undeclared_evars_rr=false;unconstrained_sorts=false;}inletc=Tacinterp.type_uconstr~flagsistcinTacticals.tclDELAYEDWITHHOLESfalsectacletreplace_in_clause_maybe_byistdir_optc1c2cltac=with_delayed_uconstristc1(func1->Equality.replace_in_clause_maybe_bydir_optc1c2cl(Option.map(Tacinterp.tactic_of_valueist)tac))letreplace_termistdir_optccl=with_delayed_uconstristc(func->Equality.replace_termdir_optccl)letelimOnConstrWithHolestacwith_evarsc=Tacticals.tclDELAYEDWITHHOLESwith_evarsc(func->tacwith_evars(Some(None,ElimOnConstrc)))letdiscr_mainc=elimOnConstrWithHolesEquality.discr_tacfalsecletdiscrHypid=Proofview.tclEVARMAP>>=funsigma->discr_main(funenvsigma->(sigma,(EConstr.mkVarid,NoBindings)))letinjection_mainwith_evarsc=elimOnConstrWithHoles(Equality.injClauseNoneNone)with_evarscletinjHypid=Proofview.tclEVARMAP>>=funsigma->injection_mainfalse(funenvsigma->(sigma,(EConstr.mkVarid,NoBindings)))letconstr_flags()=Pretyping.{use_coercions=true;use_typeclasses=UseTC;solve_unification_constraints=Proof.use_unification_heuristics();fail_evar=false;expand_evars=true;program_mode=false;poly=PolyFlags.default;undeclared_evars_rr=false;unconstrained_sorts=false;}letrefine_tacist~simple~with_classesc=letwith_classes=ifwith_classesthenPretyping.UseTCelsePretyping.NoUseTCinProofview.Goal.enterbeginfungl->letconcl=Proofview.Goal.conclglinletenv=Proofview.Goal.envglinletflags={(constr_flags())withPretyping.use_typeclasses=with_classes}inletexpected_type=Pretyping.OfTypeconclinletc=Tacinterp.type_uconstr~flags~expected_typeistcinletupdate=beginfunsigma->cenvsigmaendinletrefine=Refine.refine~typecheck:falseupdateinifsimplethenrefineelserefine<*>Tactics.reduce_after_refine<*>Proofview.shelve_unifiableend(** Term introspection *)letis_evarx=Proofview.tclEVARMAP>>=funsigma->matchEConstr.kindsigmaxwith|Evar_->Proofview.tclUNIT()|_->Tacticals.tclFAIL(Pp.str"Not an evar")lethas_evarx=Proofview.tclEVARMAP>>=funsigma->ifEvarutil.has_undefined_evarssigmaxthenProofview.tclUNIT()elseTacticals.tclFAIL(Pp.str"No evars")letis_varx=Proofview.tclEVARMAP>>=funsigma->matchEConstr.kindsigmaxwith|Var_->Proofview.tclUNIT()|_->Tacticals.tclFAIL(Pp.str"Not a variable or hypothesis")letis_fixx=Proofview.tclEVARMAP>>=funsigma->matchEConstr.kindsigmaxwith|Fix_->Proofview.tclUNIT()|_->Tacticals.tclFAIL(Pp.str"not a fix definition")letis_cofixx=Proofview.tclEVARMAP>>=funsigma->matchEConstr.kindsigmaxwith|CoFix_->Proofview.tclUNIT()|_->Tacticals.tclFAIL(Pp.str"not a cofix definition")letis_indx=Proofview.tclEVARMAP>>=funsigma->matchEConstr.kindsigmaxwith|Ind_->Proofview.tclUNIT()|_->Tacticals.tclFAIL(Pp.str"not an (co)inductive datatype")letis_constructorx=Proofview.tclEVARMAP>>=funsigma->matchEConstr.kindsigmaxwith|Construct_->Proofview.tclUNIT()|_->Tacticals.tclFAIL(Pp.str"not a constructor")letis_projx=Proofview.tclEVARMAP>>=funsigma->matchEConstr.kindsigmaxwith|Proj_->Proofview.tclUNIT()|_->Tacticals.tclFAIL(Pp.str"not a primitive projection")letis_constx=Proofview.tclEVARMAP>>=funsigma->matchEConstr.kindsigmaxwith|Const_->Proofview.tclUNIT()|_->Tacticals.tclFAIL(Pp.str"not a constant")letunshelveistt=Proofview.with_shelf(Tacinterp.tactic_of_valueistt)>>=fun(gls,())->letgls=List.mapProofview.with_empty_stateglsinProofview.Unsafe.tclGETGOALS>>=funogls->Proofview.Unsafe.tclSETGOALS(gls@ogls)(** tactic analogous to "OPTIMIZE HEAP" *)lettclOPTIMIZE_HEAP=Proofview.tclLIFT(Proofview.NonLogical.make(fun()->Gc.compact()))letonSomeWithHolestac=function|None->tacNone|Somec->Tacticals.tclDELAYEDWITHHOLESfalsec(func->tac(Somec))letdecomposelc=Proofview.Goal.enterbeginfungl->letsigma=Proofview.Goal.sigmaglinletto_indc=ifisIndsigmacthenfst(destIndsigmac)elseuser_errPp.(str"not an inductive type")inletl=List.mapto_indlinElim.h_decomposelcendletexactist(c:Ltac_pretype.closed_glob_constr)=Proofview.Goal.enterbeginfungl->letenv=Proofview.Goal.envglinletsigma=Proofview.Goal.sigmaglinletconcl=Proofview.Goal.conclglinletexpected_type=Pretyping.OfTypeconclinletsigma,c=Tacinterp.type_uconstr~expected_typeistcenvsigmainProofview.tclTHEN(Proofview.Unsafe.tclEVARSsigma)(Tactics.exact_no_checkc)end(** ProofGeneral specific command *)(* Execute tac, show the names of new hypothesis names created by tac
in the "as" format and then forget everything. From the logical
point of view [infoH tac] is therefore equivalent to idtac,
except that it takes the time and memory of tac and prints "as"
information. The resulting (unchanged) goals are printed *after*
the as-expression, which forces pg to some gymnastic.
TODO: Have something similar (better?) in the xml protocol.
NOTE: some tactics delete hypothesis and reuse names (induction,
destruct), this is not detected by this tactical. *)letinfoH~pstate(tac:raw_tactic_expr):unit=letoldhyps=trysnd@@Declare.Proof.get_goal_contextpstate1withProof.NoSuchGoal_->Global.env()inletoldhyps=List.mapContext.Named.Declaration.get_id@@Environ.named_contextoldhypsinlettac=Tacinterp.interptacinlettac=letopenProofview.Notationsintac<*>Proofview.Unsafe.tclGETGOALS>>=fungls->Proofview.tclEVARMAP>>=funsigma->letmapgl=letgl=Proofview_monad.drop_stateglinlethyps=Evd.evar_filtered_context(Evd.find_undefinedsigmagl)inList.mapContext.Named.Declaration.get_id@@hypsinlethyps=List.mapmapglsinletnewhyps=List.map(funhypl->List.subtractNames.Id.equalhyploldhyps)hypsinlets=letfrst=reftrueinList.fold_left(funacclh->acc^(if!frstthen(frst:=false;"")else" | ")^(List.fold_left(funaccd->(Names.Id.to_stringd)^" "^acc)""lh))""newhypsinlet()=Feedback.msg_noticePp.(str"<infoH>"++(hov0(strs))++(str"</infoH>"))inProofview.tclUNIT()inignore(Declare.Proof.by(Global.env())tacpstate)letdeclare_equivalent_keyscc'=letget_keyc=letenv=Global.env()inletevd=Evd.from_envenvinlet(evd,c)=Constrintern.interp_open_constrenvevdcinletkindc=EConstr.kindevdcinKeys.constr_keyenvkindcinletk1=get_keycinletk2=get_keyc'inmatchk1,k2with|Somek1,Somek2->Keys.declare_equiv_keysk1k2|_->()