Skip to content

Commit 1279738

Browse files
committed
fix(grind): handle dot notation on local variables in parameters
When a grind parameter like `n.triv` is given, where `n` is a local variable and `triv` is a theorem that takes `n` as an argument (so `n.triv` means `Nat.triv n`), grind was incorrectly rejecting it with "redundant parameter" because it detected that the identifier resolved to a local variable via `resolveLocalName`. The fix checks if `resolveLocalName` returns field projections (non-empty list), indicating dot notation. In that case, we process the parameter as a term expression to let elaboration resolve the dot notation properly, rather than trying to resolve it as a global constant name. Fixes the issue where `grind [x.exp_pos]` was rejected even though `x.exp_pos` elaborates to `Real.exp_pos x`, a valid theorem application. 🤖 Prepared with Claude Code
1 parent 19e1fe5 commit 1279738

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

src/Lean/Elab/Tactic/Grind/Param.lean

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,17 @@ public def elabGrindParams (params : Grind.Params) (ps : TSyntaxArray ``Parser.T
229229
else
230230
params := { params with ematch := (← params.ematch.eraseDecl declName) }
231231
| `(Parser.Tactic.grindParam| $[$mod?:grindMod]? $id:ident) =>
232-
params ← processParam params p mod? id (minIndexable := false) (only := only) (incremental := incremental)
232+
-- Check if this is dot notation on a local variable (e.g., `n.triv` for `Nat.triv n`).
233+
-- If so, process as term to let elaboration resolve the dot notation properly.
234+
if let some (_, _ :: _) := (← resolveLocalName id.getId) then
235+
params ← processTermParam params p mod? id (minIndexable := false)
236+
else
237+
params ← processParam params p mod? id (minIndexable := false) (only := only) (incremental := incremental)
233238
| `(Parser.Tactic.grindParam| ! $[$mod?:grindMod]? $id:ident) =>
234-
params ← processParam params p mod? id (minIndexable := true) (only := only) (incremental := incremental)
239+
if let some (_, _ :: _) := (← resolveLocalName id.getId) then
240+
params ← processTermParam params p mod? id (minIndexable := true)
241+
else
242+
params ← processParam params p mod? id (minIndexable := true) (only := only) (incremental := incremental)
235243
| `(Parser.Tactic.grindParam| $[$mod?:grindMod]? $e:term) =>
236244
params ← processTermParam params p mod? e (minIndexable := false)
237245
| `(Parser.Tactic.grindParam| ! $[$mod?:grindMod]? $e:term) =>

tests/lean/run/grind_local_hyps.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,10 @@ example : 0 = 0 := by
3838
example : 0 = 0 := by
3939
have h : 1 = 1 := rfl
4040
grind only [h]
41+
42+
-- Checks that dot notation on a local variable for a global theorem is accepted.
43+
-- `n.triv` means `Nat.triv n`, not a local hypothesis.
44+
theorem Nat.triv (n : Nat) : n = n := rfl
45+
46+
example (n : Nat) : n = n := by
47+
grind [n.triv]

0 commit comments

Comments
 (0)