Commit graph

10543 commits

Author SHA1 Message Date
Wojciech Różowski
dae150a976
fix: handle AppBuilderException in cbv tactic if the projection function is dependent (#12460)
This PR fixes an `AppBuilder` exception in the `cbv` tactic when
simplifying projections whose projection function is dependent (closes
#12457).

Previously, `handleProj` unconditionally used `mkCongrArg` to prove `e.i
= e'.i` from `e = e'`, but `mkCongrArg` requires a non-dependent
function. For dependent projections (e.g., `fun x => x.2 : (x :
String.Slice) → x.1.Pos`), this would fail.

Now, `handleProj` first checks whether the projection function type is
non-dependent (a simple arrow). If so, it proceeds with `mkCongrArg` as
before. Otherwise, it falls back to:
1. Attempting to reduce the projection directly.
2. If reduction fails, using a heterogeneous congruence lemma
(`mkHCongr`) converted to an equality via `mkEqOfHEq`, provided the
original and rewritten struct are definitionally equal.
2026-02-13 14:21:13 +00:00
Henrik Böving
92aec45057
perf: boxing a uint64 yields and object not a tobject (#12465)
This PR changes the boxed type of `uint64` from `tobject` to `object` to
allow for more precise reference counting.
2026-02-13 12:14:37 +00:00
Henrik Böving
c8462354c6
fix: handle 0 sized reads from handles correctly (#12466)
This PR handles zero-sized reads on handles correctly by returning an
empty array before the syscall
is even attempted.

Closes: #12138
2026-02-13 10:56:00 +00:00
Henrik Böving
9f64f53fef
refactor: port Boxing from IR to LCNF (#12458)
This PR ports the IR pass for box/unbox insertion to LCNF.
2026-02-13 09:56:50 +00:00
Markus Himmel
6cbaada1bf
feat: verification of String.positions, String.chars, String.revPositions, String.revChars, ForIn m String Char (#12456)
This PR verifies all of the `String` iterators except for the bytes
iterator by relating them to `String.toList`.

Along the way we define `String.posLE` and `String.posLT` analogously to
`String.posGE` and `String.posGT` and redefine `String.prev` to go
through `String.posLT`.

We also define and verify `String.positionsFrom` and
`String.revPositionsFrom`, which are the obvious generaliziations of
`String.positions` and `String.revPositions` starting at a positions
other than the start/end.

Finally, we get various lemmas about strings and positions, including
some nice induction principles `String.Pos.next_induction` and
`String.Pos.prev_induction`.

Of course, we also have all of the analogous results for `String.Slice`.
2026-02-12 15:32:44 +00:00
Henrik Böving
d9cea67e24
perf: fold Task.get (Task.pure x) to just x (#12446)
This PR adds a simplification rule for `Task.get (Task.pure x) = x` into
the LCNF simplifier. This
ensures that we avoid touching the runtime for a `Task` that instantly
gets destructed anyways.
2026-02-12 08:29:52 +00:00
Markus Himmel
01173b195f
chore: move string iteration to a new file (#12450)
This PR moves the `String.Slice`/`String` iterators out into their own
file, in preparation for verification.
2026-02-12 06:56:53 +00:00
Leonardo de Moura
483cad5fd6
feat: add [univ_out_params] (#12423)
This PR adds the attribute `@[univ_out_params]` for specifying which
universe levels should be treated as output parameters. By default, any
universe level that does not occur in any input parameter is considered
an output parameter.
2026-02-11 15:42:00 +00:00
Henrik Böving
cad960267b
refactor: port borrow inference to LCNF (#12413)
This PR ports the IR borrow pass to LCNF.
2026-02-11 12:08:17 +00:00
Joachim Breitner
f20cae3729
fix: no defeq equations for irreducible definitions (#12429)
This PR sets the `irreducible` attribute before generating the equations
for recursive definitions. This prevents these equations to be marked as
`defeq`, which could lead to `simp` generation proofs that do not type
check at default transparency.

This issue is surfacing more easily since well-founded recursion on
`Nat` is implemented with a dedicated fix point operator (#7965). Before
that, `WellFounded.fix` was used, which is inherently not reducing, so
we did get the desired result even without the explicit reducibility
setting.

Fixes #12398.
2026-02-11 11:49:10 +00:00
Wojciech Różowski
c0df714935
feat: add decide_cbv tactic (#12411)
This PR adds a finishing `decide_cbv` tactic, which applies
`of_decide_eq_true` and then tries to discharge the remaining goal using
`cbv`.


Stacked on top of #12408.

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 10:12:23 +00:00
Rob23oba
be442e9bb3
perf: cache results in replaceRecApps (#12420)
This PR adds caching to `replaceRecApps`, the procedure responsible for
replacing recursive applications for wellfounded recursion, improving
performance when many references to the same recursive call exist, e.g.
when recursive calls exist in proof terms.

Closes #12404

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2026-02-11 09:47:34 +00:00
Sebastian Graf
655cc1178c
fix: make mvcgen suggest -trivial on recursion depth error (#12427)
This PR makes `mvcgen` suggest to use `-trivial` when doing so avoids a
recursion depth error.
2026-02-11 09:10:27 +00:00
Wojciech Różowski
64bd08e1f9
feat: add non-conv, user-facing cbv tactic (#12408)
This PR adds a user facing `cbv` tactic that can be used outside of the
`conv` mode.

Example usage:
```lean4
example : "hello" ++ " " ++ "world" = "hello world" := by cbv
```

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 09:04:11 +00:00
Markus Himmel
61cef96cd7
feat: verification of our KMP implementation (#12424)
This PR gives a proof of `LawfulToForwardSearcherModel` for `Slice`
patterns, which amounts to proving that our implementation of KMP is
correct.

Note that this PR also changes the KMP implementation to make it
slightly more efficient and easier to verify. I also have a correctness
proof for the old implementation, so there were no bugs in the old
implementation.
2026-02-11 08:20:20 +00:00
Sebastian Graf
99c83b9c76
fix: mvcgen support for match splitting on excess state args (#12425)
This PR fixes a bug in `mvcgen` caused by incomplete `match` splitting. 

In particular, if a program `match s with ...` matches on a state
variable `s` (presumably the result of a call to `get`), then `s` will
also occur in the stateful goal `H ⊢ₛ wp⟦match s with ...⟧ Q s`
*outside* the program expression; this was not anticipated before.
2026-02-11 08:12:25 +00:00
Leonardo de Moura
14b595e952
feat: better support for eta expanded terms in grind (#12415)
This PR improves the support for eta expanded terms in `grind` patterns.

Closes #12390
2026-02-10 19:46:00 +00:00
Sebastian Graf
fc4f51d759
feat: pick up specs from the local context in mvcgen (#12395)
This PR adds `mvcgen` support for specifications in the local context.
Example:

```lean
import Std.Tactic.Do

open Std.Do

set_option mvcgen.warning false

def foo (x : Id Nat → Id Nat) : Id Nat := do
  let r₁ ← x (pure 42)
  let r₂ ← x (pure 26)
  pure (r₁ + r₂)

theorem foo_spec
    (x : Id Nat → Id Nat)
    (x_spec : ∀ (k : Id Nat) (_ : ⦃⌜True⌝⦄ k ⦃⇓r => ⌜r % 2 = 0⌝⦄), ⦃⌜True⌝⦄ x k ⦃⇓r => ⌜r % 2 = 0⌝⦄) :
    ⦃⌜True⌝⦄ foo x ⦃⇓r => ⌜r % 2 = 0⌝⦄ := by
  mvcgen [foo, x_spec] <;> grind

def bar (k : Id Nat) : Id Nat := do
  let r ← k
  if r > 30 then return 12 else return r

example : ⦃⌜True⌝⦄ foo bar ⦃⇓r => ⌜r % 2 = 0⌝⦄ := by
  mvcgen [foo_spec, bar] -- unfold `bar` and automatically apply the spec for the higher-order argument `k`
```
2026-02-10 15:51:26 +00:00
Wojciech Różowski
7d32030729
feat: add cbv_eval attribute (#12296)
This PR adds `cbv_eval` attribute that allows to evaluate functions in
`cbv` tactic using pre-registered theorems.
2026-02-10 15:41:42 +00:00
Garmelon
d29407b481
chore: remove outdated trust0 test (#12401) 2026-02-10 13:07:10 +00:00
Paul Reichert
df26bea7c1
feat: upstream slice API improvements from human-eval-lean (#12352)
This PR improves the slice API with lemmas for `drop`/`take` operations
on `Subarray` and more lemmas about `Std.Slice.fold`, `Std.Slice.foldM`
and `Std.Slice.forIn`. It also changes the `simp` and `grind`
annotations for `Slice`-related lemmas. Lemmas converting between slices
of different shapes are no longer `simp`/`grind`-annotated because they
often complicated lemmas and hindered automation.
2026-02-10 10:54:07 +00:00
Wojciech Różowski
82d90b4cdc
fix: force unfolding of the Decidable instace in Decidable.rec (#12399)
This PR adds a custom simproc to handle `Decidable.rec`, where we force
the rewrite in the argument of the `Decidable` type, that normally is
not rewritten due to being a subsingleton.

Closes #12386
2026-02-10 10:49:19 +00:00
Henrik Böving
7488201604
refactor: port IR.SimpCase to LCNF (#12384)
This PR ports the IR SimpCase pass to LCNF.
2026-02-10 08:35:31 +00:00
Wojciech Różowski
57c5efe309
fix: handling of ite/dite expressions in cbv tactic (#12361)
This PR develops custom simprocs for dealing with `ite`/`dite`
expressions in `cbv` tactics, based on equivalent simprocs from
`Sym.simp`, with the difference that if the condition is not reduced to
`True`/`False`, we make use of the decidable instance and calculate to
what the condition reduces to.

Stacked on top of #12391.
2026-02-09 15:00:10 +00:00
Mac Malone
919721c758
feat: IO.FS.Metadata.numLinks (#12277)
This PR adds `IO.FS.Metadata.numLinks`, which contains the number of
hard links to a file.

This changes the implementation of `System.FilePath.metadata` and
`System.FilePath.symlinkMetadata` to use libuv. Otherwise, `st_nlink`
was not properly set on Windows. This also has the side benefit of
provided sub-second precision for file times on Windows (fulfilling an
old TODO). Also, while libuv supports `lstat` for Windows, enabling that
is left to a future PR.
2026-02-09 14:28:56 +00:00
Mac Malone
9a15df5e28
fix: IO.FS.removeFile should delete read-only files on Windows (#12282)
This PR fixes a platform inconsistency in `IO.FS.removeFile` where it
could not delete read-only files on Windows.

The implementation now uses `uv_fs_unlink` instead of `std::remove`, as
libuv can delete read-only files. The PR also fixes a inconsistency in
`IO_test.lean` where it would generate files in the wrong directory when
run interactively.

---------

Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
2026-02-09 14:28:31 +00:00
Leonardo de Moura
6f4e711171
feat: some unification hints (#12341)
This PR adds a few unification hints that we will need after
`backward.isDefEq.respectTransparency` is `true` by default.

See #12338
It was part of #12179.
2026-02-09 04:51:13 +00:00
Sebastian Ullrich
23dc467ef5
chore: do not rely on Name.lt for ordering fvars in acLt (#12306)
Also relands #12000, fixing #12150
2026-02-08 14:25:31 +00:00
Sebastian Ullrich
ae79d14d27
feat: shake: track [csimp] uses (#12351)
This PR extends the `@[csimp]` attribute to be correctly tracked by
`lake shake`
2026-02-07 14:27:00 +00:00
David Thrane Christiansen
2a02685d95
fix: make classes appear as classes rather than structures in docs (#12373)
This PR moves the elaboration of structure/class Verso docstrings until
after the fact that it's a class is registered, so code samples in the
docstring can use it as a class. Redundant addition of structure and
constructor docstrings are also removed, because they're already handled
in MutualInductive.lean.

Closes #11651
2026-02-07 13:06:41 +00:00
David Thrane Christiansen
99b3ba12c9
fix: error messages from Verso docstring parser (#12372)
This PR extensively reworks the Verso docstring parser so that it gives
much better parser errors that provide more useful guidance.

Closes #12063
2026-02-07 07:49:06 +00:00
Leonardo de Moura
03dc334f73
fix: simp have in Sym (#12370)
This PR fixes a proof construction bug in `Sym.simp`.

Closes #12336
2026-02-07 00:24:30 +00:00
David Thrane Christiansen
64c0555e0b
fix: parse indented Verso docstrings specially (#12331)
This PR treats the first character of the first line of a docstring as
being in the leftmost column, even if it physically is not. This allows
left-column items like headers to be used even after spaces. It also
detects the indentation of the entire docstring, using it as the
zero-point for indentation sensitive syntax such as headers.

Closes #12067.
2026-02-06 21:03:56 +00:00
David Thrane Christiansen
0e19692d0b
fix: handle Verso docstrings that don't consume all the docstring (#12362)
This PR fixes poor error reporting from Verso docstrings. Before, if the
Verso parser didn't consume the whole docstring, then Lean would try to
parse the closing -/ and fail; this would lead to backtracking and an
assumption that the docstring must be non-Verso, with only the non-Verso
commands like #guard_msgs as possibilities. Now, the input is always
consumed.

Closes #12118.
2026-02-06 20:00:49 +00:00
Sebastian Graf
6ac96ecd41
feat: improve simp and grind rules for PredTrans.apply (#12358)
This PR improves the `simp` and `grind` rule framework for
`PredTrans.apply` and also renames the respective lemmas according to
convention.
2026-02-06 17:28:56 +00:00
Garmelon
76befb82e4
chore: remove orphaned *.expected.out files (#12357) 2026-02-06 17:05:43 +00:00
Henrik Böving
32fb1ccf1c
refactor: port IR elim_dead_vars to LCNF (#12356)
This PR moves the IR elim_dead_vars pass to LCNF. It cannot delete the
pass yet as it is still used
in later IR passes.
2026-02-06 17:01:59 +00:00
Leonardo de Moura
9ba41a692d
feat: unfold [reducible] class fields (part 1) (#12340)
This PR implements better support for unfolding class fields marked as
`reducible`. For example, we want to mark fields that are types such as
```lean
MonadControlT.stM : Type u -> Type u
```
The motivation is similar to our heuristic that type definitions should
be abbreviations.
Now, suppose we want to unfold `stM m (ExceptT ε m) α` using the
`.reducible` transparency setting, we want the result to be `stM m m
(MonadControl.stM m (ExceptT ε m) α)` instead of
`(instMonadControlTOfMonadControl m m (ExceptT ε m)).1 α`. The latter
would defeat the intent of marking the field as reducible, since the
instance `instMonadControlTOfMonadControl` is `[instance_reducible]` and
the resulting term would be stuck when using `.reducible` transparency
mode.

**Remark**: This feature introduces a few breakages in core and Mathlib.
So, it is disabled for now in this PR. To enable, we must use
`set_option backward.whnf.reducibleClassField true`
2026-02-06 16:18:33 +00:00
Sebastian Ullrich
fae768fb3e
fix: ensure List.filterMap is always csimped (#12348)
Shake accidentally broke this from missing dependency tracking (TBD)
2026-02-06 16:00:33 +00:00
Wojciech Różowski
d2176cb5fb
test: add tests and benchmarks for cbv tactic (#12345)
This PR adds two benchmarks (sieve of Eratosthenes, removing duplicates
from the list) and one test (a function with sublinear complexity
defined via well-founded recursion evaluated on large naturals with up
to `60` digits).

The tests have been suggested by @b-mehta.
2026-02-06 11:41:03 +00:00
Henrik Böving
8d29c591e6
refactor: behavior of inline annotations in the compiler (#12344)
This PR changes the semantics of `inline` annotations in the compiler.
The behavior of the original `@[inline]` attribute remains the same but
the function `inline` now comes with a restriction that it can only use
declarations that are local to the current module. This comes as a
preparation to pulling the compiler out into a separate process.

Closes: #12334
2026-02-06 10:38:14 +00:00
Rob23oba
9b7a8eb7c8
perf: improve over-applied cases in ToLCNF (#12284)
This PR changes the handling of over-applied cases expressions in
`ToLCNF` to avoid generating function declarations that are called
immediately. For example, `ToLCNF` previously produced this:
```lean-4
set_option trace.Compiler.init true
/--
trace: [Compiler.init] size: 4
    def test x y : Bool :=
      fun _y.1 _y.2 : Bool :=
        cases x : Bool
        | PUnit.unit =>
          fun _f.3 a : Bool :=
            return a;
          let _x.4 := _f.3 _y.2;
          return _x.4;
      let _x.5 := _y.1 y;
      return _x.5
-/
#guard_msgs in
def test (x : Unit) (y : Bool) : Bool :=
  x.casesOn (fun a => a) y
```
which is now simplified to
```lean-4
set_option trace.Compiler.init true
/--
trace: [Compiler.init] size: 3
    def test x y : Bool :=
      cases x : Bool
      | PUnit.unit =>
        let a := y;
        return a
-/
#guard_msgs in
def test (x : Unit) (y : Bool) : Bool :=
  x.casesOn (fun a => a) y
```
This is especially relevant for #8309 because there `dite` is defined as
an over-applied `Bool.casesOn`.
2026-02-06 09:27:15 +00:00
David Thrane Christiansen
71e340eb97
feat: allow Verso syntax for module docs to be controlled separately (#12329)
This PR adds the option `doc.verso.module`. If set, it controls whether
module docstrings use Verso syntax. If not set, it defaults to the value
of the `doc.verso` option.

Closes #12070.
2026-02-06 09:09:04 +00:00
Marc Huisinga
f4c5f8e422
fix: set data? field in eager code actions (#12332)
This PR fixes an issue on new NeoVim versions that would cause the
language server to display an error when using certain code actions.

(For some reason, NeoVim recently decided to diverge from VS Code in
terms of when it emits code action resolution requests, which means that
not setting the `data?` field won't preclude NeoVim from emitting a
request anymore, which in turn means that the server can't resolve the
code action.)
2026-02-06 08:57:27 +00:00
Henrik Böving
8e5655516e
perf: put the compiler off the critical path (#12335) 2026-02-05 20:39:11 +00:00
Henrik Böving
c3779bc8d5
refactor: reset reuse pass to LCNF (#12315)
This PR migrates the IR ResetReuse pass to LCNF.
2026-02-05 15:54:46 +00:00
David Thrane Christiansen
4046dd1e61
fix: docstring code suggestions take shadowing into account (#12321)
This PR makes suggestions for builtin docstring roles take shadowing
into account and improves the error message when this goes wrong.

Closes ##12291
2026-02-05 13:45:35 +00:00
Sebastian Ullrich
2a1ba94caf
chore: ready shake for use on core (#12326) 2026-02-05 12:37:55 +00:00
Sebastian Ullrich
b4d4e371d2
chore: shake core (#12276) 2026-02-05 09:10:32 +00:00
Leonardo de Moura
1695b940b1
feat: do not simp instances (#12244)
This PR ensures `simp` does not "simplify" instances by default. The old
behavior can be retrieved by using `simp +instances`. This PR is similar
to #12195, but for `dsimp`.
The backward compatibility flag for `dsimp` also deactivates this new
feature.

```
set_option backward.dsimp.instances true
```

Applying `simp` (and `dsimp`) to instances creates non-standard
instances, and this creates all sorts of problems in Mathlib.

---------

Co-authored-by: Henrik Böving <hargonix@gmail.com>
Co-authored-by: Sebastian Graf <sgraf1337@gmail.com>
Co-authored-by: Kim Morrison <kim@tqft.net>
2026-02-05 04:53:46 +00:00