Commit graph

36752 commits

Author SHA1 Message Date
Mac Malone
dd64678f07
feat: server support for new module setup (#8699)
This PR adds support to the server for the new module setup process by
changing how `lake setup-file` is used.

In the new server setup, `lake setup-file` is invoked with the file name
of the edited module passed as a CLI argument and with the parsed header
passed to standard input in JSON form. Standard input is used to avoid
potentially exceeding the CLI length limits on Windows. Lake will build
the module's imports along with any other dependencies and then return
the module's workspace configuration via JSON (now in the form of
`ModuleSetup`). The server then post-processes this configuration a bit
and returns it back to the Lean language processor.

The server's header is currently only fully respected by Lake for
external modules (files that are not part of any workspace library). For
workspace modules, the saved module header is currently used to build
imports (as has been done since #7909). A follow-up Lake PR will align
both cases to follow the server's header.

Lean search paths (e.g., `LEAN_PATH`, `LEAN_SRC_PATH`) are no longer
negotiated between the server and Lake. These environment variables are
already configured during sever setup by `lake serve` and do not change
on a per-file basis. Lake can also pre-resolve the `.olean` files of
imports via the `importArts` field of `ModuleSetup`, limiting the
potential utility of communicating `LEAN_PATH`.
2025-06-23 18:00:14 +00:00
Mac Malone
e0a793ae20
feat: ignore lean -R if module name is in setup (#8874)
This PR skips attempting to compute a module name from the file name and
root directory (i.e., `lean -R`) if a name is already provided via `lean
--setup`.

This is accomplished by porting the rest of the frontend code in the
`try` block to Lean.
2025-06-23 17:55:52 +00:00
jrr6
32795911d2
feat: add initial error explanations (#8934)
This PR adds explanations for a few errors concerning noncomputability,
redundant match alternatives, and invalid inductive declarations.

These adopt a lower-case error naming style, which is also applied to
existing error explanation tests.
2025-06-23 17:24:09 +00:00
Anne Baanen
ecf670e08c
feat: make math Lake template follow Mathlib standards (#8866)
This PR upgrades the `math` template for `lake init` and `lake new` to
configures the new project to meet rigorous Mathlib maintenance
standards. In comparison with the previous version (now available as
`lake new ... math-lax`), this automatically provides:

* Strict linting options matching Mathlib.
* GitHub workflow for automatic upgrades to newer Lean and Mathlib
releases.
* Automatic release tagging for toolchain upgrades.
* API documentation generated by
[doc-gen4](https://github.com/leanprover/doc-gen4) and hosted on
`github.io`.
* README with some GitHub-specific instructions.

The previous edition of the template is still available, renamed to
`math-lax`.

---------

Co-authored-by: Mac Malone <tydeu@hatpress.net>
2025-06-23 13:28:47 +00:00
Leonardo de Moura
9a202a420b
feat: semiring normalization theorems (#8943)
This PR adds helper theorems for normalizing semirings that do not
implement `AddRightCancel`.
2025-06-23 13:07:46 +00:00
Wojciech Rozowski
489d7b6d72
feat: add antitonicity lemmas for (co)inductive predicates (#8940)
This PR introduces antitonicity lemmas that support the elaboration of
mixed inductive-coinductive predicates defined using the
`least_fixpoint` / `greatest_fixpoint` constructs.

For instance, the following definition elaborates correctly because all
occurrences of the inductively defined predicate `tock `within the
coinductive definition of `tick` appear in negative positions. The dual
situation applies to the definition of `tock`:
```
  mutual
    def tick : Prop :=
      tock → tick
    greatest_fixpoint

    def tock : Prop :=
      tick → tock
    least_fixpoint
  end
```
2025-06-23 11:02:08 +00:00
Parth Shastri
8223a96bf5
fix: correct universe used in below/brecOn for non-reflexive inductive types (#8937)
This PR changes the output universe of the generated `below`
implementation for non-reflexive inductive types to match the
implementation for reflexive inductive types in #7639.

This fixes the `below`/`brecOn` implementations for certain nested
inductive types, as reported in
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Universes/near/525030149.
2025-06-23 09:42:31 +00:00
Joachim Breitner
29298c9f30
feat: linter.loopingSimpArgs (#8865)
This PR allows `simp` to recognize and warn about simp lemmas that are
likely looping in the current simp set. It does so automatically
whenever simplification fails with the dreaded “max recursion depth”
error fails, but it can be made to do it always with `set_option
linter.loopingSimpArgs true`. This check is not on by default because it
is somewhat costly, and can warn about simp calls that still happen to
work.

This closes #5111. In the end, this implemented much simpler logic than
described there (and tried in the abandoned #8688; see that PR
description for more background information), but it didn’t work as well
as I thought. The current logic is:

“Simplify the RHS of the simp theorem, complain if that fails”.

It is a reasonable policy for a Lean project to say that all simp
invocation should be so that this linter does not complain. Often it is
just a matter of explicitly disabling some simp theorems from the
default simp set, to make it clear and robust that in this call, we do
not want them to trigger. But given that often such simp call happen to
work, it’s too pedantic to impose it on everyone.
2025-06-23 07:36:21 +00:00
Cameron Zwarich
596a3034e7
chore: fix indentation (#8936) 2025-06-23 05:07:33 +00:00
Lean stage0 autoupdater
91a4e17b6d chore: update stage0 2025-06-23 03:43:45 +00:00
Kyle Miller
7b0a9bdadf
feat: let +generalize (#8935)
This PR adds the `+generalize` option to the `let` and `have` syntaxes.
For example, `have +generalize n := a + b; body` replaces all instances
of `a + b` in the expected type with `n` when elaborating `body`. This
can be likened to a term version of the `generalize` tactic. One can
combine this with `eq` in `have +generalize (eq := h) n := a + b; body`
as an analogue of `generalize h : n = a + b`.
2025-06-23 02:21:57 +00:00
Kim Morrison
8f4b2909de
chore: cleanup of grind's order typeclasses (#8913)
This PR cleans up `grind`'s internal order typeclasses, removing
unnecessary duplication.
2025-06-22 23:36:48 +00:00
Kyle Miller
bb0132e4b3
chore: for #8914 after stage0 update, part 2 (#8931)
This PR finishes post-stage0-cleanup after #8914 and #8929. Also:
- adds configuration options for `haveI` and `letI` terms.
- adds `letConfig` parser alias
2025-06-22 22:40:00 +00:00
Kyle Miller
02c8c2f9e1
feat: use nondep flag in Expr.letE and LocalContext.ldecl (#8804)
This PR implements first-class support for nondependent let expressions
in the elaborator; recall that a let expression `let x : t := v; b` is
called *nondependent* if `fun x : t => b` typechecks, and the notation
for a nondependent let expression is `have x := v; b`. Previously we
encoded `have` using the `letFun` function, but now we make use of the
`nondep` flag in the `Expr.letE` constructor for the encoding. This has
been given full support throughout the metaprogramming interface and the
elaborator. Key changes to the metaprogramming interface:
- Local context `ldecl`s with `nondep := true` are generally treated as
`cdecl`s. This is because in the body of a `have` expression the
variable is opaque. Functions like `LocalDecl.isLet` by default return
`false` for nondependent `ldecl`s. In the rare case where it is needed,
they take an additional optional `allowNondep : Bool` flag (defaults to
`false`) if the variable is being processed in a context where the value
is relevant.
- Functions such as `mkLetFVars` by default generalize nondependent let
variables and create lambda expressions for them. The
`generalizeNondepLet` flag (default true) can be set to false if `have`
expressions should be produced instead. **Breaking change:** Uses of
`letLambdaTelescope`/`mkLetFVars` need to use `generalizeNondepLet :=
false`. See the next item.
- There are now some mapping functions to make telescoping operations
more convenient. See `mapLetTelescope` and `mapLambdaLetTelescope`.
There is also `mapLetDecl` as a counterpart to `withLetDecl` for
creating `let`/`have` expressions.
- Important note about the `generalizeNondepLet` flag: it should only be
used for variables in a local context that the metaprogram "owns". Since
nondependent let variables are treated as constants in most cases, the
`value` field might refer to variables that do not exist, if for example
those variables were cleared or reverted. Using `mapLetDecl` is always
fine.
- The simplifier will cache its let dependence calculations in the
nondep field of let expressions.
- The `intro` tactic still produces *dependent* local variables. Given
that the simplifier will transform lets into haves, it would be
surprising if that would prevent `intro` from creating a local variable
whose value cannot be used.

Note that nondependence of lets is not checked by the kernel. To
external checker authors: If the elaborator gets the nondep flag wrong,
we consider this to be an elaborator error. Feel free to typecheck `letE
n t v b true` as if it were `app (lam n t b default) v` and please
report issues.

This PR follows up from #8751, which made sure the nondep flag was
preserved in the C++ interface.
2025-06-22 21:54:57 +00:00
Lean stage0 autoupdater
2ebc001dd1 chore: update stage0 2025-06-22 20:38:51 +00:00
Kyle Miller
f4f664e1ed
fix: update Parser.Term.letIdDeclNoBinders to use new letIdDecl format (#8929)
This PR is a followup to #8914, fixing an oversight where
`letIdDeclBinders` is was not updated with the new format. This relies
on some bootstrapping code to stay in place, but we do bootstrap cleanup
that is currently possible.
2025-06-22 19:28:46 +00:00
Mac Malone
ded8a0cb57
feat: IO.FS.Stream.readToEnd (#8886)
This PR adds `IO.FS.Stream.readToEnd` which parallels
`IO.FS.Handle.readToEnd` along with its upstream definitions (i.e.,
`readBinToEndInto` and `readBinToEnd`). It also removes an unnecessary
`partial` from `IO.FS.Handle.readBinToEnd`.

This function is useful for reading, for example, all of standard input.
2025-06-22 15:39:10 +00:00
Mac Malone
52bdc9bcbd
feat: IO.FS.Stream.lines & IO.FS.Handle.lines (#8887)
This PR generalizes `IO.FS.lines` with `IO.FS.Handle.lines` and adds the
parallel `IO.FS.Stream.lines` for streams.

The stream version is useful for reading, for example, the lines of
standard input.
2025-06-22 14:57:17 +00:00
Joachim Breitner
6092561f93
refactor: SimpM.run (#8843)
This PR factors out the common code for running `SimpM` from `mainCore`
and `dsimpMainCore`, and make it available separately (e.g. for #8865).
2025-06-22 13:50:44 +00:00
Joachim Breitner
117f73fc84
feat: linter.unusedSimpArgs (#8901)
This PR adds a linter (`linter.unusedSimpArgs`) that complains when a
simp argument (`simp [foo]`) is unused. It should do the right thing if
the `simp` invocation is run multiple times, e.g. inside `all_goals`. It
does not trigger when the `simp` call is inside a macro. The linter
message contains a clickable hint to remove the simp argument.

I chose to display a separate warning for each unused argument. This
means that the user has to click multiple times to remove all of them
(and wait for re-elaboration in between). But this just means multiple
endorphine kicks, and the main benefit over a single warning that would
have to span the whole argument list is that already the squigglies tell
the users about unused arguments.

This closes #4483.

Making Init and Std clean wrt to this linter revealed close to 1000
unused simp args, a pleasant experience for anyone enjoying tidying
things: #8905
2025-06-22 09:10:21 +00:00
Sebastian Graf
1e78207d3a
chore: Revert "feat: Upstream MPL.SPred.* from mpl" (#8927)
Reverts leanprover/lean4#8745 until I take a closer look on its breakage
in Mathlib on Monday
2025-06-22 09:02:54 +00:00
Lean stage0 autoupdater
16c918a652 chore: update stage0 2025-06-22 08:08:57 +00:00
Kyle Miller
239534cbb7
chore: for #8914 after stage0 update (#8925)
This PR does a first pass at cleaning things up for #8914 after a stage0
update.
2025-06-22 06:52:11 +00:00
Cameron Zwarich
85e061bed5
chore: remove unused impure LCNF Phase (#8924)
The `.impure` LCNF `Phase` is not currently used, but was intended for a
potential future where the current `IR` passes (which operate on a
highly impure representation) were rewritten to operate on LCNF instead.
For several reasons, I don't think this is very likely to happen, and
instead we are more likely to remove some of the unnecessary differences
between LCNF and IR while keeping them distinct.
2025-06-22 05:38:16 +00:00
Cameron Zwarich
d41b9f004a
feat: support casesOn for Thunk and Task (#8923)
This PR implements `casesOn` for `Thunk` and `Task`. Since these are
builtin types, this needs to be special-cased in `toMono`.

Fixes #8659.
2025-06-22 05:24:33 +00:00
Lean stage0 autoupdater
c63618b7b8 chore: update stage0 2025-06-22 05:33:59 +00:00
Kyle Miller
219f8214d3
feat: make let and have term syntaxes be consistent (#8914)
This PR modifies `let` and `have` term syntaxes to be consistent with
each other. Adds configuration options; for example, `have` is
equivalent to `let +nondep`, for *nondependent* lets. Other options
include `+usedOnly` (for `let_tmp`), `+zeta` (for `letI`/`haveI`), and
`+postponeValue` (for `let_delayed)`. There is also `let (eq := h) x :=
v; b` for introducing `h : x = v` when elaborating `b`. The `eq` option
works for pattern matching as well, for example `let (eq := h) (x, y) :=
p; b`.

Future PRs will add these options to tactic syntax, once a stage0 update
has been done.
2025-06-22 04:22:47 +00:00
Leonardo de Moura
7531d16112
feat: (commutative) semiring support in grind (#8921)
This PR implements support for (commutative) semirings in `grind`. It
uses the Grothendieck completion to construct a (commutative) ring
`Lean.Grind.Ring.OfSemiring.Q α` from a (commutative) semiring `α`. This
construction is mostly useful for semirings that implement
`AddRightCancel α`. Otherwise, the function `toQ` is not injective.
Examples:
```lean
example (x y : Nat) : x^2*y = 1 → x*y^2 = y → y*x = 1 := by
  grind 

example [CommSemiring α] [AddRightCancel α] (x y : α) : x^2*y = 1 → x*y^2 = y → y*x = 1 := by
  grind

example (a b : Nat) : 3 * a * b = a * b * 3 := by grind

example (k z : Nat) : k * (z * 2 * (z * 2 + 1)) = z * (k * (2 * (z * 2 + 1))) := by grind

example [CommSemiring α] [AddRightCancel α] [IsCharP α 0] (x y : α) 
    : x^2*y = 1 → x*y^2 = y → x + y = 1 → False := by
  grind
```
2025-06-21 23:00:16 +00:00
Joachim Breitner
61518e4357
chore: remove more unused simp args (#8920)
This PR uses the linter from #8901 to clean up more simp arguments,
completing #8905.
2025-06-21 18:34:17 +00:00
Joachim Breitner
2441bf1f76
perf: check simp cache in simpLoop (#8880)
This PR makes `simp` consult its own cache more often, to avoid
replicating work.

Before, the simp cache was checked upon entry of `simpImpl` only, which
then calls `simpLoop`, which recursively iterates the `pre`-lemmas,
without checking the cache again.

Now, `simpLoop` itself checks the cache. This seems more principled,
given that `simpLoop` is actually putting entries into the cache for
each of its calls, so it’s more uniform if it checks the cache itself.

This avoids repeated rewrites. For example given
```
theorem ab : a = b := testSorry
theorem bc : b = c := testSorry
example (h : P c) : P b ∧ P a := by simp [ab, bc, h]
```
simp would rewrite `b ==> c` twice (once as part of `b ==> c` and then
again as part of `a ==> b ==> c`). And it’d be order dependent: With
```
example (h : P c) : P a ∧ P b := by simp [ab, bc, h]
```
the `a ==> b ==> c` chain would insert `b ==> c` into the cache, and
picked up by `simpImpl` when rewriting `P b`.

With this change, `b ==> c` is performed only once in both examples.

Instruction counts on stdlib and mathlib both show a mild improvement
across the board (0.5%), with individual modules improving by up to 4%
in stdlib and even more in mathlib.


(This does not check the cache before applying `post`, which explains
where there are still some repeated rewrites in the trace logs. But I’m
less sure about inserting a cache check here and so I am treading
carefully here. It’s also going to be at most one `post` application
that’s duplicated, because if `post` returns `.visit`, we go back to
`pre` and thus a cache check.)
2025-06-21 17:58:05 +00:00
Joachim Breitner
4d697874b7
refactor: simp arg elaboration (#8815)
This PR refactors the way simp arguments are elaborated: Instead of
changing the `SimpTheorems` structure as we go, this elaborates each
argument to a more declarative description of what it does, and then
apply those. This enables more interesting checks of simp arguments that
need to happen in the context of the eventually constructed simp context
(the checks in #8688), or after simp has run (unused argument linter
#8901).

The new data structure describing an elaborated simp argument isn’t the
most elegant, but follows from the code.

While I am at it, move handling of `[*]` into `elabSimpArgs`. Downstream
adaption branches exist (but may not be fully up to date because of the
permission changes).

While I am at it, I cleaned up `SimpTheorems.lean` file a bit (sorting
declarations, mild renaming) and added documentation.
2025-06-21 17:55:53 +00:00
Cameron Zwarich
85992757e7
fix: check guard_msgs.diff using .get rather than Options.getBool (#8918)
This PR fixes the `guard_msgs.diff` default behavior so that the default
specified in the option definition is actually used everywhere.
2025-06-21 16:03:31 +00:00
Cameron Zwarich
7d82dd99c9
chore: add test for #4278, which was fixed by the new compiler (#8916) 2025-06-21 15:05:46 +00:00
Kyle Miller
3878432ac7
fix: make sure local instance detection sees through reductions (#8903)
This PR make sure that the local instance cache calculation applies more
reductions. In #2199 there was an issue where metavariables could
prevent local variables from being considered as local instances. We use
a slightly different approach that ensures that, for example, `let`s at
the ends of telescopes do not cause similar problems. These reductions
were already being calculated, so this does not require any additional
work to be done.

Metaprogramming interface addition: the various forall telescope
functions that do reduction now have a `whnfType` flag (default false).
If it's true, then the callback `k` is given the WHNF of the type. This
is a free operation, since the telescope function already computes it.
2025-06-21 06:26:32 +00:00
Kim Morrison
5198a3fbb7
feat: refactor grind's typeclasses for ordered algebra (#8855)
This PR refactors `Lean.Grind.NatModule/IntModule/Ring.IsOrdered`.

We ensure the the diamond from `Ring` to `NatModule` via either
`Semiring` or `IntModule` is defeq, which was not previously the case.

---------

Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
2025-06-21 04:49:13 +00:00
Leonardo de Moura
921453e3e6
feat: NoNatZeroDivisors for Semiring envelope (#8910)
This PR adds the `NoNatZeroDivisors` instance for `OfSemiring.Q α`
2025-06-21 03:56:37 +00:00
Leonardo de Moura
9ece4e463a
refactor: NoNatZeroDivisors (#8909)
This PR refactors the `NoNatZeroDivisors` to make sure it will work with
the new `Semiring` support.
2025-06-21 03:01:05 +00:00
Sebastian Ullrich
c38c0898a3
chore: allow module in tests (#8881)
This PR adjusts the test scripts and adds a simple test-only lakefile so
that `experimental.module` is set both when editing and running tests.
2025-06-21 02:49:22 +00:00
Leonardo de Moura
12a8f1b5f8
chore: remove staging workarounds (#8908) 2025-06-21 02:38:09 +00:00
Lean stage0 autoupdater
7050dc6d38 chore: update stage0 2025-06-21 01:59:13 +00:00
Kim Morrison
376ae32c7c
feat: fix pretty printing of grind attributes (#8892)
This PR corrects the pretty printing of `grind` modifiers. Previously
`@[grind →]` was being pretty printed as `@[grind→ ]` (Space on the
right of the symbol, rather than left.) This fixes the pretty printing
of attributes, and preserves the presence of spaces after the symbol in
the output of `grind?`.

---------

Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
2025-06-21 00:50:25 +00:00
Cameron Zwarich
0c44aab811
chore: add a test for #4716, which is fixed by the new compiler (#8907) 2025-06-20 23:43:25 +00:00
Kim Morrison
a5eeed4f2c
chore: a few missing grind typeclass docstrings (#8906) 2025-06-20 23:35:58 +00:00
Joachim Breitner
be80a23281
chore: remove unused simp args (#8905)
This PR uses the linter from
https://github.com/leanprover/lean4/pull/8901 to clean up simp
arguments.
2025-06-20 22:34:30 +00:00
Sebastian Ullrich
92ac564f3c
fix: make mkHCongrWithArityForConst? compatible with parallelism (#8899)
This PR ensures the helper is compatible with using `grind` in
asynchronous proofs
2025-06-20 21:55:14 +00:00
Cameron Zwarich
0fcb6495d6
chore: add a test for #6957, fixed by the new compiler (#8904) 2025-06-20 21:44:09 +00:00
Lean stage0 autoupdater
e7c8baaef5 chore: update stage0 2025-06-20 18:52:57 +00:00
Cameron Zwarich
8d8c73416a
chore: add a test for #2602, which was fixed by the new compiler (#8902) 2025-06-20 17:37:19 +00:00
Sebastian Graf
cf527e05bd
feat: where ... finally section to assign leftover goals (#8723)
This PR implements a `finally` section following a (potentially empty)
`where` block. `where ... finally` opens a tactic sequence block in
which the goals are the unassigned metavariables from the definition
body and its auxiliary definitions that arise from use of `let rec` and
`where`.

This can be useful for discharging multiple proof obligations in the
definition body by a single invocation of a tactic such as `all_goals`:
```lean
example (i j : Nat) (xs : Array Nat) (hi : i < xs.size) (hj: j < xs.size) :=
  match i with
  | 0 => x
  | _ => xs[i]'?_ + xs[j]'?_
where x := 13
finally all_goals assumption
```

---------

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-06-20 15:51:28 +00:00
Sebastian Graf
61ee83f73b
feat: Upstream MPL.SPred.* from mpl (#8745)
This PR adds a logic of stateful predicates `SPred` to `Std.Do` in order
to support reasoning about monadic programs. It comes with a dedicated
proof mode the tactics of which are accessible by importing
`Std.Tactic.Do`.

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-06-20 15:13:40 +00:00