feat: efficient tactic configuration elaborators and configurability#13651
Open
kmill wants to merge 7 commits into
Open
feat: efficient tactic configuration elaborators and configurability#13651kmill wants to merge 7 commits into
kmill wants to merge 7 commits into
Conversation
25290c6 to
9873567
Compare
Collaborator
Author
|
!bench |
|
Benchmark results for 9873567 against 25ec7e5 are in. There are significant results. @kmill
Large changes (4✅, 9🟥)
Medium changes (7✅, 5🟥)
Small changes (233✅, 30🟥) Too many entries to display here. View the full report on radar instead. |
|
Mathlib CI status (docs):
|
Collaborator
|
Reference manual CI status:
|
3dff268 to
b0252ef
Compare
mathlib-nightly-testing Bot
pushed a commit
to leanprover-community/batteries
that referenced
this pull request
May 6, 2026
mathlib-nightly-testing Bot
pushed a commit
to leanprover-community/mathlib4-nightly-testing
that referenced
this pull request
May 6, 2026
mathlib-nightly-testing Bot
pushed a commit
to leanprover-community/batteries
that referenced
this pull request
May 8, 2026
mathlib-nightly-testing Bot
pushed a commit
to leanprover-community/batteries
that referenced
this pull request
May 9, 2026
mathlib-nightly-testing Bot
pushed a commit
to leanprover-community/mathlib4-nightly-testing
that referenced
this pull request
May 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR replaces the previous tactic configuration system with a significantly more efficient one that supports custom configuration syntaxes and processing. The
declare_config_elabcommand generates a configuration elaborator that now directly constructs configuration objects; previously it relied onMeta.evalExpr', which involved running a configuration through the full term elaboration, compilation, and evaluation processes. The generated configuration elaborators now also have the capability to do directSyntaxevaluation in common cases, skipping term elaboration. Furthermore, the elaborator accepts configurations more liberally: any user-defined syntax that has the form of anoptConfig-style configuration or configuration item (including, e.g.,namedArguments) is accepted. ImportLean.Elab.ConfigEvalto use the system; see this module for some documentation in addition to the docstrings inLean.Elab.ConfigEval.Commands. Furthermore, thesimptactic now also has(user.optionName := ...)user configuration options, which can be declared using a globaltactic.simp.user.optionNameoption; usegetUserConfigOptionandwithUserConfigto access and set these in metaprograms.Other features:
declare_config_elabcreates a function that exposes aninitparameter for the configuration that will be modified. It also now has awhereclause, enabling the ability to set custom handlers for specific keys.simpandgrindto support multiple default configurations with proper(config := ...)elaboration.EvalTermclass supports direct evaluation ofSyntax, skipping term elaboration. The system will attempt to automatically derive this class when generating the elaborator.EvalTermdoes not recognize the term, then the syntax is elaborated to an expression and anEvalExprinstance is applied to evaluate the expression. The system will similarly automatically derive these instances if possible.EvalTerm (List T)instance it will be able to reduce this to seeking anEvalTerm Tinstance.declare_core_config_elabanddeclare_term_config_elabfor conveniently generating elaborators forCoreMandTermElabM. The difference is that the first takes an explicit flag for whether to log exceptions, and the second uses the currenterrToSorrystate. Warning: if you use theTermElabMone fromTacticM, it will be unaware of the currentrecoverstate. The only differences between these macros are the ways error recovery is handled per monad.Other changes:
#reducetactic configuration now makes use of this system and has more optionsLean.Elab.Tactic.ConfigSetteris removed; thedeclare_config_elab-family macros handle its functionality.Lean.Elab.Tactic.Configis deprecated and will be removed. ImportLean.Elab.ConfigEvalinstead.Notes for metaprogram authors
If you are using the module system, you just need a
meta import Lean.Elab.ConfigEvalto use the macros, and it should serve as a drop-in replacement to the previous system so long asstructurewith no parameters, indices, or universes (onlyTypeis supported);Option,List,Array,String,DataValue, and inductive types inTypewith no parameters or indices, whose fields are similarly composed.The macros synthesize a self-contained configuration elaboration procedure, analyzing the
EvalTermandEvalExprinstances that are currently available or can be automatically derived. These are the components of the system:EvalTerminstances provideTerm → TermElabM αfunctions for evaluation of raw syntax; these handle the common cases where an option value is a identifier, application, or other simple expression. They are responsible for adding TermInfo when info is enabled, to support hovers. One can invoke derivation of aEvalTerm Tinstance with theensure_eval_term_instance Tcommand (afteropen scoped Lean.Elab.ConfigEval).EvalExprinstances provideExpr → TermElabM αfunctions for evaluation of elaborated expressions; these handle cases where an option value may require reduction to evaluate. Similarly, one can invoke derivation of anEvalExpr Tinstance with theensure_eval_expr_instance Tcommand. If needed, there's alsoderive_eval_expr_instance_using_meta_eval Tfor creating aMeta.evalExpr'-based evaluator.ConfigEval.evalExprWithElabcomposeEvalTermandEvalExprinstances into a single procedure that first attemptsEvalTerm, and, if that fails, applies the standard term elaborator and then attemptsEvalExpr. This way term elaboration can be skipped in all but uncommon cases.ConfigEval.foldConfigM, which is a procedure with a lax specification for what counts as a configuration item, calling the provided function on each recognized configuration item. The idea is:optConfigorconfigItem("+"<|>"-") (atom<|>ident)are considered to be boolean options"(" (atom<|>ident) ":=" syntax ")"are considered to be general configuration items. (It only checks for the presence of(and that there are two-to-five arguments.)EvalConfigItem.seton each item produced by the fold, for anEvalConfigItemstructure defined for the given configuration type. Thedef_eval_config_itemcommand can be used to generate this structure. It analyzes whichEvalTermandEvalExprinstances exist and derives missing ones, then builds an efficient procedure to process configuration items and apply evaluators.declare_core_config_elab,declare_term_config_elab,declare_config_elab, anddeclare_command_config_elabmacros for conveniently running thedef_eval_config_itemcommand and constructing a self-contained elaboration function.The derivation procedures analyze which
EvalTerm/EvalExprinstances already exist and only derive the "leaf" instances that are necessary to constructEvalTermandEvalExprinstances. The derived instances are madeprivate local— since configuration elaborators are meant to be self-contained, we decided not to let the additional instances be a side effect of the macros. The instances can be globally added by manually using theensure_*commands.The macros support making parameterized elaborators with arbitrary additional binders. See
make_elab_grind_configandmake_elab_simp_configin core Lean for examples of generating a single elaborator that's used with multiple default value configurations.To see how to create a key handler that matches all configuration keys with a given prefix, see
make_elab_simp_config.There is a todo item at
Lean.Elab.ConfigEval.ReflectConfigItemsfor reflecting configurations back to syntax, which is not yet supported.The #13426 draft PR includes some LSP modifications to support completions for
simpuser configuration options.