@@ -13,6 +13,7 @@ public import Lean.LibrarySuggestions.Basic
1313import Lean.Meta.Tactic.Grind.SimpUtil
1414import Lean.Meta.Tactic.Grind.Util
1515import Lean.Meta.Tactic.Grind.EMatchTheoremParam
16+ import Lean.Meta.Tactic.Simp.Attr
1617import Lean.Elab.Tactic.Grind.Basic
1718import Lean.Elab.Tactic.Grind.Param
1819import Lean.Meta.Tactic.Grind.Action
@@ -198,6 +199,47 @@ def elabGrindSuggestions
198199 throwError "unexpected modifier {p.flag}"
199200 return params
200201
202+ /--
203+ Check if the conclusion of a type (after stripping foralls) is an equality-like proposition
204+ (Eq, Iff, or HEq). Returns true if so.
205+ -/
206+ private def isEqLike (type : Expr) : Bool :=
207+ let conclusion := type.getForallBody
208+ conclusion.isAppOf ``Eq || conclusion.isAppOf ``Iff || conclusion.isAppOf ``HEq
209+
210+ /--
211+ Add simp theorems as E-matching theorems for grind.
212+
213+ **Performance note** : This function iterates over all simp lemmas and generates
214+ grind patterns dynamically at tactic execution time. This is potentially slow
215+ with large simp databases. If this becomes a bottleneck, the proper solution is
216+ to hook into the `@[simp]` attribute handler (in `Lean.Meta.Tactic.Simp.Attr`)
217+ to generate and cache grind patterns at attribute registration time, similar to
218+ how `@[grind]` works.
219+ -/
220+ def elabGrindSimpTheorems (params : Grind.Params) : MetaM Grind.Params := do
221+ let simpTheorems ← getSimpTheorems
222+ let symPrios ← Grind.getGlobalSymbolPriorities
223+ let mut params := params
224+ -- Iterate over all simp lemma origins (includes both fwd and inv directions)
225+ for origin in simpTheorems.lemmaNames.toList do
226+ match origin with
227+ | .decl declName _ inv =>
228+ try
229+ let info ← getConstInfo declName
230+ -- Use eqLhs/eqRhs for equality-like theorems (faster pattern extraction),
231+ -- fall back to .default for other propositions like `P 37`
232+ let kind : Grind.EMatchTheoremKind :=
233+ if isEqLike info.type then
234+ if inv then .eqRhs false else .eqLhs false
235+ else
236+ .default false
237+ let thm ← Grind.mkEMatchTheoremForDecl declName kind symPrios
238+ params := { params with ematch := params.ematch.insert thm }
239+ catch _ => pure () -- Silently skip theorems that fail
240+ | _ => pure () -- Skip non-declaration origins (fvars, etc.)
241+ return params
242+
201243open LibrarySuggestions in
202244def elabGrindParamsAndSuggestions
203245 (params : Grind.Params)
@@ -225,6 +267,8 @@ def mkGrindParams
225267 else
226268 pure #[]
227269 let mut params ← elabGrindParamsAndSuggestions params ps suggestions (only := only) (lax := config.lax)
270+ if config.simp then
271+ params ← elabGrindSimpTheorems params
228272 trace[grind.debug.inj] "{params.inj.getOrigins.map (·.pp)}"
229273 if params.anchorRefs?.isSome then
230274 /-
@@ -297,17 +341,19 @@ def setGrindParams (stx : TSyntax `tactic) (params : Array Syntax) : TSyntax `ta
297341def getGrindParams (stx : TSyntax `tactic) : Array Syntax :=
298342 stx.raw[grindParamsPos][1 ].getSepArgs
299343
300- /-- Filter out `+suggestions` from the config syntax -/
344+ /-- Filter out `+suggestions` and `+simp` from the config syntax for `grind?` suggestions. -/
301345def filterSuggestionsFromGrindConfig (config : TSyntax ``Lean.Parser.Tactic.optConfig) :
302346 TSyntax ``Lean.Parser.Tactic.optConfig :=
303347 let configItems := config.raw.getArgs
304348 let filteredItems := configItems.filter fun item =>
305- -- Keep all items except +suggestions
349+ -- Keep all items except +suggestions and +simp
306350 -- Structure: null node -> configItem -> posConfigItem -> ["+", ident]
307351 match item[0 ]? with
308352 | some configItem => match configItem[0 ]? with
309353 | some posConfigItem => match posConfigItem[1 ]? with
310- | some ident => !(posConfigItem.getKind == ``Lean.Parser.Tactic.posConfigItem && ident.getId == `suggestions)
354+ | some ident =>
355+ let id := ident.getId
356+ !(posConfigItem.getKind == ``Lean.Parser.Tactic.posConfigItem && (id == `suggestions || id == `simp))
311357 | none => true
312358 | none => true
313359 | none => true
0 commit comments