This PR fixes a bug in #11125. Added a test this time ...
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Exclude deprecated declarations from library suggestions and add a
test verifying they are filtered out.
>
> - **Library Suggestions**:
> - Update `isDeniedPremise` in `src/Lean/LibrarySuggestions/Basic.lean`
to treat `Lean.Linter.isDeprecated` as denied (`true`), filtering
deprecated constants from suggestions.
> - **Tests**:
> - Add `tests/lean/run/library_suggestions_deprecated.lean` to verify
deprecated theorems (e.g., `deprecatedTheorem`) are not suggested by
`currentFile`, while non-deprecated ones are.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ef7e546dbcca1893d68b07ed79e592ff97f2ceb4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
This PR adds iterators and slices for `DTreeMap`/`TreeMap`/`TreeSet`
based on zippers and provides basic lemmas about them.
---------
Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
This PR removes all uses of `String.Iterator` from core, preferring
`String.ValidPos` instead.
In an upcoming PR, `String.Iterator` will be renamed to
`String.Legacy.Iterator`.
This PR adds support for `try?` to use induction; it will only perform
induction on inductive types defined in the current namespace and/or
module; so in particular for now it will not induct on built-in
inductives such as `Nat` or `List`.
This is stacked on top of #11132, and there are overlapping changes.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Adds vanilla induction suggestions to `try?`, updates collection of
inductive candidates, and tests the new behavior on custom inductive
types.
>
> - **Try tactic pipeline**:
> - Add vanilla induction generators (`mkIndStx`, `mkAllIndStx`) that
try `induction <var> <;> …`, with fallback via `expose_names` when
needed.
> - Integrate induction into `mkTryEvalSuggestStx`, alongside existing
atomic, suggestions, and function-induction options.
> - **Collector updates (`Try/Collect.lean`)**:
> - Enhance `checkInductive` to `whnf` the type and use `getAppFn` to
detect inductive heads, populating `indCandidates`.
> - **Tests**:
> - New `tests/lean/run/try_induction.lean` covering suggestions for
`induction` on custom inductives, interaction with `grind`, and
coexistence with `fun_induction`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b357990c97d0855418202626dad3a73cdcae8a86. 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 adds support for `grind +suggestions` and `simp_all?
+suggestions` in `try?`. It outputs `grind only [X, Y, Z]` or `simp_all
only [X, Y, Z]` suggestions (rather than just `+suggestions`).
Co-authored-by: Claude <noreply@anthropic.com>
This PR fixes disequality propagation for constructor applications in
`grind`. The equivalence class representatives may be distinct
constructor applications, but we must ensure they have the same type.
Examples that were panic'ing before this PR:
```lean
example (a b : List Nat)
: a ≍ ([] : List Int) → b ≍ ([1] : List Int) → a = b ∨ p → p := by
grind
example (a b : List Nat)
: a = [] → a ≍ ([] : List Int) → b = [1] → a = b ∨ p → p := by
grind
example (a b : List Nat)
: a = [] → a ≍ ([] : List Int) → b = [1] → b ≍ [(1 : Int)] → a = b ∨ p → p := by
grind
example (a b : List Nat)
: a = [] → b = [1] → a = b ∨ p → p := by
grind
example (a b : List Nat)
: a = [] → a ≍ ([] : List Int) → b = [1] → a = b ∨ p → p := by
grind
```
Closes#11124
This PR fixes a problem for structures with diamond inheritance: rather
than copying doc-strings (which are not available unless `.server.olean`
is loaded), we link to them. Adds tests.
This PR adds `Job.sync` as a standard way of declaring a synchronous
job.
It makes some non-behavior changes to related Job APIs to improve
compilation.
This PR lets the match compilation procedure use sparse case analysis
when the patterns only match on some but not all constructors of an
inductive type. This way, less code is produce. Before, code handling
each of the other cases was then optimized and commoned-up by later
compilation pipeline, but that is wasteful to do.
In some cases this will prevent Lean from noticing that a match
statement is complete
because it performs less case-splitting for the unreachable case. In
this case, give explicit
patterns to perform the deeper split with `by contradiction` as the
right-hand side.
At least temporarily, there is also the option to disable this behaviour
with
```
set_option backwards.match.sparseCases false
```
This PR adds “sparse casesOn” constructions. They are similar to
`.casesOn`, but have arms only for some constructors and a catch-all
(providing `t.ctorIdx ≠ 42` assumptions). The compiler has native
support for these constructors and now (because of the similarity) also
the per-constructor elimination principles.
This PR ensures that the `denote` functions used to implement
proof-by-reflection terms in `grind` are abbreviations. This change
eliminates the need for the `withAbstractAtoms` gadget.
This PR enables Lake users to require Reservoir dependencies by a
semantic version range. On a `lake update`, Lake will fetch the
package's version information from Reservoir and select the newest
version of the package that satisfies the range.
### Using Version Ranges
Version ranges can be specified through the `version` field of a TOML
`require` or the `@` clause of a Lean `require`. They are only
meaningful on Reservoir dependencies.
**lakefile.lean**
```lean-4
require "Seasawher" / "mdgen" @ "2.*"
```
**lakefile.toml**
```toml
[[require]]
name = "mdgen"
scope = "Seasawher"
version = "2.*"
```
The syntax for these versions ranges is a mix of
[Rust's](https://doc.rust-lang.org/stable/cargo/reference/specifying-dependencies.html?highlight=caret#version-requirement-syntax)
and
[Node's](https://github.com/npm/node-semver/tree/v7.7.3?tab=readme-ov-file#ranges)
with some Lean-friendly deviations.
### Comparators
The basic unit of semantic version ranges are version comparators. They
take a base version and a comparison operator and match versions which
compare positively with their base. Lake supports the following
comparison operators.
* `<`, `<=` / `≤`, `>`, `>=` / `≥`, `=`, `!=` / `≠`
Unlike Rust and Node, Lake supports Unicode alternatives for the
operators. It also adds the not-equal operator (`!=` / `≠`) to make
excluding broken versions easier.
Comparators can be combined into clauses via conjunction or disjunction:
* **AND clauses**: Rust-style `≥1.2.3, <1.8.0` or Node-style `1.2.3
<1.8.0`
* **OR clauses**: Node-style `1.2.7 || >=1.2.9, <2.0.0`
When the base version of a comparator has a `-` suffix (e.g.,
`>1.2.3-alpha.3`) it will match versions of the same core (`1.2.3`) with
suffixes that lexicographically compare (e.g., `1.2.3-alpha.7` or
`1.2.3-beta.2`) but will not match suffixed versions of different cores
(e.g., `3.4.5-rc5`). An empty `-` suffix can be used to disable this
behavior. For example, `<2.0.0-` will match `1.2.3-beta.2` and
`2.0.0-alpha.1`.
### Range Macros
In addition to the basic comparators, Lake also supports standard
shorthand for specifying more complex ranges. Namely, it supports the
caret (`^`) and tilde (`~`) operator along with wildcard ranges.
**Caret Ranges**
* `^1` => `≥1.0.0, <2.0.0-`
* `^1.2` => `≥1.2.0, <2.0.0-`
* `^1.2.3` => `≥1.2.3, <2.0.0-`
* `^1.2.3-beta.2` => `≥1.2.3-beta.2, <2.0.0-`
* `^0.2` => `≥0.0.0, <0.3.0-`
* `^0.2.3` => `≥0.2.3, <0.3.0-`
* `^0.0.3` => `≥0.0.3, <0.0.4-`
* `^0` => `≥0.0.0, <1.0.0-`
* `^0.0` => `≥0.0.0, <0.1.0-`
**Tilde Ranges**
* `~1` => `≥1.0.0, <2.0.0-`
* `~1.2` => `≥1.2.0, <1.3.0-`
* `~1.2.3` => `≥1.2.3, <1.3.0-`
* `~1.2.3-beta.2` => `≥1.2.3-beta.2, <1.3.0-`
* `^0` => `≥0.0.0, <1.0.0-`
* `^0.2.3` => `≥0.2.3, <0.3.0-`
* `^0.0.3` => `≥0.0.3, <0.0.4-`
* `~0` => `≥0.0.0, <1.0.0-`
* `~0.0` => `≥0.0.0, <0.1.0-`
* `~0.0.0` => `≥0.0.0, <0.1.0-`
**Wildcard Ranges**
* `*` => `≥0.0.0`
* `1.x` => `≥1.0.0, <2.0.0-`
* `1.*.x` => `≥1.0.0, <2.0.0-`
* `1.2.*` => `≥1.2.0, <1.3.0-`
These ranges closely follow Rust's and Node's syntax. Like Node but
unlike Rust, wildcard ranges support `x` and `X` as alternative syntax
for wildcards.
This PR implements `simp? +suggestions`, which uses the configured
library suggestion engine to add relevant theorems to the `simp` call.
`simp +suggestions` without the `?` prints a message requiring adding
the `?`.
This PR fixes `ST.Ref.ptrEq` to act as described in the docs. This fixes
two bugs:
1. The recent `IO.RealWorld` elimination PR overlooked this function
(afaik this is the only one),
causing its return value to be generally wrong.
2. The implementation of `ptrEq` would previously always consider two
different cells with pointer
equivalent value to be pointer equal. However, the function is supposed
to check whether two
`Ref` are the same cell, not whether the contained elements are.
This PR implements equality propagation for `Nat` in `grind order`.
`grind order` supports offset equalities for rings, but it has an
adapter for `Nat`. Example:
```lean
example (a b : Nat) (f : Nat → Int) : a ≤ b + 1 → b + 1 ≤ a → f (1 + a) = f (1 + b + 1) := by
grind -offset -mbtc -lia -linarith (splits := 0)
```
This PR implements (nested term) equality propagation in `grind order`.
That is, it propagates implied equalities from `grind order` back to the
`grind` core. Examples:
```lean
open Lean Grind Std
example [LE α] [IsPartialOrder α] (a b : α) (f : α → Nat) : a ≤ b → b ≤ c → c ≤ a → f a = f b := by
grind (splits := 0)
example [CommRing α] [LE α] [LT α] [LawfulOrderLT α] [IsPartialOrder α] [OrderedRing α]
(a b : α) (f : α → Int) : a ≤ b + 1 → b ≤ a - 1 → f a = f (2 + b - 1) := by
grind -mbtc -lia -linarith (splits := 0)
example (a b : Int) (f : Int → Int) : a ≤ b + 1 → b ≤ a - 1 → f a = f (2 + b - 1) := by
grind -mbtc -lia -linarith (splits := 0)
```
`prelude-injectivity.lean` was testing inj thm generation for all
inductives in core, including private ones, which could lead to name
clashes that should not be able to occur in actual files. Put it under
the module system to not load private decls in the first place.
This PR fixes a case of overeager constant folding on Nat where the
compiler would mistakenly assume `0 - x = x` (see also #11042 for the
same bug on UInts).
This PR adds a new suggestion to `finish?`. It now generates the `grind`
tactic script as before, and a `finish only` tactic. Example:
```lean
/--
info: Try these:
[apply] ⏎
instantiate only [findIdx, insert, = mem_indices_of_mem]
instantiate only [= getElem?_neg, = getElem?_pos]
cases #1bba
· instantiate only [findIdx]
· instantiate only
instantiate only [= HashMap.mem_insert, = HashMap.getElem_insert]
[apply] finish only [findIdx, insert, = mem_indices_of_mem, = getElem?_neg, = getElem?_pos, = HashMap.mem_insert,
= HashMap.getElem_insert, #1bba]
-/
example (m : IndexMap α β) (a : α) (b : β) :
(m.insert a b).findIdx a = if h : a ∈ m then m.findIdx a else m.size := by
grind => finish?
```
This PR adds a library suggestion engine for local theorems. To be
useful, I still need to write more combinators to re-rank and combine
suggestions from multiple engines.
This is stacked on top of #11029.
This PR changes the terminology used from "premise selection" to
"library suggestions". This will be more understandable to users (we
don't assume anyone is familiar with the premise selection literature),
and avoids a conflict with the existing use of "premise" in Lean
terminology (e.g. "major premise" in induction, as well as generally the
synonym for "hypothesis"/"argument").
This PR improves match compilation: Branch on variables in the order
suggested by the first remaining alternative, and do not branch when the
first remaining alternative does not require it. This fixes
https://github.com/leanprover/lean4/issues/10749. With `set_option
backwards.match.rowMajor false` the old behavior can be turned on.
(For now this is an experiment to get familiar with the code and the
whole
problem domain. It is likely overly naive.)