Skip to content

Commit 184ad81

Browse files
committed
feat: tryAtEachStep linters run on a fraction of goals (#31039)
This PR allows us to run the `tryAtEachStep` linters on a deterministic fraction of all Mathlib goals, to enable faster benchmarks.
1 parent 49d8bb1 commit 184ad81

File tree

2 files changed

+36
-16
lines changed

2 files changed

+36
-16
lines changed

Mathlib/Tactic/TacticAnalysis/Declarations.lean

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ register_option linter.tacticAnalysis.rwMerge : Bool := {
164164
}
165165

166166
@[tacticAnalysis linter.tacticAnalysis.rwMerge, inherit_doc linter.tacticAnalysis.rwMerge]
167-
def rwMerge : TacticAnalysis.Config := .ofComplex {
167+
def Mathlib.TacticAnalysis.rwMerge : TacticAnalysis.Config := .ofComplex {
168168
out := (List MVarId × Array Syntax)
169169
ctx := (Array (Array Syntax))
170170
trigger ctx stx :=
@@ -193,7 +193,7 @@ private abbrev mergeWithGrindAllowed : Std.HashSet Name := { `«tactic#adaptatio
193193

194194
@[tacticAnalysis linter.tacticAnalysis.mergeWithGrind,
195195
inherit_doc linter.tacticAnalysis.mergeWithGrind]
196-
def mergeWithGrind : TacticAnalysis.Config where
196+
def Mathlib.TacticAnalysis.mergeWithGrind : TacticAnalysis.Config where
197197
run seq := do
198198
if let #[(preCtx, preI), (_postCtx, postI)] := seq[0:2].array then
199199
if postI.stx.getKind == ``Lean.Parser.Tactic.grind && preI.stx.getKind ∉ mergeWithGrindAllowed then
@@ -212,7 +212,7 @@ register_option linter.tacticAnalysis.terminalToGrind : Bool := {
212212

213213
@[tacticAnalysis linter.tacticAnalysis.terminalToGrind,
214214
inherit_doc linter.tacticAnalysis.terminalToGrind]
215-
def terminalToGrind : TacticAnalysis.Config where
215+
def Mathlib.TacticAnalysis.terminalToGrind : TacticAnalysis.Config where
216216
run seq := do
217217
let threshold := 3
218218
-- `replaced` will hold the terminal tactic sequence that can be replaced with `grind`.
@@ -265,19 +265,32 @@ def terminalToGrind : TacticAnalysis.Config where
265265
if oldHeartbeats * 2 < newHeartbeats then
266266
logWarningAt stx m!"'grind' is slower than the original: {oldHeartbeats} -> {newHeartbeats}"
267267

268-
open Elab.Command in
268+
open Elab.Command
269+
270+
/--
271+
When running the "tryAtEachStep" tactic analysis linters,
272+
only run on a fraction `1/n` of the goals found in the library.
273+
274+
This is useful for running quick benchmarks.
275+
-/
276+
register_option linter.tacticAnalysis.tryAtEachStep.fraction : Nat := {
277+
defValue := 1
278+
}
279+
269280
/-- Run a tactic at each proof step. -/
270-
def tryAtEachStep (tac : Syntax → MVarId → CommandElabM (TSyntax `tactic)) : TacticAnalysis.Config where
281+
def Mathlib.TacticAnalysis.tryAtEachStep (tac : Syntax → MVarId → CommandElabM (TSyntax `tactic)) : TacticAnalysis.Config where
271282
run seq := do
283+
let fraction := linter.tacticAnalysis.tryAtEachStep.fraction.get (← getOptions)
272284
for (ctx, i) in seq do
273285
if let [goal] := i.goalsBefore then
274-
let tac ← tac i.stx goal
275-
let goalsAfter ← try
276-
ctx.runTacticCode i goal tac
277-
catch _e =>
278-
pure [goal]
279-
if goalsAfter.isEmpty then
280-
logInfoAt i.stx m!"`{i.stx}` can be replaced with `{tac}`"
286+
if (hash goal) % fraction = 0 then
287+
let tac ← tac i.stx goal
288+
let goalsAfter ← try
289+
ctx.runTacticCode i goal tac
290+
catch _e =>
291+
pure [goal]
292+
if goalsAfter.isEmpty then
293+
logInfoAt i.stx m!"`{i.stx}` can be replaced with `{tac}`"
281294

282295
/-- Run `grind` at every step in proofs, reporting where it succeeds. -/
283296
register_option linter.tacticAnalysis.tryAtEachStepGrind : Bool := {
@@ -286,7 +299,7 @@ register_option linter.tacticAnalysis.tryAtEachStepGrind : Bool := {
286299

287300
@[tacticAnalysis linter.tacticAnalysis.tryAtEachStepGrind,
288301
inherit_doc linter.tacticAnalysis.tryAtEachStepGrind]
289-
def tryAtEachStepGrind := tryAtEachStep (fun _ _ => `(tactic| grind))
302+
def tryAtEachStepGrind := tryAtEachStep fun _ _ => `(tactic| grind)
290303

291304
/-- Run `simp_all` at every step in proofs, reporting where it succeeds. -/
292305
register_option linter.tacticAnalysis.tryAtEachStepSimpAll : Bool := {
@@ -295,7 +308,7 @@ register_option linter.tacticAnalysis.tryAtEachStepSimpAll : Bool := {
295308

296309
@[tacticAnalysis linter.tacticAnalysis.tryAtEachStepSimpAll,
297310
inherit_doc linter.tacticAnalysis.tryAtEachStepSimpAll]
298-
def tryAtEachStepSimpAll := tryAtEachStep (fun _ _ => `(tactic| simp_all))
311+
def tryAtEachStepSimpAll := tryAtEachStep fun _ _ => `(tactic| simp_all)
299312

300313
/-- Run `aesop` at every step in proofs, reporting where it succeeds. -/
301314
register_option linter.tacticAnalysis.tryAtEachStepAesop : Bool := {
@@ -316,7 +329,7 @@ register_option linter.tacticAnalysis.tryAtEachStepGrindPremises : Bool := {
316329

317330
@[tacticAnalysis linter.tacticAnalysis.tryAtEachStepGrindPremises,
318331
inherit_doc linter.tacticAnalysis.tryAtEachStepGrindPremises]
319-
def tryAtEachStepGrindPremises := tryAtEachStep (fun _ _ => `(tactic| grind +premises))
332+
def tryAtEachStepGrindPremises := tryAtEachStep fun _ _ => `(tactic| grind +premises)
320333

321334
-- TODO: add compatibility with `rintro` and `intros`
322335
/-- Suggest merging two adjacent `intro` tactics which don't pattern match. -/
@@ -325,7 +338,7 @@ register_option linter.tacticAnalysis.introMerge : Bool := {
325338
}
326339

327340
@[tacticAnalysis linter.tacticAnalysis.introMerge, inherit_doc linter.tacticAnalysis.introMerge]
328-
def introMerge : TacticAnalysis.Config := .ofComplex {
341+
def Mathlib.TacticAnalysis.introMerge : TacticAnalysis.Config := .ofComplex {
329342
out := Option (TSyntax `tactic)
330343
ctx := Array (Array Term)
331344
trigger ctx stx :=

MathlibTest/tryAtEachStep.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,10 @@ set_option linter.tacticAnalysis.tryAtEachStepAesop true
77
#guard_msgs in
88
theorem foo : 2 + 2 = 4 := by
99
rfl
10+
11+
-- Set the fraction sufficiently high that nothing will ever run.
12+
set_option linter.tacticAnalysis.tryAtEachStep.fraction 1_000_000_000_000
13+
14+
#guard_msgs in
15+
theorem bar : 2 + 2 = 4 := by
16+
rfl

0 commit comments

Comments
 (0)