lean4-htt/src/Lean/Elab/Tactic/Generalize.lean
Yann Herklotz 19ce2040a2
fix: wildcard generalize only generalizes visible theorems (#4846)
`generalize ... at *` sometimes will try to modify the recursive
hypothesis corresponding to the current theorem being defined, which may
not be the expected behaviour. It should only try to `generalize`
hypotheses that it can actually modify and are visible, not
implementation details. Otherwise this means that there are
discrepancies between `generalize ... at *` and `generalize ... at H`,
even though `H` is the only hypothesis in the context.

This commit uses `getLocalHyps` instead of `getFVarIds` to get the
current valid `FVarIds` in the context. This uses
`isImplementationDetail` to filter out `FVarIds` that are implementation
details in the context and are not visible to the user and should not be
manipulated by `generalize`.

Closes #4845
2024-10-25 05:09:28 +00:00

42 lines
1.4 KiB
Text

/-
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura, Sebastian Ullrich
-/
prelude
import Lean.Meta.Tactic.Generalize
import Lean.Meta.Check
import Lean.Meta.Tactic.Intro
import Lean.Elab.Binders
import Lean.Elab.Tactic.ElabTerm
import Lean.Elab.Tactic.Location
namespace Lean.Elab.Tactic
open Meta
@[builtin_tactic Lean.Parser.Tactic.generalize] def evalGeneralize : Tactic := fun stx =>
withMainContext do
let mut xIdents := #[]
let mut hIdents := #[]
let mut args := #[]
for arg in stx[1].getSepArgs do
let hName? ← if arg[0].isNone then
pure none
else
hIdents := hIdents.push arg[0][0]
pure (some arg[0][0].getId)
let expr ← elabTerm arg[1] none
xIdents := xIdents.push arg[3]
args := args.push { hName?, expr, xName? := arg[3].getId : GeneralizeArg }
let hyps ← match expandOptLocation stx[2] with
| .targets hyps _ => getFVarIds hyps
| .wildcard => pure ((← getLocalHyps).map (·.fvarId!))
let mvarId ← getMainGoal
mvarId.withContext do
let (_, newVars, mvarId) ← mvarId.generalizeHyp args hyps
mvarId.withContext do
for v in newVars, id in xIdents ++ hIdents do
Term.addLocalVarInfo id (.fvar v)
replaceMainGoal [mvarId]
end Lean.Elab.Tactic