@@ -12,19 +12,20 @@ public import Lean.Meta.CompletionName
1212public import Init.Data.Random
1313
1414/-!
15- # An API for premise selection algorithms.
15+ # An API for library suggestion algorithms.
1616
17- This module provides a basic API for premise selection algorithms,
18- which are used to suggest identifiers that should be introduced in a proof.
17+ This module provides a basic API for library suggestion algorithms,
18+ which are used to suggest relevant theorems from the library for the current goal.
19+ In the literature this is usually known as "premise selection",
20+ but we mostly avoid that term as most of our users will not be familiar with the term.
1921
2022The core interface is the `Selector` type, which is a function from a metavariable
2123and a configuration to a list of suggestions.
24+ The `Selector` is registered as an environment extension,
25+ and the trivial (no suggestions) implementation is `Lean.LibrarySuggestions.empty`.
2226
23- The `Selector` is registered as an environment extension, and the trivial (no suggestions) implementation
24- is `Lean.PremiseSelection.empty`.
25-
26- Lean does not provide a default premise selector, so this module is intended to be used in conjunction
27- with a downstream package which registers a premise selector.
27+ Lean does not provide a default library suggestion engine, so this module is intended to be used in conjunction
28+ with a downstream package which registers a library suggestion engine.
2829-/
2930
3031namespace Lean.Expr.FoldRelevantConstantsImpl
@@ -113,7 +114,7 @@ public def Lean.MVarId.getRelevantConstants (g : MVarId) : MetaM NameSet := with
113114
114115@[expose] public section
115116
116- namespace Lean.PremiseSelection
117+ namespace Lean.LibrarySuggestions
117118
118119/--
119120A `Suggestion` is essentially just an identifier and a confidence score that the identifier is relevant.
@@ -285,52 +286,68 @@ def random (gen : StdGen := ⟨37, 59⟩) : Selector := fun _ cfg => do
285286 suggestions := suggestions.push { name := name, score := 1 .0 / consts.size.toFloat }
286287 return suggestions
287288
288- builtin_initialize premiseSelectorExt : EnvExtension (Option Selector) ←
289+ /-- A library suggestion engine that returns locally defined theorems (those in the current file). -/
290+ def currentFile : Selector := fun _ cfg => do
291+ let env ← getEnv
292+ let max := cfg.maxSuggestions
293+ -- Use map₂ from the staged map, which contains locally defined constants
294+ let mut suggestions := #[]
295+ for (name, ci) in env.constants.map₂.toList do
296+ if suggestions.size >= max then
297+ break
298+ if isDeniedPremise env name then
299+ continue
300+ match ci with
301+ | .thmInfo _ => suggestions := suggestions.push { name := name, score := 1 .0 }
302+ | _ => continue
303+ return suggestions
304+
305+ builtin_initialize librarySuggestionsExt : EnvExtension (Option Selector) ←
289306 registerEnvExtension (pure none)
290307
291- /-- Generate premise suggestions for the given metavariable, using the currently registered premise selector . -/
308+ /-- Generate library suggestions for the given metavariable, using the currently registered library suggestions engine . -/
292309def select (m : MVarId) (c : Config := {}) : MetaM (Array Suggestion) := do
293- let some selector := premiseSelectorExt .getState (← getEnv) |
294- throwError "No premise selector registered. \
295- (Note that Lean does not provide a default premise selector , \
310+ let some selector := librarySuggestionsExt .getState (← getEnv) |
311+ throwError "No library suggestions engine registered. \
312+ (Note that Lean does not provide a default library suggestions engine , \
296313 these must be provided by a downstream library, \
297- and configured using `set_premise_selector `.)"
314+ and configured using `set_library_suggestions `.)"
298315 selector m c
299316
300317/-!
301318Currently the registration mechanism is just global state.
302- This means that if multiple modules register premise selectors ,
319+ This means that if multiple modules register library suggestions engines ,
303320the behaviour will be dependent on the order of loading modules.
304321
305322We should replace this with a mechanism so that
306- premise selectors are configured via options in the `lakefile`, and
323+ library suggestions engines are configured via options in the `lakefile`, and
307324commands are only used to override in a single declaration or file.
308325-/
309326
310- /-- Set the current premise selector .-/
311- def registerPremiseSelector (selector : Selector) : CoreM Unit := do
312- modifyEnv fun env => premiseSelectorExt .setState env (some selector)
327+ /-- Set the current library suggestions engine .-/
328+ def registerLibrarySuggestions (selector : Selector) : CoreM Unit := do
329+ modifyEnv fun env => librarySuggestionsExt .setState env (some selector)
313330
314331open Lean Elab Command in
315- @[builtin_command_elab setPremiseSelectorCmd , inherit_doc setPremiseSelectorCmd ]
316- def elabSetPremiseSelector : CommandElab
317- | `(command| set_premise_selector $selector) => do
318- if `Lean.PremiseSelection .Basic ∉ (← getEnv).header.moduleNames then
319- logWarning "Add `import Lean.PremiseSelection .Basic` before using the `set_premise_selector ` command."
332+ @[builtin_command_elab setLibrarySuggestionsCmd , inherit_doc setLibrarySuggestionsCmd ]
333+ def elabSetLibrarySuggestions : CommandElab
334+ | `(command| set_library_suggestions $selector) => do
335+ if `Lean.LibrarySuggestions .Basic ∉ (← getEnv).header.moduleNames then
336+ logWarning "Add `import Lean.LibrarySuggestions .Basic` before using the `set_library_suggestions ` command."
320337 let selector ← liftTermElabM do
321338 try
322339 let selectorTerm ← Term.elabTermEnsuringType selector (some (Expr.const ``Selector []))
323340 unsafe Meta.evalExpr Selector (Expr.const ``Selector []) selectorTerm
324341 catch _ =>
325342 throwError "Failed to elaborate {selector} as a `MVarId → Config → MetaM (Array Suggestion)`."
326- liftCoreM (registerPremiseSelector selector)
343+ liftCoreM (registerLibrarySuggestions selector)
327344 | _ => throwUnsupportedSyntax
328345
329346open Lean.Elab.Tactic in
330- @[builtin_tactic Lean.Parser.Tactic.suggestPremises ] def evalSuggestPremises : Tactic := fun _ =>
347+ @[builtin_tactic Lean.Parser.Tactic.suggestions ] def evalSuggestions : Tactic := fun _ =>
331348 liftMetaTactic1 fun mvarId => do
332349 let suggestions ← select mvarId
333- logInfo m!"Premise suggestions: {suggestions.map (·.name)}"
350+ logInfo m!"Library suggestions: {suggestions.map (·.name)}"
334351 return mvarId
335352
336- end Lean.PremiseSelection
353+ end Lean.LibrarySuggestions
0 commit comments