This PR fixes an issue where `exact?` would not suggest private
declarations defined in the current module.
## Problem
When using `exact?` in a file with private declarations, those private
declarations were not being suggested even though they are valid and
accessible:
```lean
module
axiom P : Prop
private axiom p : P
example : P := by exact? -- error: could not find lemma
```
The problem was that `blacklistInsertion` in `LazyDiscrTree` was
filtering out all declarations whose names matched `isInternalDetail`,
which includes private names due to their `_private.Module.0.name`
structure.
## Solution
The fix adds a helper function `isPrivateNameOf` that checks if a
private declaration belongs to a specific module. The
`blacklistInsertion` function now allows private declarations belonging
to the current module (`env.header.mainModule`) to pass through the
filter.
Private declarations from imported modules are still filtered out, as
they may reference internal declarations that aren't accessible (which
would cause processing errors).
Zulip discussion:
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/.60exact.3F.60.20and.20private.20declarations/near/564586152🤖 Prepared with Claude Code
---------
Co-authored-by: Claude <noreply@anthropic.com>
This PR adds a `+all` option to `exact?` and `apply?` that collects all
successful lemmas instead of stopping at the first complete solution.
When `+all` is enabled:
- `exact?` shows all lemmas that completely solve the goal (admits the
goal with `sorry`)
- `apply?` shows all lemmas including both complete and partial
solutions
🤖 Prepared with Claude Code
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Adds a +all flag to exact? and apply? to collect all successful
lemmas, updates library search to support aggregation and proper
star-lemma fallback, and extends the discriminator tree to
extract/append dropped entries; includes tests.
>
> - **Tactics / UI**:
> - Add `LibrarySearchConfig.all` and `+all` flag to `exact?`/`apply?`
to collect all successful lemmas.
> - `exact?` now aggregates complete solutions (via
`addExactSuggestions`); `apply?` shows both complete and partial
suggestions.
> - Updated help texts and error/hint messages.
> - **Library Search Core (`Lean.Meta.Tactic.LibrarySearch`)**:
> - Thread new `collectAll` option through `tryOnEach`,
`librarySearch'`, and `librarySearch`.
> - `tryOnEach` continues collecting complete solutions when `collectAll
= true`.
> - Star-lemma fallback now runs even when primary search yields only
partial results; include complete solutions when aggregating.
> - Cache and retrieve star-indexed lemmas via
`droppedEntriesRef`/`getStarLemmas`.
> - **Lazy Discriminator Tree (`Lean.Meta.LazyDiscrTree`)**:
> - Add `extractKey(s)`/`collectSubtreeAux` to extract and drop entries,
returning them.
> - Modify import/module tree building to optionally append dropped
entries to a shared ref (for star-lemmas), and pass this through
`findMatches`/`createModuleTreeRef`.
> - Minor comment/logic tweaks (append vs set) when handling dropped
entries.
> - **Elaboration (`Lean.Elab.Tactic.LibrarySearch`)**:
> - Integrate `collectAll` into `exact?`/`apply?`; partition and present
complete vs incomplete suggestions; admit goals appropriately when
aggregating.
> - **Tests**:
> - Update existing expectations and add
`tests/lean/run/library_search_all.lean` to verify `+all`, aggregation,
and star-lemma behavior.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
cbfc9313affad45012ebd5ac40b338ee829009b1. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Claude <noreply@anthropic.com>
This PR re-enables star-indexed lemmas as a fallback for `exact?` and
`apply?`.
Star-indexed lemmas (those with overly-general discrimination tree keys
like `[*]`)
were previously dropped entirely for performance reasons. This caused
useful lemmas
like `Empty.elim`, `And.left`, `not_not.mp`, `Sum.elim`, and
`Function.mtr` to be
unfindable by library search.
The implementation adds a two-pass search strategy:
1. First, search using concrete discrimination keys (the current
behavior)
2. If no results are found, fall back to trying star-indexed lemmas
The star-indexed lemmas are extracted during tree initialization and
cached in an
environment extension, avoiding repeated computation.
Users can disable the fallback with `-star`:
```lean
example {α : Sort u} (h : Empty) : α := by apply? -star -- error: no lemmas found
example {α : Sort u} (h : Empty) : α := by apply? -- finds Empty.elim
```
🤖 Prepared with Claude Code
---------
Co-authored-by: Claude <noreply@anthropic.com>
This PR fixes a potential miscompilation when using non-exposed type
definitions using the module system by turning it into a static error. A
future revision may lift the restriction by making the compiler metadata
independent of the current module.
(Almost) only typos in constant names and doc-strings were considered;
grammar was not considered. Also, along others,
`mkDefinitionValInferrringUnsafe` has been fixed :-)
This PR resolves an issue where the `Meta.Context.configKey` field is
private but we still want to use the constructor of the structure for
setting other fields, which would be prevented by the module system
checks:
```lean
structure Context where
private config : Config := {}
private configKey : UInt64 := config.toKey
...
def ContextInfo.runMetaM (info : ContextInfo) (lctx : LocalContext) (x : MetaM α) : IO α := do
-- cannot call private constructor of `Meta.Context`!
(·.1) <$> info.runCoreM (x.run { lctx := lctx } { mctx := info.mctx })
```
Instead, the private field is extracted into an (existing) structure
that applies its default value:
```lean
/-- Configuration with key produced by `Config.toKey`. -/
structure ConfigWithKey where
private mk ::
config : Config := {}
key : UInt64 := config.toKey
structure Context where
keyedConfig : ConfigWithKey := default
```
Thus `Context`'s constructor remains public without exposing a way to
set `key` directly.
This PR replaces all usages of `[:]` slice notation in `src` with the
new `[...]` notation in production code, tests and comments. The
underlying implementation of the `Subarray` functions stays the same.
Notation cheat sheet:
* `*...*` is the doubly-unbounded range.
* `*...a` or `*...<a` contains all elements that are less than `a`.
* `*...=a` contains all elements that are less than or equal to `a`.
* `a...*` contains all elements that are greater than or equal to `a`.
* `a...b` or `a...<b` contains all elements that are greater than or
equal to `a` and less than `b`.
* `a...=b` contains all elements that are greater than or equal to `a`
and less than or equal to `b`.
* `a<...*` contains all elements that are greater than `a`.
* `a<...b` or `a<...<b` contains all elements that are greater than `a`
and less than `b`.
* `a<...=b` contains all elements that are greater than `a` and less
than or equal to `b`.
Benchmarks have shown that importing the iterator-backed parts of the
polymorphic slice library in `Init` impacts build performance. This PR
avoids this problem by separating those parts of the library that do not
rely on iterators from those those that do. Whereever the new slice
notation is used, only the iterator-independent files are imported.
This PR moves away from using `List.get` / `List.get?` / `List.get!` and
`Array.get!`, in favour of using the `GetElem` mediated getters. In
particular it deprecates `List.get?`, `List.get!` and `Array.get?`. Also
adds `Array.back`, taking a proof, matching `List.getLast`.
This PR allows environment extensions to opt into access modes that do
not block on the entire environment up to this point as a necessary
prerequisite for parallel proof elaboration.
This PR modifies the signature of the functions `Nat.fold`,
`Nat.foldRev`, `Nat.any`, `Nat.all`, so that the function is passed the
upper bound. This allows us to change runtime array bounds checks to
compile time checks in many places.
This PR fixes the caching infrastructure for `whnf` and `isDefEq`,
ensuring the cache accounts for all relevant configuration flags. It
also cleans up the `WHNF.lean` module and improves the configuration of
`whnf`.
This PR changes the signature of `Array.get` to take a Nat and a proof,
rather than a `Fin`, for consistency with the rest of the (planned)
Array API. Note that because of bootstrapping issues we can't provide
`get_elem_tactic` as an autoparameter for the proof. As users will
mostly use the `xs[i]` notation provided by `GetElem`, this hopefully
isn't a problem.
We may restore `Fin` based versions, either here or downstream, as
needed, but they won't be the "main" functions.
---------
Co-authored-by: David Thrane Christiansen <david@davidchristiansen.dk>
It currently only reports how many times each declaration has been
unfolded, and how often the `isDefEq` heuristic for `f a =?= f b` has
been used. Only counters above the threshold are reported.
The matches returned by the lazy discriminator tree are partially
constrained by a priority, but ties are broken by the order in which
keys are traversed and the order of declarations.
This PR changes the match key traversal to use an explicit stack rather
than recursion and implicitly changes the order in which results are
returned to favor left-matches first e.g., given the term `f a b` with
constants `f a b`, and a tree with patterns `f a x -> 1` `f x b -> 2`
that have the same priority, this will return `#[1, 2]` since the early
matches for the key `a` are returned before the match for `x` which has
a star.
This appears to address the [lower quality results mentioned on
zulip](https://leanprover.zulipchat.com/#narrow/stream/428973-nightly-testing/topic/Mathlib.20status.20updates/near/429955747).
This makes several changes to rw? and lazy discrimination trees based on
test failures in rewrite search.
Changes include:
1. Reverting to Mathlib function for candidate lemma priority in rw?
2. Introducing additional filters for auto-generated named in lazy
discriminator tree.
3. Refactoring lazy discriminator values to clarify what is stored.
4. Including star keys in calculation of match closeness in
prioritization.
5. Using more fields in current core context when initializing lazy
discriminator tree and avoiding max heartbeat issues.
---------
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
This updates the rw? tactic from Mathlib to use lazy discriminator trees
and upstreams it.
---------
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
This fixes an issue discovered in Mathlib with the meta cache being
poisoned by using a name generator. It is difficult to reproduce due to
the name collisions being rare, but here is a minimal module with
definitions that result in an error:
```lean
prelude
universe u
inductive Unit2 : Type where
| unit : Unit2
inductive Eq2 {α : Sort u} : α → α → Prop where
| refl (a : α) : Eq2 a a
structure Subtype2 {α : Sort u} (p : α → Prop) where
val : α
def End (α) := α → α
theorem end_app_eq (α : Type u) (f : End α) (a : α) : Eq2 (f a) (f a) := Eq2.refl _
theorem Set.coe_eq_subtype {α : Type u} (s : α → Prop) : Eq2 (Subtype2 s) (Subtype2 s) := Eq2.refl _
def succAboveCases {_ : Unit2} {α : Unit2 → Sort u} (i : Unit2) (v : α i) : α i := v
theorem succAbove_cases_eq_insertNth : Eq2 @succAboveCases.{u + 1} @succAboveCases.{u + 1} := Eq2.refl _
```
Removing any of thee last 5 definitions avoids the error. Testing
against Mathlib shows this PR fixes the issue.
This is still a draft PR, but includes the core exact? and apply?
tactics.
Still need to convert to builtin syntax and test on Std.
---------
Co-authored-by: David Thrane Christiansen <david@davidchristiansen.dk>