Commit graph

27591 commits

Author SHA1 Message Date
Kim Morrison
2e779f79de
fix: bump numInstances for delayed grind theorem instances (#12176)
This PR fixes a bug where delayed E-match theorem instances could cause
uniqueId collisions in the instance tracking map.

The `uniqueId` for theorem instances is generated using `numInstances`,
but this counter was only bumped for immediately activated instances
(`.ready` case), not for delayed instances (`.next` case). This caused
ID collisions:

1. Theorem A matches, becomes delayed, gets `uniqueId = N`
2. Counter isn't bumped (stays at N)
3. Theorem B matches next, gets `uniqueId = N` (same!)
4. B's entry overwrites A's entry in `instanceMap`
5. A's tracking is lost

This manifested as `grind?` and `finish?` producing `instantiate approx`
(meaning "we couldn't determine which theorems to use") instead of
proper `instantiate only [...]` with specific theorem lists.

The fix bumps `numInstances` for delayed instances too, ensuring each
theorem instance gets a truly unique ID.

🤖 Prepared with Claude Code

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-28 03:09:27 +00:00
Elazar Gershuni
90ba5f3f40
feat: add prefix and suffix map injectivity lemmas (#12108)
This PR adds `prefix_map_iff_of_injective` and
`suffix_map_iff_of_injective` lemmas to Init.Data.List.Nat.Sublist.

These lemmas establish that if a function `f` is injective, then the
prefix and suffix relations are preserved under mapping (e.g., `l₁.map f
<+: l₂.map f ↔ l₁ <+: l₂`). These additions complement the existing
index-based lemmas in this file and allow for simpler structural proofs
without resorting to `take`, `drop`, or manual index manipulation.
2026-01-27 22:54:16 +00:00
Eric Wieser
afee8aa1c1
fix: avoid SIGFPE on x86_64 for ISize division overflow (#12110)
This PR fixes a SIGFPE crash on x86_64 when evaluating `(ISize.minValue
/ -1 : ISize)`, filling an omission from #11624.

Closes #12097.
2026-01-27 19:36:07 +00:00
Henrik Böving
31e4eb62b7
perf: speed up compiler recompilation (#12196) 2026-01-27 18:50:58 +00:00
Marc Huisinga
4bcb3cea42
test: make interactive runner uri patching slightly more robust (#12194) 2026-01-27 16:23:46 +00:00
Markus Himmel
ba0e755adc
feat: Std.Iter.first? (#12162)
This PR adds the function `Std.Iter.first?` and proves the specification
lemma `Std.Iter.first?_eq_match_step` if the iterator is productive.

The monadic variant on `Std.IterM` is also provided.

We use this new function to fix the default implementation for
`startsWith` and `dropPrefix` on `String` patterns, which used to fail
if the searcher returned a `skip` at the beginning. None of the patterns
we ship out of the box were affected by this, but user-defined patterns
were vulnerable.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2026-01-27 12:10:16 +00:00
Marc Huisinga
3666544aad
refactor: eliminate $/lean/ileanHeaderInfo (#12107) 2026-01-27 10:08:37 +00:00
Sebastian Graf
4ce04776b6
fix: do not assign synthetic opaque MVars in mspec (#12184)
This PR ensures that the `mspec` tactic does not assign synthetic opaque
MVars occurring in the goal, just like the `apply` tactic.
2026-01-27 10:05:20 +00:00
Marc Huisinga
621fdea272
refactor: eliminate FileIdent.mod (#12089) 2026-01-27 09:55:29 +00:00
Marc Huisinga
fb3aae7509
refactor: remove redundant calls to DocumentMeta.mod (#12085) 2026-01-27 09:02:20 +00:00
Markus Himmel
d4c74b3566
fix: missing order instances for Int (#12181)
This PR adds two missing order instances for `Int`.

As reported on
[Zulip](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/No.20Std.2EMaxOrEq.20Int.20instance.2C.20but.20yes.20Std.2EMinOrEq.20Int/near/570198709).
2026-01-27 05:42:30 +00:00
Kim Morrison
c7f941076e
fix: scope FamilyOut.fam_eq simp lemma to Lake namespace (#12178)
This PR scopes the `simp` attribute on `FamilyOut.fam_eq` to the `Lake`
namespace. The lemma has a very permissive discrimination tree key
(`_`), so when `Lake.Util.Family` is transitively imported into
downstream projects, it causes `simp` to attempt this lemma on every
goal, leading to timeouts.

See
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Lake.20.60FamilyOut.2Efam_eq.60.20leads.20to.20timeouts.3F

🤖 Prepared with Claude Code

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Mac Malone <tydeu@hatpress.net>
2026-01-27 04:24:08 +00:00
Kim Morrison
9185fd2a34
fix: correct comment about instance implicit arguments (#12173)
This PR fixes a comment that said "implicit arguments" when the code
actually checks `isInstImplicit`, which is specifically for instance
implicit arguments (`[...]` binders), not all implicit arguments.

🤖 Prepared with Claude Code

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 01:33:55 +00:00
Kim Morrison
642863e8c5
chore: begin development cycle for v4.29.0 (#12169)
This PR bumps the version to 4.29.0 to begin the next development cycle
after v4.28.0-rc1.

🤖 Prepared with Claude Code

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 23:31:37 +00:00
Leonardo de Moura
62d2688579
feat: eta-reduction support in SymM (#12168)
This PR adds support for eta-reduction in `SymM`.
2026-01-26 21:30:29 +00:00
Sebastian Graf
e8870da205
chore: improve performance of mpure_intro and mvcgen by avoiding whnfD (#12165)
New measurements:

```
goal_10: 181.910200 ms, kernel: 37.241050 ms
goal_20: 386.540215 ms, kernel: 83.497428 ms
goal_30: 648.282057 ms, kernel: 117.038447 ms
goal_40: 946.733191 ms, kernel: 168.369124 ms
goal_50: 1325.846873 ms, kernel: 223.838786 ms
goal_60: 1734.175705 ms, kernel: 285.594486 ms
goal_70: 2199.522317 ms, kernel: 351.659865 ms
goal_80: 2700.077802 ms, kernel: 428.303337 ms
goal_90: 3260.446641 ms, kernel: 515.976499 ms
goal_100: 3865.503733 ms, kernel: 600.229962 ms
```

Previously, goal_100 took 7.8s.
2026-01-26 17:58:33 +00:00
Joachim Breitner
a6a3df8af0
perf: use .inj in proof of .injEq (#12164)
This PR uses the `.inj` theorem in the proof of one direction of the
`.injEq` theorem.
2026-01-26 14:50:32 +00:00
Sebastian Graf
0bcac0d46c
feat: add Option.of_wp_eq and Except.of_wp_eq (#12161)
This PR adds `Option.of_wp_eq` and `Except.of_wp_eq`, similar to the
existing `Except.of_wp`. `Except.of_wp` is deprecated because applying
it requires prior generalization, at which point it is more convenient
to use `Except.of_wp_eq`.
2026-01-26 12:50:23 +00:00
Henrik Böving
c3d753640a
feat: use static initializers where possible (#12082)
This PR makes the compiler produce C code that statically initializes
close terms when possible. This change reduces startup time as the terms
are directly stored in the binary instead of getting computed at
startup.

The set of terms currently supported by this mechanism are:
- string literals
- ctors called with other statically initializeable arguments
- `Name.mkStrX` and other `Name` ctors as they require special support
due to their computed field and occur frequently due to name literals.

In core there are currently 152,524 closed terms and of these 103,929
(68%) get initialized statically with this PR. The remaining 48585 ones
are not extracted because they use (potentially transitively) various
non trivial pieces of code like `stringToMessageData` etc. We might
decide to add special support for these in the future but for the moment
this feels like it's overfitting too much for core.
2026-01-26 11:22:12 +00:00
Joachim Breitner
e94ed002b5
perf: in FunInd, boldly do not check terms (#12160)
This PR removes calls to `check` that we expect to pass under normal
circumstances. This may be re-added later guarded by a `debug` option.
2026-01-26 11:22:00 +00:00
Sebastian Graf
7564329f06
fix: make Std.Do's post macro universe polymorphic (#12159)
This PR makes Std.Do's `post` macro universe polymorphic by expanding to
`PUnit.unit` instead of `()`.
2026-01-26 11:20:16 +00:00
Eric Wieser
0336a8385b
chore: inline trace nodes (#11954)
This extracts a `postCallback` helper so that only the actual callback
is inlined.

Part of the motivation here is to exclude these tracing frames from
flame graph profiles.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2026-01-26 08:51:25 +00:00
David Thrane Christiansen
c6e530a4f1
doc: add link to reference manual in stack overflow message (#12157)
This PR updates #12137 with a link to the Lean reference manual.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2026-01-26 07:56:48 +00:00
Leonardo de Moura
0e28043ec6
feat: add simpTelescope simproc for simplifying binders before intro (#12154)
This PR adds `simpTelescope`, a simproc that simplifies telescope
binders (`have`-expression values and arrow hypotheses) but not the
final body. This is useful for simplifying targets before introducing
hypotheses.
2026-01-25 23:16:30 +00:00
Leonardo de Moura
45862d5486
feat: improves simpArrowTelescope simproc (#12153)
This PR improves the `simpArrowTelescope` simproc that simplifies
non-dependent arrow telescopes: `p₁ → p₂ → ... → q`.

The simproc now also applies telescope-specific simplifications:
- `False → q` to `True` (when `q : Prop`)
- `True → q` to `q` (when `q : Prop`)
- `p → True` to `True`
2026-01-25 22:29:38 +00:00
Leonardo de Moura
ba8c2ed4ee
feat: add simpArrowTelescope for compact proofs of arrow simplification (#12152)
This PR adds `simpArrowTelescope`, a simproc that simplifies telescopes
of non-dependent arrows (p₁ → p₂ → ... → q) while avoiding quadratic
proof growth.

When using `Expr.forallE` to represent nested implications, each nesting
level bumps de Bruijn indices in subterms, destroying sharing even with
hash-consing. For example, a free variable `x` gets different de Bruijn
representations at each depth, causing proof terms to grow.

`simpArrowTelescope` works by:

- Converting arrows to `Arrow p q` (a definitional wrapper)
- Simplifying each component
- Converting back to `→` form

Since `Arrow` arguments are not under binders, subterms remain identical
across nesting levels and can be shared.

The `simp_4` benchmark demonstrates the improvement:

With `forallE`: ~160ms, proof_size ≈ 173k
With `Arrow`: ~43ms, proof_size ≈ 16k
Tradeoff: `simpArrowTelescope` misses simplifications that depend on the
arrow structure (e.g., `p → p` to `True`), since post-methods aren't
applied to intermediate arrows. Thus, it is not used by default. to use
it, one has to set `simpArrowTelescope` as a `pre`-method.
2026-01-25 20:43:59 +00:00
Kim Morrison
9e241a4087
fix: revert "split ngen on async elab" (#12148)
This PR reverts #12000, which introduced a regression where `simp`
incorrectly rejects valid rewrites for perm lemmas.

The issue is that `NameGenerator.mkChild` creates names that don't
maintain the ordering assumption used by `acLt` for perm lemma
decisions. For example, after the change:
- Child generator creates names like `_uniq.102.2`
- Parent continues with `_uniq.7`
- But `Name.lt (.num (.num `_uniq 102) 2) (.num `_uniq 7)` is true

This causes fvars created later (in async tasks) to compare as smaller
than fvars created earlier, breaking the assumption that later fvars
compare greater according to `Name.lt`.

Fixes #12136.

🤖 Prepared with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 03:18:24 +00:00
Leonardo de Moura
e90f6f77db
test: local rewrite with Sym.simp (#12147)
This PR adds a new API for helping users write focused rewrites.
2026-01-25 01:32:50 +00:00
Leonardo de Moura
9deb9ab59d
refactor: move commonly shared expressions to SymM (#12145)
This PR moves the pre-shared commonly used expressions from `GrindM` to
`SymM`.
2026-01-25 00:17:53 +00:00
Leonardo de Moura
6de7100f69
feat: add Goal API for SymM + grind (#12143)
This PR adds an API for building symbolic simulation engines and
verification
condition generators that leverage `grind`. The API wraps `Sym`
operations to
work with `grind`'s `Goal` type, enabling lightweight symbolic execution
while
carrying `grind` state for discharge steps.

New operations on `Goal`:
- `mkGoal`: create a `Goal` from an `MVarId`
- `introN`, `intros`: introduce binders
- `apply`: apply backward rules
- `simp`, `simpIgnoringNoProgress`: simplify using `Sym.Simp`
- `internalize`, `internalizeAll`: add hypotheses to the E-graph
- `grind`: attempt to close the goal using `grind`
- `assumption`: close by matching a hypothesis

A new test demonstrates the API on a stateful program with conditionals,
using `grind` to discharge arithmetic side conditions.
2026-01-24 20:30:08 +00:00
Mac Malone
6f409e0eea
fix: lake: --no-build exit code w/ release fetch (#12142)
This PR fixes a bug introduced in #12086 where a `lake build :release
--no-build` would exit with code 1 rather than the `--no-build ` code 3.
Now both the bug from #12086 and this bug are fixed.
2026-01-24 17:03:07 +00:00
Kim Morrison
a3755fe0a5
fix: add syntax to recommended_spelling for inv (#12139)
This PR adds `«term_⁻¹»` to the `recommended_spelling` for `inv`,
matching
the pattern used by all other operators which include both the function
and the syntax in their spelling lists.

Reported at
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/.60recommended_spelling.60.20for.20.60.C2.ABterm_.E2.81.BB.C2.B9.C2.BB.60

🤖 Prepared with Claude Code

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 11:04:36 +00:00
Henrik Böving
c9facc8102
fix: move allocation of execvp args before fork (#12123)
This PR fixes an issue that may sporadically trigger ASAN to got into a
deadlock when running a subprocess through the `IO.Process.spawn`
framework.

The general issue here is that we run `fork()` and then perform an
allocation in the child before going to `execvp` (for allocating the
arguments to `execvp`). As it turns out, doing this can cause a race
condition in ASAN that ultimately causes a deadlock in the child. This
was fixed upstream but then rolled back (see
https://github.com/google/sanitizers/issues/774). Thus, we must avoid
allocating any memory in between `fork` and `execvp`.
2026-01-23 23:12:23 +00:00
Sebastian Ullrich
3f09741fb9
chore: revert "fix: do not compile with -fwrapv" (#12125)
We are seeing (non-deterministically?) some ubsan reports from implicit
casting to `int`:
https://github.com/leanprover/lean4/actions/runs/21290374536/job/61282105493?pr=12082

Reverts leanprover/lean4#12098
2026-01-23 17:39:52 +00:00
Sebastian Ullrich
9f9531fa13
fix: getParentDeclName? inside where inside public def (#12119)
This PR fixes the call hierarchy for `where` declarations under the
module system

---------

Co-authored-by: mhuisi <mhuisi@protonmail.com>
2026-01-23 17:32:05 +00:00
David Thrane Christiansen
dae0d6fa05
fix: context for info trees and warning hints in Verso docstrings (#12121)
This PR wraps info trees produced by the `lean` Verso docstring
codeblock in a context info node.

Closes #12065.
2026-01-23 16:22:09 +00:00
David Thrane Christiansen
4a3401f69a
fix: enable Verso docstrings in where-blocks (#12122)
This PR adds support for Verso docstrings in `where` clauses.

Closes #12066.
2026-01-23 14:02:11 +00:00
Paul Reichert
4526cdda5f
fix: fix verso's +warning hint (#12116)
This PR fixes the verso hint that appears when using `sorry` in an
example block. It previously said: `` The `+error` flag indicates that
warnings are expected: +warning `` This PR replaces `error` with
`warning`. Fixes #12064
2026-01-23 13:31:02 +00:00
Eric Wieser
c4639150c1
fix: do not compile with -fwrapv (#12098)
This PR removes the requirement that libraries compiled against the lean
headers must use `-fwrapv`.

clang
[documents](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#:~:text=Note%20that%20checks%20are%20still%20added%20even%20when%20%2Dfwrapv%20is%20enabled)
that `-fwrapv` does not automatically turn off the integer overflow
sanitizer; and so overflow should still be avoided in normal execution.
2026-01-23 12:14:17 +00:00
Mac Malone
5e29d7660a
feat: lake: +mod target keys for modules in deps (#12112)
This PR revives the ability to specify modules in dependencies via the
basic `+mod` target key.

Implementation-wise, this removes deprecation of `BuildKey.module` and
once again uses it for `+mod` target keys. It also adds a test for
depending on a module of a dependency via `needs`.
2026-01-23 02:35:02 +00:00
Mac Malone
fa2ddf1c56
chore: lake: disable import all check in module disambiguation (#12104)
This PR disables an overlooked check (in #12045) of `import all` during
module disambiguation.
2026-01-22 18:12:14 +00:00
Mac Malone
f9af240bc4
fix: lake: query :deps output (#12105)
This PR fixes the `lake query` output for targets which produce an
`Array` or `List` of a value with a custom `QueryText` or `QueryJson`
instance (e.g., `deps` and `transDeps`).
2026-01-22 17:52:43 +00:00
Joachim Breitner
3bfeb0bc1f
refactor: use isRecursiveDefinition when validating macro_inline (#12106)
This PR uses `isRecursiveDefinition` when validating `macro_inline`,
instead of rummaging in the internals of the definition.
2026-01-22 16:31:34 +00:00
Paul Reichert
0a0323734b
feat: suggest Int*.toNatClamp for Int*.toNat (#11979)
This PR adds `suggest_for` annotations such that `Int*.toNatClamp` is
suggested for `Int*.toNat`.
2026-01-22 08:51:51 +00:00
Markus Himmel
69b058dc82
feat: Fin and Char ranges (#12058)
This PR implements iteration over ranges for `Fin` and `Char`.

To this end, we introduce machinery for pulling back lawfulness of
`UpwardEnumerable` along an injective map and study the function
`Char.ordinal : Char -> Fin Char.numCodePoints`.
2026-01-22 07:44:55 +00:00
David Thrane Christiansen
2c48ae7dfb
chore: make Verso module docstring API more like that for Markdown (#12093)
This PR makes the Verso module docstring API more like the Markdown
module docstring API, enabling downstream consumers to use them the same
way.
2026-01-22 04:45:49 +00:00
Leonardo de Moura
c81a8897a9
feat: improve Sym.simp APIs and new benchmark data (#12101)
This PR improves the the `Sym.simp` APIs. It is now easier to reuse the
simplifier cache between different simplification steps. We use the APIs
to improve the benchmark at #12100.

### Symbolic simulation with simplifier cache reuse (SymM)

Problem size `n` corresponds to a program with `2·n + 2` instructions.

| n   | Tactic time (ms) | Kernel time (ms) |
|-----|------------------|------------------|
| 10  | 4.53  | 4.29  |
| 20  | 5.56  | 6.91  |
| 30  | 6.46  | 8.67  |
| 40  | 8.07  | 11.20 |
| 50  | 9.37  | 13.63 |
| 60  | 11.89 | 15.43 |
| 70  | 12.43 | 18.28 |
| 80  | 14.07 | 20.72 |
| 90  | 15.62 | 23.41 |
| 100 | 17.39 | 24.80 |
| 200 | 30.35 | 48.39 |
| 300 | 45.41 | 72.84 |
| 400 | 59.17 | 97.67 |
| 500 | 79.63 | 138.99 |
| 600 | 100.05 | 173.67 |
| 700 | 119.77 | 208.80 |

<img width="571" height="455" alt="image"
src="https://github.com/user-attachments/assets/70da7ea2-b5d2-405e-985c-bfa358455afc"
/>
2026-01-22 03:37:16 +00:00
Mac Malone
3bc63aefb7
fix: lake: small cache issues (#12037)
This PR fixes two Lake cache issues: a bug where a failed upload would
not produce an error and a mistake in the `--wfail` checks of the cache
commands.
2026-01-22 03:27:30 +00:00
Leonardo de Moura
af438425d5
perf: avoid mkAppM in Sym.simp (#12099)
This PR ensures `Sym.simpGoal` does not use `mkAppM`. It also increases
the default number of maximum steps in `Sym.simp`.
2026-01-22 00:01:43 +00:00
Mac Malone
648e1b1877
fix: lake: --no-build failure w/ optional release fetch (#12086)
This PR fixes a bug where a `lake build --no-build` would exit with code
`3` if the optional job to fetch a GitHub or Reservoir release for a
package failed (even if nothing else needed rebuilding).
2026-01-21 23:14:54 +00:00