lean4-htt/tests/lean/run/grind_local_hyps.lean
Kim Morrison 1c1bd8e064
fix: handle dot notation on local variables in grind parameters (#11573)
This PR fixes `grind` rejecting dot notation terms, mistaking them for
local hypotheses.

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.

### Minimal reproducer

```lean
theorem Nat.triv (n : Nat) : n = n := rfl

example (n : Nat) : n = n := by
  grind [n.triv]  -- Previously: "redundant parameter `n.triv`"
```

This also 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
2025-12-11 01:28:22 +00:00

47 lines
1.4 KiB
Text

/-! This test ensures that local declarations explicitly passed to `grind` produce an appropriate
error message, instead of just `unknown constant '...'`. -/
-- Checks that (invalid) identifiers which are not local declarations are still elaborated as global
-- constants.
/-- error: Unknown constant `h` -/
#guard_msgs in
example : 0 = 0 := by
grind [h]
-- Checks the same property as before, but in the presence of the modifier `=`, which should not
-- affect how the subsequent identifier is resolved.
/-- error: Unknown constant `h` -/
#guard_msgs in
example : 0 = 0 := by
grind [= h]
-- Checks that (valid) identifiers which are not local declarations are still elaborated as global
-- constants.
theorem t : 0 = 0 := rfl
example : 0 = 0 := by
grind [= t]
-- Checks that local hypotheses do not shadow global constants.
def P := 0 = 0
example : 0 = 0 := by
have P : 0 = 0 := rfl
grind [P]
/-- error: redundant parameter `h`, `grind` uses local hypotheses automatically -/
#guard_msgs in
example : 0 = 0 := by
have h : 1 = 1 := rfl
grind [h]
/-- error: redundant parameter `h`, `grind` uses local hypotheses automatically -/
#guard_msgs in
example : 0 = 0 := by
have h : 1 = 1 := rfl
grind only [h]
-- Checks that dot notation on a local variable for a global theorem is accepted.
-- `n.triv` means `Nat.triv n`, not a local hypothesis.
theorem Nat.triv (n : Nat) : n = n := rfl
example (n : Nat) : n = n := by
grind [n.triv]