123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223(************************************************************************)(* * 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) *)(************************************************************************)openUtilopenPpopenNamesopenTacexpr(** Nametab for tactics *)moduleTacticV=structincludeKerNameletis_var_=NonemoduleMap=KNmapletstage=Summary.Stage.Interpletsummary_name="ltac1tab"endmoduleTacticTab=Nametab.EasyNoWarn(TacticV)()letpush_tacticvisspkn=TacticTab.pushvisspknletlocate_tacticqid=TacticTab.locateqidletlocate_extended_all_tacticqid=TacticTab.locate_allqidletexists_tactickn=TacticTab.existsknletpath_of_tactickn=TacticTab.to_pathknletshortest_qualid_of_tactickn=TacticTab.shortest_qualidId.Set.emptykn(** Tactic notations (TacAlias) *)typealias=KerName.ttypealias_tactic={alias_args:Id.tlist;alias_body:glob_tactic_expr;alias_deprecation:Deprecation.toption;}letalias_map=Summary.ref~name:"tactic-alias"(KNmap.empty:alias_tacticKNmap.t)letregister_aliaskeytac=alias_map:=KNmap.addkeytac!alias_mapletinterp_aliaskey=tryKNmap.findkey!alias_mapwithNot_found->CErrors.anomaly(str"Unknown tactic alias: "++KerName.printkey++str".")letcheck_aliaskey=KNmap.memkey!alias_map(** ML tactic extensions (TacML) *)typeml_tactic=Geninterp.Val.tlist->Geninterp.interp_sign->unitProofview.tacticmoduleMLName=structtypet=ml_tactic_nameletcomparetac1tac2=letc=String.comparetac1.mltac_tactictac2.mltac_tacticinifc=0thenString.comparetac1.mltac_plugintac2.mltac_pluginelsecendmoduleMLTacMap=Map.Make(MLName)letpr_tacnamet=strt.mltac_plugin++str"::"++strt.mltac_tacticlettac_tab=refMLTacMap.emptyletregister_ml_tactic?(overwrite=false)s(t:ml_tacticarray)=let()=ifMLTacMap.mems!tac_tabthenifoverwritethentac_tab:=MLTacMap.removes!tac_tabelseCErrors.anomaly(str"Cannot redeclare tactic "++pr_tacnames++str".")intac_tab:=MLTacMap.addst!tac_tabletinterp_ml_tactic{mltac_name=s;mltac_index=i}=trylettacs=MLTacMap.finds!tac_tabinlet()=ifArray.lengthtacs<=ithenraiseNot_foundintacs.(i)withNot_found->CErrors.user_err(str"The tactic "++pr_tacnames++str" is not installed.")(***************************************************************************)(* Tactic registration *)(* Summary and Object declaration *)openLibobjecttypeltac_entry={tac_for_ml:bool;tac_body:glob_tactic_expr;tac_redef:ModPath.tlist;tac_deprecation:Deprecation.toption}letmactab=Summary.ref(KNmap.empty:ltac_entryKNmap.t)~name:"tactic-definition"letltac_entries()=!mactabletinterp_ltacr=(KNmap.findr!mactab).tac_bodyletis_ltac_for_ml_tacticr=(KNmap.findr!mactab).tac_for_mlletadd~deprknbt=letentry={tac_for_ml=b;tac_body=t;tac_redef=[];tac_deprecation=depr;}inmactab:=KNmap.addknentry!mactabletreplaceknpatht=letentry_e={ewithtac_body=t;tac_redef=path::e.tac_redef}inmactab:=KNmap.modifyknentry!mactablettac_deprecationkn=try(KNmap.findkn!mactab).tac_deprecationwithNot_found->Nonetypetacdef={local:bool;id:Id.t;for_ml:bool;expr:glob_tactic_expr;depr:Deprecation.toption;}letload_mdi(prefix,{local;id;for_ml=b;expr=t;depr})=letsp,kn=Lib.make_onameprefixidinlet()=ifnotlocalthenpush_tactic(Nametab.Untili)spkninadd~deprknbtletopen_mdi(prefix,{local;id;for_ml=b;expr=t;depr})=(* todo: generate a warning when non-unique, record choices for non-unique mappings *)letsp,kn=Lib.make_onameprefixidinlet()=ifnotlocalthenpush_tactic(Nametab.Exactlyi)spknin()letcache_md(prefix,{local;id;for_ml=b;expr=t;depr})=letsp,kn=Lib.make_onameprefixidinlet()=push_tactic(Nametab.Until1)spkninadd~deprknbtletsubst_md(subst,{local;id;for_ml;expr=t;depr})={local;id;for_ml;expr=Tacsubst.subst_tacticsubstt;depr}letclassify_md_=SubstituteletinMD:tacdef->obj=declare_named_object_gen{(default_object"TAC-DEFINITION")withcache_function=cache_md;load_function=load_md;open_function=filtered_openopen_md;subst_function=subst_md;classify_function=classify_md}letregister_ltacfor_mllocal?deprecationidtac=Lib.add_leaf(inMD{local;id;for_ml;expr=tac;depr=deprecation})typetacreplace={repl_local:Libobject.locality;repl_tac:ltac_constant;repl_expr:glob_tactic_expr;}letload_replacei(prefix,{repl_local;repl_tac;repl_expr=t})=matchrepl_localwith|Local|Export->()|SuperGlobal->replacerepl_tacprefix.obj_mptletopen_replacei(prefix,{repl_local;repl_tac;repl_expr=t})=matchrepl_localwith|Local|SuperGlobal->()|Export->replacerepl_tacprefix.obj_mptletcache_replace(prefix,{repl_local;repl_tac;repl_expr=t})=replacerepl_tacprefix.obj_mptletsubst_replace(subst,{repl_local;repl_tac;repl_expr})={repl_local;repl_tac=Mod_subst.subst_knsubstrepl_tac;repl_expr=Tacsubst.subst_tacticsubstrepl_expr;}letclassify_replaceo=matcho.repl_localwith|Local->Dispose|Export|SuperGlobal->SubstituteletinReplace:tacreplace->obj=declare_named_object_gen{(default_object"TAC-REDEFINITION")withcache_function=cache_replace;load_function=load_replace;(* should this be simple_open ie only redefine when importing the
module containing the redef instead of a parent? *)open_function=filtered_openopen_replace;subst_function=subst_replace;classify_function=classify_replace}letredefine_ltacrepl_localrepl_tacrepl_expr=Lib.add_leaf(inReplace{repl_local;repl_tac;repl_expr})