@@ -13,14 +13,14 @@ public meta import Mathlib.Lean.Elab.InfoTree
1313public meta import Mathlib.Tactic.Basic
1414
1515/-!
16- # The `hint` tactic.
16+ # The `hint` tactic (deprecated) .
1717
18- The `hint` tactic tries the kitchen sink:
19- it runs every tactic registered via the `register_hint <prio> tac` command
20- on the current goal, and reports which ones succeed.
18+ The `hint` tactic is deprecated in favor of `try?`, which is built into Lean 4.26.0+.
2119
22- ## Future work
23- It would be nice to run the tactics in parallel.
20+ Use `register_try?_tactic (priority := N) <tactic>` to register tactics with `try?`.
21+
22+ The `hint` tactic and `register_hint` command are kept for backward compatibility
23+ but will be removed in a future release.
2424-/
2525
2626public meta section
@@ -31,28 +31,34 @@ open Lean.Meta.Tactic.TryThis
3131
3232namespace Mathlib.Tactic.Hint
3333
34- /-- An environment extension for registering hint tactics with priorities. -/
34+ /-- An environment extension for registering hint tactics with priorities. (Deprecated) -/
35+ @ [deprecated "Use `register_try?_tactic` instead" (since := "2025-12-08" )]
3536initialize hintExtension :
3637 SimplePersistentEnvExtension (Nat × TSyntax `tactic) (List (Nat × TSyntax `tactic)) ←
3738 registerSimplePersistentEnvExtension {
3839 addEntryFn := (·.cons)
3940 addImportedFn := mkStateFromImportedEntries (·.cons) {}
4041 }
4142
42- /-- Register a new hint tactic. -/
43+ /-- Register a new hint tactic. (Deprecated) -/
44+ @ [deprecated "Use `register_try?_tactic` instead" (since := "2025-12-08" )]
4345def addHint (prio : Nat) (stx : TSyntax `tactic) : CoreM Unit := do
4446 modifyEnv fun env => hintExtension.addEntry env (prio, stx)
4547
46- /-- Return the list of registered hint tactics. -/
48+ /-- Return the list of registered hint tactics. (Deprecated) -/
49+ @ [deprecated "Use `register_try?_tactic` instead" (since := "2025-12-08" )]
4750def getHints : CoreM (List (Nat × TSyntax `tactic)) :=
4851 return hintExtension.getState (← getEnv)
4952
5053open Lean.Elab.Command in
5154/--
5255Register a tactic for use with the `hint` tactic, e.g. `register_hint 1000 simp_all`.
56+ (Deprecated: use `register_try?_tactic (priority := N) <tactic>` instead)
57+
5358The numeric argument specifies the priority: tactics with larger priorities run before
5459those with smaller priorities. The priority must be provided explicitly.
5560-/
61+ @ [deprecated "Use `register_try?_tactic` instead" (since := "2025-12-08" )]
5662elab (name := registerHintStx)
5763 "register_hint" prio:num tac:tactic : command =>
5864 liftTermElabM do
@@ -70,7 +76,9 @@ Construct a suggestion for a tactic.
7076* If found, use that as the suggestion.
7177* Otherwise use the provided syntax.
7278* Also, look for remaining goals and pretty print them after the suggestion.
79+ (Deprecated)
7380-/
81+ @ [deprecated "Use `try?` instead" (since := "2025-12-08" )]
7482def suggestion (tac : TSyntax `tactic) (trees : PersistentArray InfoTree) : TacticM Suggestion := do
7583 -- TODO `addExactSuggestion` has an option to construct `postInfo?`
7684 -- Factor that out so we can use it here instead of copying and pasting?
@@ -95,42 +103,20 @@ def suggestion (tac : TSyntax `tactic) (trees : PersistentArray InfoTree) : Tact
95103 return { preInfo?, suggestion, postInfo? }
96104
97105/--
98- Run all tactics registered using `register_hint`.
99- Print a "Try these:" suggestion for each of the successful tactics.
106+ The `hint` tactic is deprecated in favor of `try?`.
100107
101- If one tactic succeeds and closes the goal, we don't look at subsequent tactics.
102- -/
103- -- TODO We could run the tactics in parallel.
104- -- TODO With widget support, could we run the tactics in parallel
105- -- and do live updates of the widget as results come in?
106- def hint (stx : Syntax) : TacticM Unit := withMainContext do
107- let tacs := (← getHints).toArray.qsort (·.1 > ·.1 ) |>.toList.map (·.2 )
108- let tacs := Nondet.ofList tacs
109- let results := tacs.filterMapM fun t : TSyntax `tactic => do
110- if let some { msgs, trees, .. } ← observing? (withResetServerInfo (evalTactic t)) then
111- if msgs.hasErrors then
112- return none
113- else
114- return some (← getGoals, ← suggestion t trees)
115- else
116- return none
117- let results ← (results.toMLList.takeUpToFirst fun r => r.1 .1 .isEmpty).asArray
118- let results := results.qsort (·.1 .1 .length < ·.1 .1 .length)
119- addSuggestions stx (results.map (·.1 .2 ))
120- match results.find? (·.1 .1 .isEmpty) with
121- | some r =>
122- -- We don't restore the entire state, as that would delete the suggestion messages.
123- setMCtx r.2 .term.meta.meta.mctx
124- | none => admitGoal (← getMainGoal)
108+ The `try?` tactic provides similar functionality by trying multiple tactics
109+ and reporting successes. Register tactics using:
110+ `register_try?_tactic (priority := N) <tactic>`
125111
126- /--
127- The `hint` tactic tries every tactic registered using `register_hint <prio> tac`,
128- and reports any that succeed.
112+ Note: User-registered tactics run after built-in `try?` strategies.
129113-/
114+ @ [deprecated "Use `try?` instead" (since := "2025-12-08" )]
130115syntax (name := hintStx) "hint" : tactic
131116
132- @ [inherit_doc hintStx]
133117elab_rules : tactic
134- | `(tactic| hint%$tk) => hint tk
118+ | `(tactic| hint) => do
119+ logWarning "The `hint` tactic is deprecated. Use `try?` instead."
120+ evalTactic (← `(tactic| try ?))
135121
136122end Mathlib.Tactic.Hint
0 commit comments