Compare commits

...

1759 Commits

Author SHA1 Message Date
Kim Morrison
c3486f253f fix 2025-11-10 00:14:04 +01:00
Kim Morrison
5c35405052 chore: add failing test for diamond structure docstrings 2025-11-10 00:14:04 +01:00
Mac Malone
80409a9ceb feat: lake: Job.sync & other touchups (#11118)
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.
2025-11-08 04:35:05 +00:00
Mac Malone
590ff23e71 fix: lake: moreLinkObjs|Libs on a lean_exe (#11117)
This PR fixes a bug where Lake ignored `moreLinkObjs` and `moreLinkLibs`
on a `lean_exe`.
2025-11-08 04:20:42 +00:00
Joachim Breitner
f843837bfa test: test missing cases error (#11107)
This PR tests the missing cases error.

I thought I broke this, but it seems I did not (or at least not this
way, maybe there is a way to trigger it).
2025-11-06 14:38:55 +00:00
Joachim Breitner
d41f39fb10 perf: sparse case splitting in match compilation (#10823)
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
```
2025-11-06 13:46:35 +00:00
Joachim Breitner
7459304e98 refactor: bv_decide: remove verifyEnum et. al (#11068)
This PR removes the `verifyEnum` functions from the bv_decide frontend.
These functions looked at the implementation of matchers to see if they
really do the matching that they claim to do. This breaks that
abstraction barrier, and should not be necessary, as only functions with
a `MatcherInfo` env entry are considered here, which should all play
nicely.
2025-11-06 09:22:36 +00:00
Kim Morrison
e6b1f1984c feat: suggestions tactic generates hovers (#11098)
This PR updates the `suggestions` tactic so the printed message includes
hoverable type information (and displays scores and flags when
relevant).
2025-11-06 06:31:04 +00:00
Kim Morrison
6d2af21aa0 feat: add Int.ediv_pow and related lemmas (#11100)
This PR adds `theorem Int.ediv_pow {a b : Int} {n : Nat} (hab : b ∣ a) :
(a / b) ^ n = a ^ n / b ^ n` and related lemmas.

---------

Co-authored-by: Bhavik Mehta <bhavikmehta8@gmail.com>
2025-11-06 06:16:18 +00:00
Kim Morrison
3a4e64fe94 feat: some missing Array grind annotations (#11102)
This PR adds some annotations missing in the Array bootstrapping files.
2025-11-06 05:22:40 +00:00
Leonardo de Moura
0d7ca700ad fix: Function.Injective initialization in grind (#11101)
This PR fixes an initialization issue for local `Function.Injective f`
hypotheses.

Closes #11088
2025-11-06 04:26:57 +00:00
Leonardo de Moura
f401f8b46e fix: universe meta-variable support in grind (#11099)
This PR improves the support for universe-metavariables in `grind`.

Closes #11086
2025-11-06 03:38:59 +00:00
Sebastian Ullrich
ae86c18ac1 chore: backward.privateInPublic should not break irrelevance of proofs for rebuilds (#11097) 2025-11-05 23:00:04 +00:00
Sebastian Ullrich
ea2b745e57 chore: new module system adjustments for the Mathlib port (#11093) 2025-11-05 22:17:53 +00:00
Kim Morrison
28a3cf9a6c chore: grind attributes for Prod (#11085) 2025-11-05 20:52:28 +00:00
Joachim Breitner
343887e480 perf: use hasIndepIndices (#11095)
This PR makes use of `hasIndepIndices`. That function was unused since
commit 54f6517ca3, but it seems it should
be used.
2025-11-05 18:41:23 +00:00
Joachim Breitner
d8a67095d6 chore: make workspaceSymbol benchmarks modules (#11094)
This PR makes workspaceSymbol benchmarks `module`s, so that they are
less sensitive to additions of private symbols in the standard library.
2025-11-05 18:40:39 +00:00
Joachim Breitner
0cb79868f4 feat: sparse casesOn constructions (#11072)
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.
2025-11-05 15:49:11 +00:00
Leonardo de Moura
ccecac5a56 chore: use abbrev in denote functions (#11092)
This PR ensures that `grind ac` denotation functions used in proof by
reflection are marked as `abbrev`.
2025-11-05 13:51:36 +00:00
Marc Huisinga
8b43fc54b2 doc: clarify server protocol violations around initialize (#11091) 2025-11-05 09:53:39 +00:00
Leonardo de Moura
e7f4f98071 fix: stackoverflow during proof construction in grind (#11084)
This PR fixes a stack overflow that occurs when constructing a proof
term in `grind`.

Closes #11081
2025-11-05 02:35:05 +00:00
Leonardo de Moura
52e37e0d55 refactor: denote functions in grind (#11071)
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.
2025-11-04 23:34:17 +00:00
Leonardo de Moura
a4e073f565 fix: panic during equality propagation in grind ring (#11080)
This PR fixes a panic during equality propagation in the `grind ring`
module. If the maximum number of steps has been reached, the polynomials
may not be fully simplified.

Closes #11073
2025-11-04 23:20:38 +00:00
Sebastian Ullrich
18131de438 fix: evalConst meta check and auxiliary IR decls (#11079)
Uncovered in Mathlib through new boxed decls from `BaseIO` changes
2025-11-04 21:29:49 +00:00
Leonardo de Moura
e430626d8a fix: anchor values in grind? (#11077)
This PR fixes the anchor values produced by `grind?`
2025-11-04 13:03:18 +00:00
Kim Morrison
e76bbef79b feat: simp? +suggestions handles ambiguity (#11075)
This PR updates `simp? +suggestions` so that if a name is ambiguous
(because of namespaces) all alternatives are used, rather than erroring.
2025-11-04 05:26:51 +00:00
Kim Morrison
04d72fe346 chore: basic dev instructions for Claude (#11074)
This PR adds a `.claude/claude.md`, with basic development instructions
for Claude Code to operate in this repository.
2025-11-04 04:07:53 +00:00
Sebastian Ullrich
e4fb780f8a perf: remove unused argument to ExternEntry.opaque (#11066)
This used to create quite a few unique objects in public .olean
2025-11-03 17:26:32 +00:00
Wojciech Różowski
00e29075f3 feat: add union on DTreeMap/TreeMap/TreeSet (#10896)
This PR adds union operations on DTreeMap/TreeMap/TreeSet and their raw
variants and provides lemmas about union operations.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-11-03 13:47:44 +00:00
Kim Morrison
ec775907e4 chore: update stage0 2025-11-03 23:26:40 +11:00
Kim Morrison
8d603d34dc feat: make set_library_suggestions persistent 2025-11-03 23:26:40 +11:00
Mac Malone
528c0dd2e4 feat: lake: require dependencies by semver range (#10959)
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.
2025-11-03 04:18:24 +00:00
Kim Morrison
b8bd91d92b feat: simp? +suggestions (#11032)
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 `?`.
2025-11-03 03:26:16 +00:00
Lean stage0 autoupdater
e05b0e097c chore: update stage0 2025-11-03 02:54:49 +00:00
Mac Malone
d23dcc88ea fix: lake: pin mathlib in new/init to toolchain (#11063)
This PR changes the `math` and `math-lax` templates for `lake new` and
`lake init` to use the version of Mathlib corresponding to the current
Lean toolchain. Thus, `lake +x.y.z new <pkg> math` will use the Mathlib
for Lean `x.y.z`. On the other hand, `lake update` on such packages will
no longer update Mathlib automatically. Users will need to change the
Mathlib revision in the configuration file before updating.

This change was inspired by a
[discussion](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Build.20error.20on.20.60lake.20.2Bleanprover.2Flean4.3Av4.2E22.2E0.20new.20foo.20math.60/near/546236449)
on the community Zulip.
2025-11-03 02:16:29 +00:00
Mac Malone
1aca181fe2 fix: lake: use -O0 for debug builds (#11062)
This PR changes Lake's debug build type to use `-O0` instead of `-Og`
when compiling C code. `-Og` was found to be insufficient for debugging
compiled Lean code -- relevant code was stilled optimized out.
2025-11-03 02:16:26 +00:00
Leonardo de Moura
2c45d55683 fix: deep recursion type checking grind proof (#11061)
This PR fixes a deep recursion issue in the kernel when type-checking a
proof term produced by `grind`.

Closes #11059
2025-11-02 19:43:48 +00:00
Rob23oba
f4c71f6ec8 fix: simplify Nat.ble (#11058)
This PR changes `Nat.ble` by joining the two `Nat.ble Nat.zero _` cases
into one, allowing `decide (0 <= x) = true` and `decide (0 < succ x) =
true` to be solvable by `rfl`.
2025-11-02 12:39:49 +00:00
Henrik Böving
823173a761 fix: make ST.Ref.ptrEq behave as stated in the docs (#11056)
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.
2025-11-02 10:42:33 +00:00
Leonardo de Moura
3e86729ee0 feat: grind? using finish? infrastructure (#11057)
This PR implements `grind?` using the new `grind => finish?`
infrastructure.
2025-11-02 05:00:50 +00:00
Leonardo de Moura
2da124d469 chore: remove grind offset (#11051)
This PR removes the `grind offset` module because it is (now) subsumed
by `grind order`.
2025-11-01 19:08:18 +00:00
Leonardo de Moura
1d00dee392 fix: grind order equality propagation for Nat (#11050)
This PR fixes equality propagation for `Nat` in `grind order`.
2025-11-01 18:35:34 +00:00
Leonardo de Moura
e5a6901161 feat: Nat equality propagation in grind order (#11049)
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)
```
2025-11-01 15:37:17 +00:00
Markus Himmel
cf871a892c chore: use String.ofList instead of String.mk in elaborator+kernel (#11048)
This PR is a follow-up to #11017, preparing for the eventual removal of
the `String.mk` function.
2025-11-01 14:44:16 +00:00
Markus Himmel
d24ece1396 feat: String.toList_map (#11021)
This PR adds more theory about `Splits` for strings and deduces the
first user-facing `String` lemma, `String.toList_map`.
2025-11-01 13:54:39 +00:00
Leonardo de Moura
faed852c2f feat: equality propagation in grind order (#11047)
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)
```
2025-11-01 13:45:54 +00:00
Sebastian Ullrich
4939f447a3 test: avoid testing colliding private inductives (#11041)
`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.
2025-11-01 11:47:52 +00:00
Henrik Böving
3d307925b7 refactor: make constant folding more robust for future bugs (#11044)
This PR enforces users of the constant folder API to provide proofs of
their algebraic properties,
thus hopefully avoiding bugs such as #11042 and #11043 in the future.
2025-11-01 11:07:20 +00:00
Rob23oba
1fa67d0d47 fix: overeager Nat.sub constant folding (#11043)
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).
2025-11-01 10:14:20 +00:00
Henrik Böving
51ef1dcc5e fix: overeager uint constant folding (#11042)
This PR fixes a case of overeager constant folding on UInts where the
compiler would mistakenly
assume `0 - x = x`.
2025-11-01 02:42:43 +00:00
Leonardo de Moura
282b583f1d fix: panic during the processing of generalized patterns in grind (#11040)
This PR fixes a panic that occurred during the processing of generalized
E-matching patterns in `grind`.

Closes #10983
2025-10-31 16:58:11 +00:00
Leonardo de Moura
4a111501eb fix: grind invalid universe level regression (#11039)
This PR fixes the `grind` invalid universe level regression reported in
#11036

Closes #11036
2025-10-31 15:44:34 +00:00
Leonardo de Moura
16d0005991 feat: finish? produces finish only suggestion (#11034)
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?
```
2025-10-31 14:47:24 +00:00
Markus Himmel
377f149862 refactor: use String.ofList and String.toList for String <-> List Char conversion (#11017)
This PR establishes `String.ofList` and `String.toList` as the preferred
method for converting between strings and lists of characters and
deprecates the alternatives `String.mk`, `List.asString` and
`String.data`.
2025-10-31 14:41:23 +00:00
Markus Himmel
c41cb64ca7 chore: adjust pr-title check to enforce capitalization (#11033)
This PR updates the `pr-title` CI check to enforce that the commit
message does not start with a capital letter followed by a non-capital
letter.

This should ensure that messages do not start with a capitalized word,
but allow messages that start with an acronym.
2025-10-31 07:23:25 +00:00
Kim Morrison
1ce05b2a17 feat: library suggestion engine for local theorems (#11030)
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.
2025-10-31 04:48:53 +00:00
Kim Morrison
0db89d65b2 chore: use 'library suggestions' rather than 'premise selection' (#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").
2025-10-31 04:07:49 +00:00
Kim Morrison
00d41d64e5 feat: remove +premises from grind? output (#11028)
This PR ensures that `grind? +premises` removes `+premises` from the
"Try this" suggestion.
2025-10-31 03:00:33 +00:00
Leonardo de Moura
40e1e097c1 fix: grind order nontermination and propagation issues (#11026)
This PR fixes a nontermination and missing propagation bug in `grind
order`. It also register relevant case-splits for arithmetic.

Closes #11001
2025-10-30 23:12:51 +00:00
Joachim Breitner
d7e4f32d75 feat: Bool.ctorIdx (#11024)
This PR lets `Bool` have `.ctorIdx` like any other inductive.
2025-10-30 21:17:43 +00:00
Joachim Breitner
c7f57d6a0b fix: avoid unnecessary branching in match compilation (#10763)
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.)
2025-10-30 20:05:13 +00:00
Wrenna Robson
275f9077b6 fix: Rename theorems that use sorted instead of pairwise (#10743)
This PR renames theorems that use `sorted` in their name to instead use
`pairwise`.


Closes #10742.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
2025-10-30 16:07:35 +00:00
Henrik Böving
8b28467655 perf: better detection of repeated branching on same value (#11020)
This PR improves the detection of situations where we branch multiple
times on the same value in the
code generator. Previously this would only consider repeated branching
on function arguments, now on
arbitrary values.


Closes: #11018
2025-10-30 16:02:45 +00:00
Markus Himmel
c0ad969b14 fix: docstring of ByteArray.IsValidUTF8.intro (#11022)
This PR fixes an incomplete docstring.
2025-10-30 15:57:01 +00:00
AxelBoldt
e73e0901f8 doc: improve variable names and specify types in SMul doc (#10989)
When documenting smul : M → α → α, it is unintuitive and confusing to
use variables a:M and b:α. It is better to use m:M and a:α. I also
specified the types of all involved terms in the documentation text.
2025-10-30 15:56:42 +00:00
Henrik Böving
cc046e0c18 perf: improve join point finding (#10999)
This PR improves join point finding in the compiler through two means:
1. We now handle situations where a function `f` can only become a join
point when a function `g`
   becomes a join point as well correctly.
2. We introduce a second join point finding pass after specialisation
and before the following
simplification pass, as the specialiser might have introduced new join
point opportunities for
   the simplifier to exploit.

Notably in the code from #10995 we now correctly detect the missing join
point which required both
of these changes to be made.

Closes: #10995
2025-10-30 15:05:11 +00:00
Wrenna Robson
e11ef3ee4e fix: Remove redundant instance requirement (#10941)
This PR removes a redundant instance requirement from
`Std.instIrreflLtOfIsPreorderOfLawfulOrderLT`.
2025-10-30 13:21:26 +00:00
Kim Morrison
b2b385b456 chore: update stage0 2025-10-30 18:43:59 +11:00
Kim Morrison
7a8c2daf96 feat: sine qua non premise selection 2025-10-30 18:43:59 +11:00
Lean stage0 autoupdater
33e92677ba chore: update stage0 2025-10-30 07:41:23 +00:00
Markus Himmel
5af12df54b chore: add String.ofList redefine String.toList (#11016)
This PR ensures that `String.toList` and `String.ofList` exist and have
the right `extern` annotations.
2025-10-30 07:07:12 +00:00
Kim Morrison
705084d9ba chore: deprecate more duplications (#11004)
This PR deprecates various duplicated definitions, detected in
[#mathlib4 > duplicate declarations @
💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/duplicate.20declarations/near/547434277)
2025-10-30 05:58:29 +00:00
Joachim Breitner
e2f5938e74 refactor: some Meta.Match.Match refactorings (#11011)
This PR extracts some refactorings from #10763, including dropping dead
code and not failing in `inaccessibleAsCtor`, which leadas to (slightly)
better error messages, and also on the grounds that the failing
alternative may actually be unreachable.
2025-10-29 23:24:57 +00:00
Leonardo de Moura
d3c9056d2b feat: support grind parameters in finish and finish? (#11012)
This PR ensures the `grind` tactics `finish` and `finish?` can take
parameters.
2025-10-29 20:51:48 +00:00
Joachim Breitner
2f0f0a3018 chore: pr release: git commit --allow-empty (#11013)
This PR uses `--allow-empty` so that the PR release script does not fail
when it's being retried after an intermittent failure.
2025-10-29 21:48:11 +01:00
Henrik Böving
1587d02dfb fix: more stable eager lambda lifting heuristic (#11010)
This PR makes the eager lambda lifting heuristic more predictable by
blocking it from lifting from
any kind of inlineable function, not just `@[inline]`. It also adapts
the doc-string to describe
what is actually going on.
2025-10-29 13:58:23 +00:00
Henrik Böving
a51822ead2 perf: inline Decidable instances (#11008)
This PR inlines several Decidable instances for performance reasons.

Unlike the previous #10934 it does not attempt to also simplify the
Decidable instance system as
that has proven to have non trivial performance impact.

Co-authored-by: Rob23oba <152706811+Rob23oba@users.noreply.github.com>
2025-10-29 10:59:54 +00:00
Henrik Böving
2cfd980528 fix: revert the waitAny refactoring (#11000)
This PR fixes a memleak caused by the Lean based `IO.waitAny`
implementation by reverting it.

This the faulty Lean implementation:
```lean
def IO.waitAny (tasks : @& List (Task α)) (h : tasks.length > 0 := by exact Nat.zero_lt_succ _) :
    BaseIO α := do
  have : Nonempty α := ⟨tasks[0].get⟩
  let promise : IO.Promise α ← IO.Promise.new
  tasks.forM <| fun t => BaseIO.chainTask (sync := true) t promise.resolve
  return promise.result!.get
```
In a situation where we call this function repeatedly in a loop with a
pair of tasks `[t1, t2]`
where `t2` is a long lived task that we pass every time and `t1` is
fresh a short lived task, `t2` will
accumlate more and more children from `BaseIO.chainTask` that fill
memory over time. The old C++
implementation did not have this issue so we are reverting.
2025-10-29 08:27:16 +00:00
Henrik Böving
2497cf0b40 fix: Revert "perf: inline decidable instances" (#11007)
This PR reverts leanprover/lean4#10934
2025-10-29 08:06:51 +00:00
Markus Himmel
167429501b refactor: redefine String.replace (#10986)
This PR defines `String.Slice.replace` and redefines `String.replace` to
use the `Slice` version.

The new implementation is generic in the pattern, so it supports things
like `"education".replace isVowel "☃!" = "☃!d☃!c☃!t☃!☃!n"`. Since it
uses the `ForwardSearcher` infrastructure, `String` patterns are
searched using KMP, unlike the previous implementation which had
quadratic runtime. As a side effect, the behavior when replacing an
empty string now matches that of most other programming languages,
namely `"abc".replace "" "k" = "kakbkck"`.
2025-10-29 07:48:33 +00:00
Sebastian Graf
d427423917 chore: remove duplicate lemmas in Std.Do.SPred (#11006)
This PR removes the duplicate lemmas
`Std.Do.SPred.{and_pure,or_pure,imp_pure,entails_pure_intro}`.
2025-10-29 07:26:24 +00:00
Markus Himmel
106b0fa661 fix: KMP implementation (#10998)
This PR fixes the KMP implementation, which did incorrect bookkeeping of
the backtracking process, leading to incorrect starting ranges of
matches.

The new implementation does not require `partial` anywhere.
2025-10-29 06:04:45 +00:00
Kim Morrison
335e34df19 chore: add deprecations for duplicated theorems (#10967) 2025-10-29 05:26:16 +00:00
Leonardo de Moura
d436619c6d feat: add anchor support for restricting search space in grind only (#11003)
This PR adds support for specifying anchors to restrict the search space
in `grind` when using `grind only`. Anchors can limit which case splits
are performed and which local lemmas are instantiated.
2025-10-29 01:16:10 +00:00
Marc Huisinga
19533ab1d4 feat: revamp server logging (#10787)
This PR revamps the server logging mechanism to allow filtering the log
output by LSP method.
2025-10-28 16:26:59 +00:00
Leonardo de Moura
28310a77ad feat: config options at finish (#10997)
This PR adds support for configuration options at `finish` and
`finish?`.
2025-10-28 15:41:26 +00:00
Lean stage0 autoupdater
8ff5b8ec2c chore: update stage0 2025-10-28 13:47:28 +00:00
Leonardo de Moura
99ff606d58 chore: rename cutsat => lia (#10991)
This PR renames `cutsat` in configuration options and trace messages to
`lia`.
2025-10-28 12:25:48 +00:00
Kim Morrison
8862d23453 chore: cleanup in Dyadic API (#10994) 2025-10-28 06:41:46 +00:00
Kim Morrison
d8335bd661 feat: add @[grind ext] attributes for extensional maps (#10993)
This PR allows `grind` to work extensionally on extensional maps/sets.
2025-10-28 05:20:45 +00:00
Kim Morrison
1981c62604 feat: make grind +premises more robust to bad suggestions (#10992)
This PR ensures that `grind +premises` silently drops warnings and
errors about bad suggestions.
2025-10-28 03:22:42 +00:00
Leonardo de Moura
bb3dd13f72 feat: set_config for setting grind configuration options (#10990)
This PR adds the `set_config` tactic for setting `grind` configuration
options. It uses the same syntax used for setting configuration options
in the `grind` main tactic.
2025-10-28 02:25:01 +00:00
Joachim Breitner
808d123e6f doc: typo in grindDef docstring (#10988)
This PR fixes a typo in the `grindDef` docstring.
2025-10-27 15:59:06 +00:00
Joachim Breitner
14d76cc062 fix: decreasing_by: preserve variable names of match alts (#10980)
This PR tries to preserve names of pattern variables in match
alternatives in `decreasing_by`, by telescoping into the concrete
alternative rather than the type of the matcher's alt. Fixes #10976.
2025-10-27 14:00:36 +00:00
Markus Himmel
d2f76ade61 fix: search for empty string (#10985)
This PR ensures that searching for an empty string returns the expected
pattern of alternating size-zero matches and size-one rejects.

In particular, splitting by an empty string returns an array formed of
the empty string, all of the string's characters as singleton strings,
followed by another empty string. This matches the [Rust
behavior](https://doc.rust-lang.org/std/primitive.str.html#method.split),
for example.
2025-10-27 13:05:33 +00:00
Rob23oba
12750d25b5 perf: inline decidable instances (#10934)
This PR adds inline annotations to several `Decidable` instances.
Additionally, it removes the `Decidable` instance for `p → q` which is
made redundant by `forall_prop_decidable`.
2025-10-27 12:05:01 +00:00
Henrik Böving
334fa475b4 fix: use general allocator for closures (#10982)
This PR changes the closure allocator to use the general allocator
instead of the small object one.
This is because users may create closures with a gigantic amount of
closed variables which in turn
boost the size of the closure beyond the small object threshold.

This issue was uncovered by #10979. Detecting that the small object
threshold is at fault requires
building mimalloc in debug mode at which point it yields:
```
mimalloc: assertion failed: at "/home/henrik/lean4/build/debug/mimalloc/src/mimalloc/src/alloc.c":132, mi_heap_malloc_small_zero
  assertion: "size <= MI_SMALL_SIZE_MAX"
```
The generated code at fault here looks as follows:
```c
LEAN_EXPORT lean_object* l_initExec___at___00res_spec__0(lean_object* x_1) {
_start:
{
lean_object* x_2; lean_object* x_3; lean_object* x_4; lean_object* x_5; lean_object* x_6; lean_object* x_7; lean_object* x_8; lean_object* x_9; lean_object* x_10; lean_object* x_11; lean_object* x_12; lean_object* x_13; lean_object* x_14;
x_2 = lean_alloc_closure((void*)(l_initializer_ext___at___00initExec___at___00res_spec__0_spec__0___lam__0___boxed), 3, 0);
x_3 = l_initExec___redArg___closed__0;
x_4 = l_initExec___redArg___closed__1;
x_5 = l_instMonadLiftNonDetT___closed__0;
x_6 = l_initExec___redArg___closed__2;
x_7 = l_initExec___at___00res_spec__0___closed__0;
lean_inc_ref(x_2);
x_8 = lean_alloc_closure((void*)(l_initExec___at___00res_spec__0___lam__29___boxed), 213, 212);
lean_closure_set(x_8, 0, x_3);
lean_closure_set(x_8, 1, x_2);
lean_closure_set(x_8, 2, x_4);
lean_closure_set(x_8, 3, x_3);
lean_closure_set(x_8, 4, x_4);
lean_closure_set(x_8, 5, x_3);
lean_closure_set(x_8, 6, x_4);
lean_closure_set(x_8, 7, x_3);
lean_closure_set(x_8, 8, x_4);
lean_closure_set(x_8, 9, x_3);
lean_closure_set(x_8, 10, x_4);
lean_closure_set(x_8, 11, x_3);
lean_closure_set(x_8, 12, x_4);
lean_closure_set(x_8, 13, x_3);
lean_closure_set(x_8, 14, x_4);
lean_closure_set(x_8, 15, x_5);
lean_closure_set(x_8, 16, x_6);
lean_closure_set(x_8, 17, x_5);
lean_closure_set(x_8, 18, x_5);
lean_closure_set(x_8, 19, x_5);
lean_closure_set(x_8, 20, x_5);
lean_closure_set(x_8, 21, x_5);
lean_closure_set(x_8, 22, x_5);
...
```
With the crash happening in `lean_alloc_closure` where we
unconditionally invoke the small allocator
which cannot cope with closures this large. Hopefully changing this to
the general purpose allocator
doesn't have too much of an impact on performance.

Closes: #10979
2025-10-27 10:16:59 +00:00
Markus Himmel
8fe260de55 feat: termination arguments for String.ValidPos and String.Slice.Pos (#10933)
This PR adds the basic infrastructure to perform termination proofs
about `String.ValidPos` and `String.Slice.Pos`.

We choose approach where the intended way to do termination arguments is
to argue about the position itself rather than some projection of it
like `remainingBytes`.

The types `String.ValidPos` and `String.Slice.Pos` are equipped with a
`WellFoundedRelation` instance given by the greater-than relation. This
means that if a function takes a position `p` and performs a recursive
call on `q`, then the decreasing obligation will be `p < q`. This works
well in the common case where `q` is `p.next h`, in which case the goal
`p < p.next h` is solved by the simplifier.

For stepping through a string backwards, we introduce a type synonym
with a `WellFoundedRelation` instance given by the less-than relation.
This means that if a function takes a position `p` and performs a
recursive call on `q` and specifies `termination_by p.down`, then the
decreasing obligation will be `q < p`. This works well in the case where
`q` is `p.prev h`, in which case the goal `p.prev h < p` is solved by
the simplifier.

For termination arguments invoving multiple strings, the lower-level
primitive `p.remainingBytes` (landing in `Nat`) is also available.

In a future PR, we will additionally provide the necessary typeclasses
instances to register `String.ValidPos` and `String.Slice.Pos` with
`grind` to make complex termination arguments more convenient in user
code.
2025-10-27 10:05:44 +00:00
Henrik Böving
7e1be20317 perf: widen more in ElimDeadBranches (#10856)
This PR performs more widening in ElimDeadBranches in an attempt to
improve performance in situations with a lot of local precision.

While this is not enough to make the compilation instant it pushes
compilation time from 12s to 3s for the example in #10857 and barely
introduces regressions so it seems like a good first step in this
direction.

Closes: #10857
2025-10-27 09:12:16 +00:00
Leonardo de Moura
3a42ee0c30 feat: grind tactic mode improvements (#10978)
This PR implements the following `grind` improvements:
1. `set_option` can now be used to set `grind` configuration options in
the interactive mode.
2. Fixes a bug in the repeated theorem instantiation detection.
3. Adds the macro `use [...]` as a shorthand for `instantiate only
[...]`.
2025-10-27 04:47:02 +00:00
Kim Morrison
30ecacd625 feat: add LawfulOfScientific class (#10971)
This PR adds a `LawfulOfScientific` class, providing compatibility with
a `Lean.Grind.Field` structure.
2025-10-27 04:18:55 +00:00
Kim Morrison
a0e742be5e chore: >6 month old deprecations (#10969) 2025-10-26 22:48:41 +00:00
Leonardo de Moura
50e2fdaa74 feat: add cdot combinator in grind tactic mode (#10975)
This PR adds the combinator ` · t_1 ... t_n` to the `grind` interactive
mode. The `finish?` tactic now generates scripts using this combinator
to conform to Mathlib coding standards. The new format is also more
compact. Example:
```lean
/--
info: Try this:
  [apply] ⏎
    instantiate only [= mem_indices_of_mem, insert, = getElem_def]
    instantiate only [= getElem?_neg, = getElem?_pos]
    cases #f590
    · cases #ffdf
      · instantiate only
        instantiate only [= Array.getElem_set]
      · instantiate only
        instantiate only [size, = HashMap.mem_insert, = HashMap.getElem_insert, = Array.getElem_push]
    · instantiate only [= mem_indices_of_mem, = getElem_def]
      instantiate only [usr getElem_indices_lt]
      instantiate only [size]
      cases #ffdf
      · instantiate only [=_ WF]
        instantiate only [= getElem?_neg, = getElem?_pos, = Array.getElem_set]
        instantiate only [WF']
      · instantiate only
        instantiate only [= HashMap.mem_insert, = HashMap.getElem_insert, = Array.getElem_push]
-/
#guard_msgs in
example (m : IndexMap α β) (a a' : α) (b : β) (h : a' ∈ m.insert a b) :
    (m.insert a b)[a'] = if h' : a' == a then b else m[a'] := by
  grind => finish?
```
2025-10-26 21:27:00 +00:00
Sebastian Ullrich
77ddfd49e6 chore: further shake improvements (#10947) 2025-10-26 11:27:19 +00:00
Kim Morrison
4887eeb77c chore: remove >6 month old deprecations (#10968) 2025-10-26 10:01:30 +00:00
Kim Morrison
9cf2877945 fix: mis-stated lemmas about empty raw maps (#10966)
This PR fixes some mis-stated lemmas which should have been about the
`.Raw` variants of maps.
2025-10-26 07:51:39 +00:00
Leonardo de Moura
97d63db52c fix: mbtc for nonlinear terms in grind cutsat (#10965)
This PR ensures that model-based theory combination in `grind cutsat`
considers nonlinear terms. Nonlinear multiplications such as `x * y` are
treated as uninterpreted symbols in `cutsat`.

Closes #10885
2025-10-26 04:35:34 +00:00
Leonardo de Moura
f8b0beeba9 fix: propagator for a^(n+m) in grind (#10964)
This PR adds a propagator for `a^(n+m)` and removes its normalizer. This
change was motivated by issue #10661

Closes #10661
2025-10-26 03:52:28 +00:00
Leonardo de Moura
93c5bd0fdd chore: use realizeGlobalConstNoOverloadWithInfo (#10963)
closes #10427
closes #10426
2025-10-26 02:45:46 +00:00
Leonardo de Moura
feb864712f fix: spurious warning message in grind (#10962)
This PR fixes a spurious warning message in `grind`.

Closes #10670
2025-10-26 02:40:12 +00:00
Leonardo de Moura
2f3211028b feat: support for Rat scientific literals (#10961)
This PR adds support for scientific literals for `Rat` in `grind`.
`grind` does not yet add support for this kind of literal in arbitrary
fields.

closes #10489
2025-10-26 02:05:26 +00:00
Leonardo de Moura
cdaa827b2a fix: grind linarith counterexample (#10960)
This PR fixes a bug in the `grind linarith` model/counterexample
construction.

Closes #10500
2025-10-26 00:27:47 +00:00
Kim Morrison
a9d6bc60d0 chore: update stage0 2025-10-26 10:29:47 +11:00
Kim Morrison
9166c71e08 feat: don't count symbols in instances and proofs 2025-10-26 10:29:47 +11:00
Kim Morrison
43b2d41e81 chore: add test file 2025-10-26 10:29:47 +11:00
Kim Morrison
e8620255a0 feat: symbol frequency environment extension 2025-10-26 10:29:47 +11:00
Leonardo de Moura
48f0eb206c test: rationals in grind linarith (#10958) 2025-10-25 21:48:43 +00:00
Leonardo de Moura
962e7d5a30 test: for #10317 (#10957)
This PR adds tests for issue that has been fixed by previous commits.

closes #10317
2025-10-25 21:42:56 +00:00
Leonardo de Moura
aa59c01742 fix: equality propagation in grind order (#10956)
This PR fixes a bug in the equality propagation procedure in
`grind.order`. Specifically, it affects the procedure that asserts
equalities in the `grind` core state that are implied by (ring)
inequalities in the `grind.order` module.

closes #10622
2025-10-25 20:12:04 +00:00
Leonardo de Moura
cd60d9c14a fix: grind order regression (#10955)
This PR fixes a regression in the `grind order` module introduced by

Closes #10953
2025-10-25 16:12:28 +00:00
Eric Wieser
b3ef7c9f25 chore: add an assertion about mkValueTypeClosure (#10954)
This is a guard against #10705; if a kernel error is raised when the
return value of this function is eventually checked, it is often
silenced downstream, making it hard to spot the failure.
If we panic here via `assert!`, then the diagnostic cannot be missed.
2025-10-25 12:59:17 +00:00
Lean stage0 autoupdater
be2c2bcf9b chore: update stage0 2025-10-25 11:32:01 +00:00
Leonardo de Moura
d5ca0c7032 fix: bug in cutsat model construction (#10951)
This PR fixes a bug in the `cutsat` incremental model construction. The
model was not being reset when new (unsatisfied) equalities were
asserted.
2025-10-25 04:16:32 +00:00
Leonardo de Moura
3c2ab0fefa feat: model-based theory combination tactic and action (#10950)
This PR adds the `mbtc` tactic to the `grind` interactive mode. It
implements model-based theory combination. It also ensures `finish?` is
capable of generating it.
2025-10-25 03:35:19 +00:00
Leonardo de Moura
1643fd7532 fix: finish? checks whether solver propagation steps are needed (#10949)
This PR ensures that solver propagation steps are necessary in the
generated tactic script to close the goal.

It produces more compact proof scripts, but this is not just an
optimization, if we include an unnecessary step, we may fail to replay
the generated script when `cases` steps are pruned using
non-chronological backtracking (NCB). For example, when executing
`finish?`, we may have performed a `cases #<anchor>` step that enabled
`ring` to propagate a new fact. If this fact is not used in the final
proof, and the corresponding `cases #<anchor>` step is pruned by NCB,
the `ring` step will fail during replay.
2025-10-25 02:27:44 +00:00
Leonardo de Moura
53442d48f5 feat: finish? produces partial tactic scripts with sorry (#10948)
This PR ensures that `finish?` produces partial tactic scripts
containing `sorry`s.
We may add an option to disable this feature in the future.
It is enabled by default because it provides a useful way to debug
`grind` failures.
2025-10-24 23:47:30 +00:00
Joachim Breitner
96bace56fa fix: run enableRealizationsForConst on sizeOf decls (#10944)
This PR runs enableRealizationsForConst on sizeOf declarations. Fixes
#10573.
2025-10-24 16:15:38 +00:00
Sebastian Ullrich
b0127e01e3 chore: final module system fixes and refinements for initial Mathlib porting (#10869) 2025-10-24 15:53:49 +00:00
Joachim Breitner
e71d0abc7d test: test case for #10775 (#10943) 2025-10-24 14:54:36 +00:00
Joachim Breitner
a6d50a61b3 fix: Meta.Closure: topologically sort abstracted vars (#10926)
This PR topologically sorts abstracted vars in
`Meta.Closure.mkValueTypeClosure` if MVars are being abstracted.
Fixes #10705

---------

Co-authored-by: Eric Wieser <efw@google.com>
2025-10-24 12:07:16 +00:00
Sebastian Ullrich
dec007693a chore: fix C++ warning (#10922) 2025-10-24 11:09:08 +00:00
Henrik Böving
1145498521 fix: regression from ST redefinition (#10940)
This PR fixes a regression introduced by the `ST` redefinition by making
the definition of `ST` as
reducible as previously. The key issue here is that in the previous
state it would reduce to a
function at which point the monad lifting mechanisms don't kick in in
the same fashion anymore.
2025-10-24 08:50:56 +00:00
Leonardo de Moura
2f07b70870 fix: default parameter value in constructor footgun at cases tactic (#10939)
This PR fixes another instance of the “default parameter value in
constructor” footgun, which was affecting the `cases` tactic in the
`grind` interactive mode.
2025-10-24 00:56:15 +00:00
Leonardo de Moura
09b36c332a fix: missing processNewFacts at solver tactics (#10938)
This PR ensures solver `grind` tactics (e.g., `ac`, `ring`, `lia`, etc)
process pending facts after making progress.
2025-10-24 00:08:06 +00:00
Leonardo de Moura
955fff52c5 fix: missing reset ematch.num at cases (#10937)
This PR fixes a missing counter reset at the `cases` tactic in `grind`
interactive mode.
2025-10-23 23:58:36 +00:00
Leonardo de Moura
6d665f3e91 fix: bugs at grind => finish? (#10936)
This PR fixes issues in `grind => finish?` that were preventing
generated `grind` tactic scripts from being successfully replayed.
2025-10-23 22:35:20 +00:00
Joachim Breitner
74fd46894f fix: deprecation warning location with field notation (#10826)
This PR fixes the location of the “deprecated constant” and similar
error messages on field notation (`e.f`, `(e).f`, `e |>. f`). Fixes
#10821.
2025-10-23 20:55:25 +00:00
Joachim Breitner
ffaadcc990 doc: warning for wf_preprocess (#10897)
This PR adds a warning to `wf_preproces` that these lemmas can be used
to introduce hidden partiality.

---------

Co-authored-by: Rob23oba <152706811+Rob23oba@users.noreply.github.com>
2025-10-23 20:54:40 +00:00
Joachim Breitner
54175f3b99 fix: decreasing_by: remove mdata (#10931)
This PR strips the `Expr.mdata` that `WF.Fix` uses to associate goal
with recursive calls from the goal presented to the tactics.
Fixes #10895.
2025-10-23 20:54:32 +00:00
Markus Himmel
59573646c2 chore: more minor String improvements (#10930)
This PR moves some more material out of `Init.Data.String.Basic` and
fixes the incorrect name
`String.Pos.Raw.IsValidForSlice.le_utf8ByteSize`.
2025-10-23 13:57:23 +00:00
Markus Himmel
ba7798b389 chore: more reorganization of strings (#10928)
This PR splits more material out of `Init.Data.String.Basic`.
2025-10-23 11:56:11 +00:00
Henrik Böving
f1203f3d0d perf: used hashmaps for symbol lookup in the interpreter (#10927)
This PR uses hashmaps for the symbol lookups in the IR interpreter
instead of the existing rbmaps.
Thus reducing the constant overhead per function call.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-10-23 11:45:20 +00:00
Henrik Böving
881a131ad3 chore: re-enable tests (#10923) 2025-10-23 08:38:57 +00:00
Lean stage0 autoupdater
fb3e2c15fd chore: update stage0 2025-10-23 08:03:18 +00:00
Rob23oba
fad0e69cc7 fix: make name mangling unambiguous (#10727)
This PR fixes name mangling to be unambiguous / injective by adding `00`
for disambiguation where necessary. Additionally, the inverse function,
`Lean.Name.unmangle` has been added which can be used to unmangle a
mangled identifier. This unmangler has been added to demonstrate the
injectivity but also to allow unmangling identifiers e.g. for debugging
purposes.

Closes #10724
2025-10-23 07:18:07 +00:00
Kim Morrison
cf22c367a1 feat: grind +premises (#10920)
This PR adds support for `grind +premises`, calling the currently
configured premise selection algorithm and including the results as
parameters to `grind`. (Recall that there is not currently a default
premise selector provided by Lean4: you need a downstream premise
selector to make use of this.)
2025-10-23 06:42:48 +00:00
Mac Malone
291d238ec4 test: symbol clash on private import of same def (#10915)
This PR adds a test for depending on two packages which privately import
modules that define the same Lean definition. It verifies the current
behavior of a symbol clash. This behavior will be fixed later this
quarter.
2025-10-23 03:42:52 +00:00
Kim Morrison
69e1eae480 feat: grind +lax ignores bad parameters (#10890)
This PR adds a `+lax` configuration option for `grind`, causing it to
ignore parameters referring to non-existent theorems, or to theorems for
which we can't generate a pattern. This allows throwing large sets of
theorems (e.g. from a premise selection enginre) into `grind` to see
what happens.
2025-10-23 03:19:31 +00:00
Leonardo de Moura
b1d4c9b9d5 feat: grind "silent" have (#10919)
This PR implements the `have <ident>? : <prop>` tactic for the `grind`
interactive mode. The proposition is proved using the default `grind`
search strategy. This tactic is also useful for inspecting or querying
the current `grind` state.
2025-10-23 02:36:49 +00:00
Leonardo de Moura
d748b0c8c9 feat: instantiate tactic parameter optimizer (#10916)
This PR implements parameter optimization for the generated
`instantiate` tactics produced by `finish?`.
We use a simple parameter optimizer that takes two sets as input: the
lower and upper bounds.
The lower bound consists of the theorems actually used in the proof
term, while the upper bound includes all the theorems instantiated in a
particular theorem instantiation step.
The lower bound is often sufficient to replay the proof, but in some
cases, additional theorems must be included because a theorem
instantiation may contribute to the proof by providing terms and many
not be present in the final proof term.
2025-10-23 01:22:33 +00:00
Kim Morrison
90af66d64b chore: minor changes to MePo (#10917)
This PR makes minor changes to the MePo premise selection algorithm.

I'm increasingly believing that MePo will not work well in Lean; I've
tried a few things without success. Alistair Geesing's thesis from 2023
had similar conclusions.

My intention is to reach the point we can properly benchmark premise
selection algorithms before doing any more work here.
2025-10-23 01:15:38 +00:00
Markus Himmel
3ce7d4ef5c chore: minor optimizations on the critical path (#10900)
This PR optimizes two `String` proofs and makes sure that
`MkIffOfInductiveProp` does not import `Lean.Elab.Tactic`, which
previously pushed it to the very end of the import graph.
2025-10-22 19:32:26 +00:00
Leonardo de Moura
63c06725bb feat: preserve instantiation order at finish? (#10899)
This PR ensures the generated `instantiate` tactic instantiates the
theorems using the same order used by `finish?`
2025-10-22 17:44:26 +00:00
Markus Himmel
b5dc11e8d3 chore: move some material out of Init.Data.String.Basic (#10893)
This PR splits some low-hanging fruit out of `Init.Data.String.Basic`:
basic material about `String.Pos.Raw`, `String.Substrig`, and
`String.Iterator`.

More splitting required and the remaining material is quite unorganized,
but it's a start.
2025-10-22 16:31:08 +00:00
Eric Wieser
08bc333705 perf: mark move constructors and assignment operators as noexcept (#10784)
Detected by
https://clang.llvm.org/extra/clang-tidy/checks/performance/noexcept-move-constructor.html.
This ensures constructions like `std::vector<object_ref>` call these
operators instead of the copy ones, and do not do extra refcounting.

Note that `optional` and `atomic` need something more complex using
`noexcept()`, as they are templated.
2025-10-22 14:21:51 +00:00
Henrik Böving
52b1b342ab feat: zero cost BaseIO (#10625)
This PR implements zero cost `BaseIO` by erasing the `IO.RealWorld`
parameter from argument lists and structures. This is a **major breaking
change for FFI**.

Concretely:
- `BaseIO` is defined in terms of `ST IO.RealWorld`
- `EIO` (and thus `IO`) is defined in terms of `EST IO.RealWorld`
- The opaque `Void` type is introduced and the trivial structure
optimization updated to account for it. Furthermore, arguments of type
`Void s` are removed from the argument lists of the C functions.
- `ST` is redefined as `Void s -> ST.Out s a` where `ST.Out` is a pair
of `Void s` and `a`

This together has the following major effects on our generated code:
- Functions that return `BaseIO`/`ST`/`EIO`/`IO`/`EST` now do not take
the dummy world parameter anymore. To account for this FFI code needs to
delete the dummy world parameter from the argument lists.
- Functions that return `BaseIO`/`ST` now return their wrapped value
directly. In particular `BaseIO UInt32` now returns a `uint32_t` instead
of a `lean_object*`. To account for this FFI code might have to change
the return type and does not need to call `lean_io_result_mk_ok` anymore
but can instead just `return` values right away (same with extracting
values from `BaseIO` computations.
- Functions that return `EIO`/`IO`/`EST` now only return the equivalent
of an `Except` node which reduces the allocation size. The
`lean_io_result_mk_ok`/`lean_io_result_mk_error` functions were updated
to account for this already so no change is required.

Besides improving performance by dropping allocation (sizes) we can now
also do fun new things such as:
```lean
@[extern "malloc"]
opaque malloc (size : USize) : BaseIO USize
```
2025-10-22 10:55:12 +02:00
Hikaru Hasegawa
6ee8511ae3 doc: fix example parenthesis in natAbs docstring (#10870)
This PR fixes an incorrect parenthesis in the `natAbs` docstring in
`src/Init/Data/Int/Basic.lean`.
2025-10-22 08:23:09 +00:00
Markus Himmel
6a1cc7d6b8 chore: minor String improvements (#10891)
This PR renames the cast functions on `String.ValidPos` for `set` and
`modify` to adhere to the established naming convention.

It also fixes two typos and very slighly tweaks the import graph,
shortening the critical path by a negligible amount.
2025-10-22 06:35:51 +00:00
Kim Morrison
2fb4d4bac2 chore: updates to release automation (#10888) 2025-10-22 03:17:28 +00:00
Leonardo de Moura
9b794befe0 feat: use new TermInfo.isDisplayableTerm when hovering grind anchors (#10887)
This PR uses the new `TermInfo.isDisplayableTerm` when hovering over
`cases` tactic anchors in the `grind` interactive mode.
2025-10-22 02:52:18 +00:00
Kim Morrison
38240612bc chore: add Rat.max_def lemma (#10886)
Closes #10842.
2025-10-22 00:38:52 +00:00
Mac Malone
3768c07654 fix: lake: cache revision path (#10883)
This PR fixes a bug with Lake's cache where revisions were stored at the
incorrect path. Revisions were stored at `<rev>/<pkg>.jsonl` rather than
the correct `<pkg>/<rev>.jsonl`.
2025-10-21 23:59:44 +00:00
Kim Morrison
466b0f824c chore: begin development cycle for v4.26 (#10884) 2025-10-21 23:22:58 +00:00
Kim Morrison
11eabdb000 chore: release_steps runs lake exe cache get when needed (#10882) 2025-10-21 22:49:38 +00:00
Leonardo de Moura
bd05f87d01 fix: grind proof instability (#10881)
This PR fixes a proof instability source in `grind`.

We say a proof is *unstable* if minor changes in the `.lean` file
containing the proof **affect** it.
2025-10-21 22:08:15 +00:00
Leonardo de Moura
56f3ca6fc7 fix: propagation in grind order (#10877)
This PR fixes theory propagation issue in `grind order`.
2025-10-21 16:38:39 +00:00
Sofia Rodrigues
94cb32bc46 fix: ipv4 address encoding from libuv to lean (#10854)
This PR fixes the IPv4 address encoding from libuv to lean
2025-10-21 14:17:22 +00:00
Leonardo de Moura
2f90b1dadd fix: elaborate grind state filter (#10874)
This PR uses the correct context for elaborating the `grind` state
filter.
2025-10-21 12:31:21 +00:00
Sebastian Graf
2991c66c81 chore: add missing spec lemmas for OptionT (#10867) 2025-10-21 12:01:35 +00:00
Eric Wieser
3f82b307aa fix: rule of 3 for xtimit (#10818)
This PR adds a missing move assignment operator, and deletes the copy
assignment operator.

C++ types should not implement move constructors without also
implementing move assignment. This also ensures that `m_fn` is correctly
emptied after a move, which is not guaranteed by the standard.

This change is also needed to allow `lean::optional` to be eventually
replaced by `std::optional`.
2025-10-21 12:01:23 +00:00
Sebastian Graf
bce47c6e0d fix: improve performance of mvcgen by optimizing try (mpure_intro; trivial) (#10872)
This PR improves the performance of `mvcgen` by an optimized
implementation for `try (mpure_intro; trivial)`. This tactic sequence is
used to eagerly discharge VCs and in the process instantiates schematic
variables.
2025-10-21 11:32:24 +00:00
Markus Himmel
b28daa6d60 chore: rename String.endPos -> String.rawEndPos (#10853)
This PR renames `String.endPos` to `String.rawEndPos`, as in a future
release the name `String.endPos` will be taken by the function that is
currently called `String.endValidPos`.
2025-10-21 11:25:30 +00:00
Markus Himmel
196d50156a fix: logic error in String.Slice.takeWhile (#10868)
This PR fixes a bug in `String.Slice.takeWhile` which caused it to get
its bookkeeping wrong and panic. The new version only uses safe
operations on `String.Slice.Pos`.
2025-10-21 09:52:11 +00:00
Sebastian Graf
2eb44b3cdc chore: fix a typo in the docstring for SeqRight and add documentation to getLevel (#10866) 2025-10-21 09:07:24 +00:00
Sebastian Graf
916125ae1c fix: make Std.Do.Spec.forIn'_list and friends more universe polymorphic (#10865)
This PR makes the spec `Std.Do.Spec.forIn'_list` and friends more
universe polymorphic.

The regression test came from a dicussion on the public Zulip.
2025-10-21 09:04:52 +00:00
Henrik Böving
bd0b91de07 perf: reduce amount of symbols in DLLs (#10864)
This PR reduces the amount of symbols in our DLLs by cutting open a
linking cycle of the shape:

`Environment -> Compiler -> Meta -> Environment`

This is achieved by introducing a dynamic call to the compiler hidden
behind a `Ref` as previously
done in the pretty printer.
2025-10-21 09:00:56 +00:00
Sebastian Ullrich
37b78bd53d chore: more module system fixes and refinements for finishing batteries port (#10819) 2025-10-21 08:19:50 +00:00
Marc Huisinga
2e3d947e07 feat: flag on TermInfo to force rendering of term in hover (#10805)
This PR adds a field `isDisplayableTerm` to `TermInfo` and all utility
functions which create `TermInfo` that can be set to force the language
server to render the term in hover popups.
2025-10-21 08:19:20 +00:00
Markus Himmel
a5a8f2779c chore: rename String.Range to Lean.Syntax.Range (#10852)
This PR renames `String.Range` to `Lean.Syntax.Range`, to reflect that
it is not part of the standard library.
2025-10-21 07:32:25 +00:00
Mac Malone
efbbb0b230 fix: lake: recurse directories in input_dir (#10861)
This PR fixes `input_dir` tracking to also recurse through
subdirectories. The `filter` of an `input_dir` will be applied to each
file in the directory tree (the path names of directories will not be
checked).

Closes #10827.
2025-10-21 04:19:10 +00:00
Leonardo de Moura
a366cbcd20 feat: show_term for grind interactive mode (#10862)
This PR implements the `show_term` combinator in `grind` interactive
mode.
2025-10-21 02:30:16 +00:00
Kim Morrison
756fee3e96 feat: improvements to release automation for v4.25.0-rc1 (#10860)
This PR improves the release automation. We link to CI output for
building the release tag, don't give instructions for bumping downstream
repositories until the release it ready, and improve documentation and
prompts.
2025-10-21 00:59:44 +00:00
Leonardo de Moura
2ead798d87 fix: set_option auto-completion in grind mode (#10859)
This PR fixes auto-completion for `set_option` in `grind` interactive
mode.
2025-10-21 00:53:35 +00:00
Leonardo de Moura
baacf86e7f feat: improve done tactic in grind interactive mode (#10858)
This PR improves the `done` tactic in `grind` interactive mode. It now
displays the `grind` state diagnostics for all unsolved subgoals.
2025-10-21 00:25:40 +00:00
Joachim Breitner
e3a5369bd7 perf: match compilation to use exfalso early (#10851)
This PR lets match compilation use exfalso as soon as no alternatives
are left. This way, the compiler does not have to look at subsequent
case splits.
2025-10-20 12:23:23 +00:00
Markus Himmel
c981ebc546 feat: split and splitInclusive iterators are finite (#10820)
This PR shows that the iterators returned by `String.Slice.split` and
`String.Slice.splitInclusive` are finite as long as the forward matcher
iterator for the pattern is finite (which we already know for all of our
patterns).

At actually also completely redefines the iterators to avoid the inner
loop in `Internal.nextMatch` which generates inefficient code. Instead,
when encountering a mismach from the matcher, we `skip` the split
iterator.
2025-10-20 10:21:21 +00:00
Paul Reichert
71f1a6c164 feat: Iterator find? consumer and variants (#10769)
This PR adds a `find?` consumer in analogy to `List.find?` and variants
thereof.
2025-10-20 09:12:53 +00:00
Sebastian Ullrich
0d5869bb71 fix: stuck "Missing alternative name" with incremental processing (#10848)
This PR fixes an issue where adding a missing case name after the pipe
in `induction` would not remove the now-obsolete error message.

Fixes #10847
2025-10-20 08:00:48 +00:00
Leonardo de Moura
135e7e7bd3 fix: instance tactic generation at finish? (#10846)
This PR fixes a few issues on `instance only [...]` tactic generation at
`finish?`.
2025-10-20 03:10:38 +00:00
Kim Morrison
58a884ef06 chore: update actions/checkout action in lake new template (#10845)
This PR update the `lake new` template to use the current version of the
`actions/checkout` Github workflow.
2025-10-20 02:32:52 +00:00
Kim Morrison
77e72afe0a chore: tweak error message about weak options (#10844)
This PR tweaks the error message about options defined in libraries.
This was relevant for an option defined in Mathlib, but set in FLT.
2025-10-20 02:28:20 +00:00
Leonardo de Moura
823671f744 feat: set_option tactic in grind interactive mode (#10843)
This PR implements the `set_option` tactic in `grind` interactive mode.
2025-10-20 00:44:59 +00:00
Leonardo de Moura
681724a8cf feat: generate instantiate only [...] at finish? (#10841)
This PR improves the `grind` tactic generated by the `instantiate`
action in tracing mode. It also updates the syntax for the `instantiate`
tactic, making it similar to `simp`. For example:

* `instantiate only [thm1, thm2]` instantiates only theorems `thm1` and
`thm2`.
* `instantiate [thm1, thm2]` instantiates theorems marked with the
`@[grind]` attribute **and** theorems `thm1` and `thm2`.

The action produces `instantiate only [...]` tactics. Example:

```lean
/--
info: Try this:
  [apply] ⏎
    instantiate only [= Array.getElem_set]
    instantiate only [= Array.getElem_set]
-/
#guard_msgs in
example (as bs cs : Array α) (v₁ v₂ : α)
        (i₁ i₂ j : Nat)
        (h₁ : i₁ < as.size)
        (h₂ : bs = as.set i₁ v₁)
        (h₃ : i₂ < bs.size)
        (h₄ : cs = bs.set i₂ v₂)
        (h₅ : i₁ ≠ j ∧ i₂ ≠ j)
        (h₆ : j < cs.size)
        (h₇ : j < as.size) :
    cs[j] = as[j] := by
  grind => finish?
```

Recall that `finish?` replays generated tactics before suggesting them.

The `instantiate` action inspects the generated proof term to decide
which theorems to include as parameters in the `instantiate only [...]`
tactic. However, in some cases, a theorem contributes only by adding a
term to the state. In such cases, the generated tactic cannot be fully
replayed, and the action uses
`instantiate approx [<thms instantiated>]` to indicate which parts of
the tactic script are approximate. The `approx` is just a hint for
users.
2025-10-19 23:35:27 +00:00
Lean stage0 autoupdater
28dd72d514 chore: update stage0 2025-10-19 23:45:51 +00:00
Leonardo de Moura
61ee3b2711 feat: expose optionValue parser (#10839)
This PR exposes the `optionValue` parser used to implement the
`set_option` notation.
2025-10-19 22:57:47 +00:00
Leonardo de Moura
206eb73cd9 feat: finish? tactic for grind interactive mode (#10837)
This PR implements the `finish?` tactic for the `grind` interactive
mode. When it successfully closes the goal, it produces a code action
that allows the user to close the goal using explicit grind tactic
steps, i.e., without any search. It also makes explicit which solvers
have been used.

This is just the first version, we will add many "bells and whistles"
later. For example, `instantiate` steps will clearly show which theorems
have been instantiated.

Example:

```lean
/--
info: Try this:
  [apply] ⏎
    cases #b0f4
    next => cases #50fc
    next => cases #50fc <;> lia
-/
#guard_msgs in
example (p : Nat → Prop) (x y z w : Int) :
    (x = 1 ∨ x = 2) →
    (w = 1 ∨ w = 4) →
    (y = 1 ∨ (∃ x : Nat, y = 3 - x ∧ p x)) →
    (z = 1 ∨ z = 0) → x + y ≤ 6 := by
  grind => finish?
```

The anchors in the generated script are based on stable hash codes.
Moreover, users can hover over them to see the exact term used in the
case split. `grind?` will also be implemented using the new framework.
2025-10-19 03:52:32 +00:00
Leonardo de Moura
09f22203f8 feat: add SolverExtension.action and Solvers.mkAction (#10836)
This PR implements support for `Action` in the `grind` solver extensions
(`SolverExtension`). It also provides the `Solvers.mkAction` function
that constructs an `Action` using all registered solvers. The generated
action is "fair," that is, a solver cannot prevent other solvers from
making progress.
2025-10-19 00:53:45 +00:00
Leonardo de Moura
ef23782608 feat: ring action (#10834)
This PR implements the `ring` action for `grind`.
2025-10-18 22:01:51 +00:00
Leonardo de Moura
e2b5747f4b feat: evalTactic in GrindM (#10833)
This PR implements infrastructure for evaluating `grind` tactics in the
`GrindM` monad. We are going to use it to check whether auto-generated
tactics can effectively close the original goal.
2025-10-18 17:02:36 +00:00
Markus Himmel
dad541265c refactor: move operations on String.Pos.Raw to the String.Pos.Raw namespace (#10735)
This PR moves many operations involving `String.Pos.Raw` to a the
`String.Pos.Raw` namespace with the eventual aim of freeing up the
`String` namespace to contain operations using `String.ValidPos` (to be
renamed to `String.Pos`) instead.

This PR adds the `String.ValidPos.set` and `String.ValidPos.modify`
functions.

After this PR, `String.pos_lt_eq` is no longer a `simp` lemma. Add
`String.Pos.Raw.lt_iff` as a `simp` lemma if your proofs break.
2025-10-18 12:12:55 +00:00
Markus Himmel
ca7a8e18b7 refactor: rename String.split to String.splitToList (#10822)
This PR renames `String.split` to `String.splitToList`, because soon the
name `String.split` will be used by a new implementation which is
superior because it is polymorphic over the pattern kind and it returns
an iterator of slices instead of a list of strings.
2025-10-18 12:12:54 +00:00
Sebastian Ullrich
721ffe5713 chore: CI: disable tree-less clone on nightly release 2025-10-18 13:32:04 +02:00
Leonardo de Moura
c76411d6c5 feat: compact notation for inspecting grind state (#10828)
This PR implements a compact notation for inspecting the `grind` state
in interactive mode. Within a `grind` tactic block, each tactic may
optionally have a suffix of the form `| filter?`.

Examples:

```lean
instantiate | gen > 0  -- Displays terms in the `grind` state after executing `instantiate` with generation greater than zero
```

```lean
instantiate |  -- Displays the `grind` state after executing `instantiate`
```

Remark: If the user places the cursor one space before `|`, the state
*before* executing `instantiate` is displayed.
This PR removes the code that was silently displaying the `grind` state
after each tactic step, as it was too noisy.
It also updates the notation for the `first` combinator in the `grind`
tactic mode to avoid conflicts with the new syntax.
2025-10-17 19:54:23 +00:00
Joachim Breitner
c22100036c fix: more pedantic checking of inaccessible patterns (#10796)
This PR changes match compilation to reject some pattern matches that
were previously accepted due to inaccessible patterns sometimes treated
like accessible ones. Fixes #10794.
2025-10-17 17:02:54 +00:00
Sebastian Ullrich
5800ce17b3 chore: CI: upgrade all git checkouts to tree-less clones (#10814) 2025-10-17 16:23:42 +00:00
Leonardo de Moura
78ab60d045 feat: cases? tactic for grind interactive mode (#10824)
This PR implements the `cases?` tactic for the `grind` interactive mode.
It provides a convenient way to select anchors. Users can filter the
candidates using the filter language. Examples:

<img width="1454" height="399" alt="image"
src="https://github.com/user-attachments/assets/fc370c2e-97f9-4d68-93a6-f0ebf33499f8"
/>

<img width="1447" height="166" alt="image"
src="https://github.com/user-attachments/assets/6c9c3707-79f7-4c63-8007-8d0aaedecc45"
/>
2025-10-17 15:44:19 +00:00
Sofia Rodrigues
f9adafe54d feat: adds acceptSelector and modified selectors (#10667)
This PR adds more selectors for TCP and Signals.

It also fixes a problem with `Selectors` that they cannot be closures
over a promise, otherwise it causes the waiter promise to never be
dropped.
2025-10-17 14:53:46 +00:00
Sebastian Ullrich
69d8d63d58 feat: hint about inaccessible private declaration on dot notation failure (#10803)
This PR improves the error message of generalized field notation if the
issue is that the resolved declaration is not visible in the current
context.
2025-10-17 09:31:56 +00:00
Sebastian Ullrich
dc7c184ee2 chore: CI: introduce fast-ci label 2025-10-17 08:45:41 +02:00
Sebastian Ullrich
e43ff50e76 chore: CI: revert macOS tests accidentally run on PRs 2025-10-17 08:45:41 +02:00
Leonardo de Moura
4ce7ad19ce feat: lia, linarith, and ac actions (#10812)
This PR implements `lia`, `linarith`, and `ac` actions for `grind`
interactive mode.
2025-10-17 03:56:21 +00:00
Leonardo de Moura
2a70da50c1 feat: proper case-split anchor generation in splitNext for grind? and finish? (#10811)
This PR implements proper case-split anchor generation in the
`splitNext` action, which will be used to implement `grind?` and
`finish?`.
2025-10-17 03:07:13 +00:00
Kim Morrison
effde06296 chore: add public modifiers in Lean.Elab.Tactic.Induction (#10810) 2025-10-16 21:52:02 +00:00
Kim Morrison
127fe785a3 chore: add public modifiers in Lean.Elab.Tactic.Ext (#10809)
This PR restores further definitions to `public`, after #10699.
2025-10-16 21:48:41 +00:00
Sebastian Ullrich
663df8f7e8 feat: backward.privateInPublic option (#10807)
This PR introduces the `backward.privateInPublic` option to aid in
porting projects to the module system by temporarily allowing access to
private declarations from the public scope, even across modules. A
warning will be generated by such accesses unless
`backward.privateInPublic.warn` is disabled.
2025-10-16 20:51:45 +00:00
Sebastian Ullrich
428355cf02 chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
Sebastian Ullrich
83126883d9 chore: CI: overhaul check level logic (#10806)
The logic was *still* wrong after two PRs so let's get rid of
`check-level` as a matrix entry and trust in simple bools.
2025-10-16 20:27:02 +00:00
Sebastian Ullrich
5c7b003191 chore: lean.code-workspace: fix terminal cwd (#10802) 2025-10-16 20:19:12 +00:00
Leonardo de Moura
8a1b6e0f71 feat: compress generated grind tactic sequences using <;> (#10808)
This PR implements support for compressing auto-generated `grind` tactic
sequences.
2025-10-16 18:14:33 +00:00
Leonardo de Moura
7087c4a039 feat: add splitNext grind action (#10801)
This PR implements the `splitNext` action for `grind`.
2025-10-16 17:28:14 +00:00
Rob23oba
b7ea66d8d3 fix: consider underscores in getHexNumSize (#10719)
This PR fixes `getHexNumSize` to consider underscores. Previously, only
the amount of bytes was counted, making it output 9 for `1234_abcd`
instead of the actual number of digits, which is 8.
2025-10-16 13:57:58 +00:00
Joachim Breitner
10d6232594 chore: remove test for #10766 (#10804)
the tested situation (kernel runs into deep recursion but elaborator is
happy) is not very stable and depends on, for example, stack size. This
test is not worth that hassle.
2025-10-16 11:11:29 +00:00
Wojciech Różowski
5b35d6192c feat: redefine HashSet.union and add lemmas (#10611)
This PR adds adds union operation on `DHashMap`/`HashMap`/`HashSet` and
their raw variants and provides lemmas about union operations.

---------

Co-authored-by: Paul-Lez <paul.lezeau@gmail.com>
Co-authored-by: Markus Himmel <markus@lean-fro.org>
Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
2025-10-16 08:43:01 +00:00
Joachim Breitner
8748031853 fix: only run processInaccessibleAsCtor if there is at least one constructor around (#10793)
This PR fixes #10792.
2025-10-16 08:20:55 +00:00
Marc Huisinga
ac499323af chore: add .vscode/settings.json to .gitignore (#10795)
This PR adds `.vscode/settings.json` to our `.gitignore`, which allows
Lean 4 developers to set local workspace settings. We already use the
the workspace file for settings in core, so this shouldn't cause any
problems.
2025-10-16 07:08:41 +00:00
Kim Morrison
def3c97dbf chore: make extCore and customEliminators public for Batteries (#10799)
This PR restores two declarations to `public`, that were made non-public
in #10699, apparently breaking Batteries.
2025-10-16 05:01:23 +00:00
Kim Morrison
8db3969f87 chore: remove bad grind _=_ annotation on List.contains_iff_mem (#10800) 2025-10-16 04:00:42 +00:00
Leonardo de Moura
2f93363752 feat: intro and assertAll as actions (#10798)
This PR implements the `grind` actions `intro`, `intros`, `assertNext`,
`assertAll`.
2025-10-15 19:47:48 +00:00
Marc Huisinga
4329eae8d4 fix: unknown identifier minimization (#10797)
This PR fixes a bug in the unknown identifier code actions where the
identifiers wouldn't be correctly minimized in nested namespaces. It
also fixes a bug where identifiers would sometimes be minimized to
`[anonymous]`.

The first bug was introduced in #10619.
2025-10-15 19:25:27 +00:00
Leonardo de Moura
114f7e42f1 feat: lazy message with grind state (#10791)
This PR adds a silent info message with the `grind` state in its
interactive mode. The message is shown only when there is exactly one
goal in the grind interactive mode. The condition is a workaround for
current limitations of our `InfoTree`.
2025-10-15 15:03:07 +00:00
Sebastian Ullrich
419982bd42 chore: even more module system fixes and refinements from Mathlib porting (#10726) 2025-10-15 14:59:09 +00:00
Joachim Breitner
8431088c93 fix: preserve error locations when expanding match arms (#10783)
This PR ensures that error messages such as “redundant alternative” have
the right error location even if the arms share their RHS. Fixes #10781.
2025-10-15 13:31:42 +00:00
Sebastian Ullrich
803ec8ff9d chore: CI: re-enable mistakenly deactivated tests for Linux Lake (#10788) 2025-10-15 13:20:26 +00:00
Sebastian Ullrich
c4747752fe fix: detect private references in inferred type of public def (#10762)
This PR fixes an inconsistency in the module system around defs with
elided types.
2025-10-15 12:51:54 +00:00
Joachim Breitner
ed4d453346 refactor: processLeaf: Only look at first alt (#10774)
This PR lets match compilation look only at the first remaining
alternative in `processLeaf`. At this point we have no further variables
we can split on, so if the first one isn’t applicable, match compilation
should fail.
2025-10-15 10:10:52 +00:00
David Thrane Christiansen
45df6fcd37 fix: hovers and docstrings for (co)inductive types (#10738)
This PR fixes a regression introduced by #10307, where hovering the name
of an inductive type or constructor in its own declaration didn't show
the docstring. In the process, a bug in docstring handling for
coinductive types was discovered and also fixed. Tests are added to
prevent the regression from repeating in the future.
2025-10-15 09:32:11 +00:00
Sebastian Graf
4077bf2c05 feat: implement mvcgen?, expanding to mvcgen invariants? (#10782)
This PR implements a hint tactic `mvcgen?`, expanding to `mvcgen
invariants?`

Example:
```
/--
info: Try this:
  [apply] mvcgen invariants?
---
info: Try this:
  [apply] mvcgen [mySum] invariants?
---
info: Try this:
  [apply] mvcgen +elimLets invariants?
---
info: Try this:
  [apply] mvcgen +elimLets [mySum] invariants?
-/
#guard_msgs (info) in
theorem mySum_suggest_invariant_short (l : List Nat) : mySum l = l.sum := by
  generalize h : mySum l = r
  apply Id.of_wp_run_eq h
  mvcgen?
  mvcgen? [mySum]
  mvcgen? +elimLets
  mvcgen? +elimLets [mySum]
  all_goals admit
```
2025-10-15 08:22:09 +00:00
Joachim Breitner
54a3fbf88f fix: improve error message when decide +kernel fails (#10780)
This PR improves the error message when `decide +kernel` fails in the
kernel, but not the elaborator. Fixes #10766.
2025-10-15 07:11:27 +00:00
Leonardo de Moura
746206c5e6 feat: hover information for grind anchors (#10779)
This PR implements hover information for `grind` anchors. Anchors are
stable hash codes for referencing terms in the grind state. The anchors
will be used when auto generating tactic scripts. The hover display the
following information:

1- In the `instantiate` tactic, it displays the type of the theorem
being instantiated.
<img width="952" height="125" alt="image"
src="https://github.com/user-attachments/assets/be949b87-cf9b-4f75-abe0-17751295de93"
/>

2- In the `cases` tactic, the hover information depends on the kind of
case-split.
  a) Proposition
<img width="1019" height="125" alt="image"
src="https://github.com/user-attachments/assets/253e2927-f18e-49ab-a8fc-2144657406d8"
/>

b) A hypotheses. In this case, you can opt to replace the anchor with
the hypothesis' name if it is accessible.
<img width="1019" height="178" alt="image"
src="https://github.com/user-attachments/assets/858b3751-4ef9-492d-a42f-c0743753a7de"
/>

c) A term. The hover displays just the type, by `grind` logs a silent
information with additional information
  
<img width="1376" height="148" alt="image"
src="https://github.com/user-attachments/assets/30078ca4-a886-49d9-912e-866f3567b0da"
/>
2025-10-15 02:43:11 +00:00
Leonardo de Moura
88141a0a49 feat: hygiene for grind interactive mode (#10778)
This PR ensures that `grind` interactive mode is hygienic. It also adds
tactics for renaming inaccessible names: `rename_i h_1 ... h_n` and
`next h_1 ... h_n => ..`, and `expose_names` for automatically generated
tactic scripts. The PR also adds helper functions for implementing
case-split actions.
2025-10-15 01:27:51 +00:00
Kim Morrison
b17afe0f06 feat: improvements to release automation (#10777)
This PR improves the scripts assisting with cutting Lean releases (by
reporting CI status of open PRs, and adding documentation), and adds a
`.claude/commands/release.md` prompt file so Claude can assist.
2025-10-15 00:28:26 +00:00
Paul Reichert
7632cefa87 feat: hash map iterators (#10761)
This PR provides iterators on hash maps.
2025-10-14 15:10:01 +00:00
Paul Reichert
7a47bfa208 feat: flatMap iterator combinator (#10728)
This PR introduces the `flatMap` iterator combinator. It also adds
lemmas relating `flatMap` to `toList` and `toArray`.
2025-10-14 12:50:54 +00:00
Sebastian Ullrich
ae6335f115 chore: demote Intel macOS to Tier 2 platform (#10770) 2025-10-14 12:10:06 +00:00
Paul Reichert
f58999a7a6 refactor: use Shrink stub in the iterator framework (#10725)
This PR introduces a no-op version of `Shrink`, a type that should allow
shrinking small types into smaller universes given a proof that the type
is small enough, and uses it in the iterator library. Because this type
would require special compiler support, the current version is just a
wrapper around the inner type so that the wrapper is equivalent, but not
definitionally equivalent.

While `Shrink` is unable to shrink universes right now, but introducing
it now will allow us to generalize the universes in the iterator library
with fewer breaking changes as soon as an actual `Shrink` is possible.
2025-10-14 10:22:14 +00:00
Lean stage0 autoupdater
888b59bf95 chore: update stage0 2025-10-14 08:04:41 +00:00
Markus Himmel
1dae353575 chore: duplicate some String functions ahead of deprecation (#10768)
This PR is split off from #10735 for boring bootstrapping reasons.
2025-10-14 07:36:05 +00:00
Leonardo de Moura
a4b788c332 feat: add Grind/Action.lean (#10767)
This PR implements the new control interface for implementing `grind`
search strategies. It will replace the `SearchM` framework.
2025-10-14 03:21:51 +00:00
Sebastian Ullrich
5865c41a76 chore: lean.code-workspace: always open terminal in root folder (#10745) 2025-10-13 14:12:35 +00:00
Marc Huisinga
4b0e8d88ce fix: don't display CSS color picker in Lean files in VS Code (#10757)
This PR fixes a bug in combination with VS Code where Lean code that
looks like CSS color codes would display a color picker decoration.

VS Code displays this decoration by default for all languages, not just
CSS. Due to https://github.com/microsoft/vscode/issues/91533, this
setting cannot be disabled in the client on a per-language basis.
However, we can override the default behavior by providing a color
provider of our own. This PR implements an empty color provider to
override the VS Code one.
2025-10-13 13:39:16 +00:00
Marc Huisinga
9d427fdfcf feat: "try this" messages with support for interactivity (#10524)
This PR adds support for interactivity to the combined "try this"
messages that were introduced in #9966. In doing so, it moves the link
to apply a suggestion to a separate `[apply]` button in front of the
suggestion. Hints with diffs remain unchanged, as they did not
previously support interacting with terms in the diff, either.

<img width="379" height="256" alt="Suggestion with interactive message"
src="https://github.com/user-attachments/assets/7838ebf6-0613-46e7-bc88-468a05acbf51"
/>
2025-10-13 13:39:03 +00:00
Kim Morrison
fe1e7d56f4 chore: restore #8656 (#10758)
This PR restores the change in #8656, which removed `autoImplicit =
false` from the default lake template (per previous discussions linked
there). This was accidentally reverted in #8866.
2025-10-13 10:34:01 +00:00
Markus Himmel
fbe98d76b2 fix: turn meta import into import in Init.Data.ToString (#10754)
This PR makes sure that we always properly import
`Init.Data.ToString.Name` when importing `Init`.
2025-10-13 09:20:48 +00:00
Joachim Breitner
9a5e425990 refactor: no public section in Elab.Induction (#10699)
This PR removes `public section` in `Elab.Induction`.
2025-10-13 09:02:36 +00:00
Leonardo de Moura
14ff08db6f feat: repeat tactical for grind interactive mode (#10748)
This PR implements the `repeat` tactical for the `grind` interactive
mode.
2025-10-12 22:05:58 +00:00
Sebastian Ullrich
316859e871 perf: reset InfoState.lazyAssignment before each command (#10744)
This PR fixes a performance regression introduced in #10518. More
generally, it ensures both message log and info state are per-command,
which has been the case in practice ever since the asynchronous language
driver was introduced.
2025-10-12 09:27:14 +00:00
Leonardo de Moura
47dbcd4b93 feat: finish? and grind? infrastructure (#10747)
This PR implements infrastructure for `finish?` and `grind?` tactics.
2025-10-12 02:48:16 +00:00
Leonardo de Moura
4f7d3bb692 feat: instantiate tactic parameters (#10746)
This PR implements parameters for the `instantiate` tactic in the
`grind` interactive mode. Users can now select both global and local
theorems. Local theorems are selected using anchors. It also adds the
`show_thms` tactic for displaying local theorems. Example:

```lean
example (as bs cs : Array α) (v₁ v₂ : α)
        (i₁ i₂ j : Nat)
        (h₁ : i₁ < as.size)
        (h₂ : bs = as.set i₁ v₁)
        (h₃ : i₂ < bs.size)
        (h₃ : cs = bs.set i₂ v₂)
        (h₄ : i₁ ≠ j ∧ i₂ ≠ j)
        (h₅ : j < cs.size)
        (h₆ : j < as.size)
        : cs[j] = as[j] := by
  grind =>
    instantiate = Array.getElem_set
    instantiate Array.getElem_set
```
2025-10-11 21:35:21 +00:00
Lean stage0 autoupdater
0dc862e3ed chore: update stage0 2025-10-11 05:57:21 +00:00
Mac Malone
d9ee24bf36 fix: lake: local cache w/ --old (#10741)
This PR fixes a bug where partially up-to-date files built with `--old`
could be stored in the cache as fully up-to-date. Such files are no
longer cached. In addition, builds without traces now only perform an
modification time check with `--old`. Otherwise, they are considered
out-of-date.
2025-10-11 02:20:31 +00:00
Mac Malone
0639d49a4c feat: scope output cache by platform & toolchain (#10730)
This PR changes the Lake's remote cache interface to scope cache outputs
by toolchain and/or platform were useful.

Packages that set `platformIndependent = true` will not be scoped by
platform and the core build (i.e., `bootstrap = true`) will not be
scoped by toolchain. Lake's detected platform and toolchain can be
overridden with the new `--platform` and `--toolchain` options to `cache
get` and `cache put`.

Lake no longer accepts the `--scope` option when using `cache get` with
Reservoir.. The `--repo` option must be used instead.
2025-10-11 02:17:39 +00:00
Lean stage0 autoupdater
3a26eb7281 chore: update stage0 2025-10-10 22:22:55 +00:00
Joachim Breitner
830be29422 feat: generate equational theorems uniformly (#10734)
This PR follows upon #10606 and creates equational theorems uniformly
from the unfold theorem, there is only one handler registered in
`registerGetEqnsFn`.

For now we keep `registerGetEqnsFn`, because it’s used by mathlib’s
`irreducible_def`, but I’d like to get rid of it in the long term,
relying only on `registerGetUnfoldEqnFn` for constructions that should
unfold differently.
2025-10-10 21:35:09 +00:00
Leonardo de Moura
2a8c03109a feat: improve ac, linarith, lia, and ring in grind interactive mode (#10740)
This PR improves the tactics `ac`, `linarith`, `lia`, `ring` tactics in
`grind` interactive mode. They now fail if no progress has been made.
They also generate an info message with counterexample/basis if the goal
was not closed.
2025-10-10 21:04:26 +00:00
Leonardo de Moura
07f8ab533c feat: add tactics to grind interactive mode (#10737)
This PR adds the tactics `linarith`, `ac`, `fail`, `first`, `try`,
`fail_if_success`, and `admit` to `grind` interactive mode.
2025-10-10 20:24:07 +00:00
Paul Reichert
a73ebe8a77 feat: any/all predicates for iterators (#10686)
This PR introduces `any`, `anyM`, `all` and `allM` for pure and monadic
iterators. It also provides lemmas about them.
2025-10-10 19:24:10 +00:00
Paul Reichert
3931a72573 feat: SInt ranges (#10633)
This PR provides range support for the signed finite number types
`Int{8,16,32,64}` and `ISize`. The proof obligations are handled by
reducing all of them to proofs about an internal `UpwardEnumerable`
instance for `BitVec` interpreted as signed numbers.
2025-10-10 17:07:20 +00:00
Wojciech Różowski
bf809b5298 chore: change the location of error message for coinductive predicates (#10722)
This PR changes where errors are displayed when trying to use
`coinductive` keyword when targeting things that do not live in `Prop`.
Instead of displaying the error above the first element of the mutual
block, it is displayed above the erroneous definition.

---------

Co-authored-by: Rob23oba <152706811+Rob23oba@users.noreply.github.com>
2025-10-10 16:06:18 +00:00
Joachim Breitner
4b6f07060d feat: remove support for reducible well-founded recursion (#10714)
This PR removes support for reducible well-founded recursion, a Breaking
Change. Using `@[semireducible]` on a definition by well-founded
recursion prints a warning that this is no longer effective.

With the upcoming module system, proofs are often not available. With
this change, we remove a fringe use case hat may require proofs, and
that would not be supported under the module system anyways.

At least for now, direct use of `WellFounded.fix` is not affected.

This fixes: #5192
2025-10-10 15:48:28 +00:00
David Thrane Christiansen
09092549d0 fix: Verso docstring semantic highlighting fixes (#10662)
This PR re-enables semantic tokens for Verso docstrings, after a prior
change accidentally disabled them. It also adds a test to prevent this
from happening again.

In the process, it became clear that there was a bug. The highlighting
strategy led to overlapping but not identical tokens, but the code had
previously assumed that this couldn't happen at the delta-encoding step.
So this PR additionally replaces the removal of duplicate tokens with
priority-based handling of overlapping tokens.

---------

Co-authored-by: Marc Huisinga <mhuisi@protonmail.com>
2025-10-10 11:57:02 +00:00
Joachim Breitner
1b4360c32a fix: unfold more auxillary theorems in termination checking (#10733)
This PR unfolds auxillary theorems more aggressively during termination
checking. This fixes #10721.
2025-10-10 11:09:28 +00:00
Cameron Zwarich
705dac4f77 chore: make @hargoniX code owner of the compiler (#10732) 2025-10-10 04:43:38 +00:00
Leonardo de Moura
3bab621364 feat: add grind interactive mode tactics (#10731)
This PR adds the following tactics to the `grind` interactive mode:
- `focus <grind_tac_seq>`
- `next => <grind_tac_seq>`
- `any_goals <grind_tac_seq>`
- `all_goals <grind_tac_seq>`
- `grind_tac <;> grind_tac`
- `cases <anchor>`
- `tactic => <tac_seq>`

Example:
```lean
def g (as : List Nat) :=
  match as with
  | []      => 1
  | [_]     => 2
  | _::_::_ => 3

example : g bs = 1 → g as ≠ 0 := by
  grind [g.eq_def] =>
    instantiate
    cases #ec88
    next => instantiate
    next => finish
    tactic =>
      rw [h_2] at h_1
      simp [g] at h_1
```
2025-10-10 01:17:37 +00:00
Sebastian Ullrich
526ab9caff feat: Verso and Shake (#10657)
This PR ensures Shake does not remove any imports required by Verso
docstrings
2025-10-09 16:40:29 +00:00
Rob23oba
71ddf227d2 doc: add a recommended spelling for HEq (#10717)
This PR adds a recommended spelling for heterogenous equality (`HEq`,
`≍`).
2025-10-09 10:10:23 +00:00
Markus Himmel
dca8d6d188 refactor: discipline around arithmetic of String.Pos.Raw (#10713)
This PR enforces rules around arithmetic of `String.Pos.Raw`.

Specifically, it adopts the following conventions:

- Byte indices ("ordinals") in strings should be represented using
`String.Pos.Raw`
- Amounts of bytes ("cardinals") in strings should be represented using
`Nat`.

For example, `String.Slice.utf8ByteSize` now returns `Nat` instead of
`String.Pos.Raw`, and there is a new function `String.Slice.rawEndPos`.

Finally, the `HAdd` and `HSub` instances for `String.Pos.Raw` are
reorganized. This is a **breaking change**.

The `HAdd/HSub String.Pos.Raw String.Pos.Raw String.Pos.Raw` instances
have been removed. For the use case of tracking positions relative to
some other position, we instead provide `offsetBy` and `unoffsetBy`
functions. For the use case of advancing/unadvancing a position by an
arbitrary number of bytes, we instead provide `increaseBy` and
`decreaseBy` functions. For
offsetting/unoffsetting/advancing/unadvancing a position `p` by the size
of a string `s` (resp. character `c`), use `s + p`/`p - s`/`p + s`/`p -
s` (resp. `c + p`/`p - c`/`p + c`/`p - c`).
2025-10-09 07:47:45 +00:00
Rob23oba
6f1e932542 fix: make IO.sleep opaque (#10718)
This PR makes the function `IO.sleep` opaque. Previously, the definition
of `IO.sleep` made it definitionally equivalent to `pure ()`.
2025-10-09 07:37:11 +00:00
Sebastian Graf
c32a57e580 feat: revert "feat: disable "experimental" warning for mvcgen (#10638)" (#10720)
This PR re-enables the "experimental" warning for `mvcgen` by changing
its default. The official release has been postponed to justify small
breaking changes in the semantic foundations in the near future.
2025-10-09 06:31:18 +00:00
Lean stage0 autoupdater
aa86d95c08 chore: update stage0 2025-10-08 22:00:53 +00:00
Leonardo de Moura
f9e140838e feat: hexnum parser (#10716)
This PR adds a new helper parser for implementing parsers that contain
hexadecimal numbers. We are going to use it to implement anchors in the
`grind` interactive mode.
2025-10-08 21:12:03 +00:00
Leonardo de Moura
98a6fa1ac7 feat: improve grind anchors computation (#10715)
This PR improves anchor stability (aka stable hash codes) used to
reference terms in a `grind` goal.
2025-10-08 17:44:55 +00:00
Sebastian Ullrich
11be7e8f4a chore: use lld if available for building core (#10694) 2025-10-08 16:47:30 +00:00
Lean stage0 autoupdater
a89463bf9e chore: update stage0 2025-10-08 16:51:08 +00:00
Sofia Rodrigues
7600d41c90 fix: add cancel function to the Timer API to make it behave correctly with finalizers and selectables (#10630)
This PR aims to fix the Timer API selector to make it finish as soon as
possible when unregistered. This change makes the `Selectable.one`
function drop the `selectables` array as soon as possible, so when
combined with finalizers that have some effects like the TCP socket
finalizer, it runs it as soon as possible.
2025-10-08 16:14:39 +00:00
Marc Huisinga
80b8e44072 test: fix test flakiness (#10680)
This PR fixes several causes of test flakiness and re-enables the tests
that were disabled in #10665, #10669 and #10673.

Specifically, it fixes:
- A race condition in the file worker that caused it to report an
incomplete snapshot prefix in the inlay hint request (confirmed to be
the cause of #10665)
- A bug in the test runner where it didn't correctly account for
non-deterministic message ordering inducing different RPC pointer
numbering (confirmed to be the cause of #10673)
- A race condition in the watchdog that would sometimes cause the module
hierarchy to be empty (likely the cause of #10669, but not confirmed as
this issue only reproduced again once in tens of thousands of test runs
on various machines, including CI)
- An unrelated bug in the module hierarchy implementation that would
cause it to report an empty module hierarchy when the file was changed

It also replaces some calls to `Task.get` in the language server with
`IO.wait` to protect the code against unfortunate compiler re-ordering.
2025-10-08 13:33:56 +00:00
Sebastian Ullrich
1d989523d4 fix: simp should not pick up inaccessible definitional equations (#10696)
Fixes #10671
2025-10-08 12:48:35 +00:00
Sebastian Ullrich
3b061a0996 chore: more module system fixes and improvements from Mathlib porting (#10655) 2025-10-08 11:30:09 +00:00
Marc Huisinga
1b1c802362 feat: auto-completion for end names (#10660)
This PR adds auto-completion for identifiers after `end`. It also fixes
a bug where completion in the whitespace after `set_option` would not
yield the full option list.

Closes #3885.

### Breaking changes

The `«end»` syntax is adjusted to take an `identWithPartialTrailingDot`
instead of an `ident`.
2025-10-08 11:12:05 +00:00
Joachim Breitner
50c19f704b fix: Let MVarId.cleanup chase local declarations (#10712)
This PR lets `MVarId.cleanup` chase local declarations (a bit as if they
were equalities). Fixes #10710.
2025-10-08 10:49:14 +00:00
Mac Malone
bbc194b733 feat: USE_LAKE_CACHE CMake option (#10708)
This PR adds the `USE_LAKE_CACHE` option to the core CMake build
(defaults to `OFF`). When enabled, the Lake artifact cache will be
enabled (via `enableArtifactCache`) for stage 1 builds (which includes
interactive use).
2025-10-08 08:56:53 +00:00
Leonardo de Moura
4e7a2b2371 feat: anchors for referencing terms in the grind state (#10709)
This PR implements *anchors* (also known as stable hash codes) for
referencing terms occurring in a `grind` goal. It also introduces the
commands `show_splits` and `show_state`. The former displays the anchors
for candidate case splits in the current `grind` goal.
2025-10-08 02:51:21 +00:00
Mac Malone
215bc30296 feat: lake: allowImportAll configuration option (#9855)
This PR adds a new `allowImportAll` configuration option for packages
and libraries. When enabled by an upstream package or library,
downstream packages will be able to `import all` modules of that package
or library. This enables package authors to selectively choose which
`private` elements, if any, downstream packages may have access to.
2025-10-08 02:47:35 +00:00
Leonardo de Moura
b00d1f933f feat: make finish fail when the goal is not closed (#10707)
This PR ensures the `finish` tactic in `grind` interactive mode fails
and reports diagnostics when goal is not closed.
2025-10-07 20:34:19 +00:00
Leonardo de Moura
5ba0f8b885 feat: have tactic for grind interactive mode (#10706)
This PR adds the `have` tactic for the `grind` interactive mode.
Example:
```lean
example {a b c d e : Nat}
    : a > 0 → b > 0 → 2*c + e <= 2 → e = d + 1 → a*b + 2 > 2*c + d := by
  grind =>
    have : a*b > 0 := Nat.mul_pos h h_1
    lia
```
2025-10-07 20:06:16 +00:00
François G. Dorais
43da17aa7f feat: add forall_fin_zero and exists_fin_zero (#10627)
This PR adds lemmas `forall_fin_zero` and `exists_fin_zero`. It also
marks lemmas `forall_fin_zero`, `forall_fin_one`, `forall_fin_two`,
`exists_fin_zero`, `exists_fin_one`, `exists_fin_two` with `simp`
attribute.

Closes #10629
2025-10-07 18:50:23 +00:00
Wojciech Różowski
0195fdf9aa feat: add coinductive command to specify coinductive predicates (#10333)
This PR introduces a `coinductive` keyword, that can be used to define
coinductive predicates via a syntax identical to the one for `inductive`
keyword. The machinery relies on the implementation of elaboration of
inductive types and extracts an endomap on the appropriate space of the
predicates from the definition that is then fed to the
`PartialFixpoint`. Upon elaborating definitions, all the constructors
are declared through automatically generated lemmas.

For example, infinite sequence of transitions in a relation, can be
given by the following:
```lean4
section
variable (α : Type)
coinductive infSeq (r : α → α → Prop) : α → Prop where
  | step : r a b → infSeq r b → infSeq r a
  
/--
info: infSeq.coinduct (α : Type) (r : α → α → Prop) (pred : α → Prop) (hyp : ∀ (x : α), pred x → ∃ b, r x b ∧ pred b)
  (x✝ : α) : pred x✝ → infSeq α r x✝
-/
#guard_msgs in
#check infSeq.coinduct

/--
info: infSeq.step (α : Type) (r : α → α → Prop) {a b : α} : r a b → infSeq α r b → infSeq α r a
-/
#guard_msgs in
#check infSeq.step
end
```
The machinery also supports `mutual` blocks, as well as mixing inductive
and coinductive predicate definitions:
```lean4
mutual
  coinductive tick : Prop where
  | mk : ¬tock → tick

  inductive tock : Prop where
  | mk : ¬tick → tock
end

/--
info: tick.mutual_induct (pred_1 pred_2 : Prop) (hyp_1 : pred_1 → pred_2 → False) (hyp_2 : (pred_1 → False) → pred_2) :
  (pred_1 → tick) ∧ (tock → pred_2)
-/
#guard_msgs in
#check tick.mutual_induct
```

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2025-10-07 18:04:51 +00:00
Joachim Breitner
5a751d4688 fix: induction: do not allow generalizing variables occurring in the using clause (#10697)
This PR lets `induction` print a warning if a variable occurring in the
`using` clause is generalized. Fixes #10683.
2025-10-07 15:38:34 +00:00
Lean stage0 autoupdater
486d93c5fd chore: update stage0 2025-10-07 13:47:20 +00:00
François G. Dorais
8cebe691a2 fix: Nat.and_distrib_right -> Nat.and_or_distrib_right (#10649)
This PR renames `Nat.and_distrib_right` to `Nat.and_or_distrib_right`.
This is to make the name consistent with other theorems in the same file
(e.g. `Nat.and_or_distrib_left`).
2025-10-07 12:57:46 +00:00
Joachim Breitner
8655f7706f refactor: structural recursion: prove .eq_def directly (#10606)
This PR changes how Lean proves the equational theorems for structural
recursion. The core idea is to let-bind the `f` argument to `brecOn` and
rewriting `.brecOn` with an unfolding theorem. This means no extra case
split for the `.rec` in `.brecOn` is needed, and `simp` doesn't change
the `f` argument which can break the definitional equality with the
defined function. With this, we can prove the unfolding theorem first,
and derive the equational theorems from that, like for all other ways of
defining recursive functions.

Backs out the changes from #10415, the old strategy works well with the
new goals.

Fixes #5667
Fixes #10431
Fixes #10195
Fixes #2962
2025-10-07 12:53:09 +00:00
Yuri de Wit
5c92ffc64d doc: fix url to profile.ts source (#10628)
This PR fixes a broken link to the firefox profile definitions in one of
the comments.

The `profile.js` file was renamed to `profile.ts` while the rest of the
url remained the same.
2025-10-07 12:41:04 +00:00
Sebastian Ullrich
ca7e7c4279 fix: do not discard mutual members on macro use (#10695)
This PR fixes an issue where non-`macro` members of a `mutual` block
were discarded if there was at least one macro present.

Fixes #10687
2025-10-07 12:04:04 +00:00
dependabot[bot]
13c38f64a5 chore: CI: bump softprops/action-gh-release from 2.3.2 to 2.3.3 (#10646)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-07 11:42:02 +00:00
dependabot[bot]
b59959ddab chore: CI: bump actions/stale from 9 to 10 (#10647)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-07 11:41:31 +00:00
dependabot[bot]
8f9c27cc06 chore: CI: bump actions/github-script from 7 to 8 (#10648)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-07 11:41:04 +00:00
Sebastian Ullrich
715c53d92e chore: Modulize: put section below first module doc (#10693) 2025-10-07 09:10:42 +00:00
Sebastian Graf
7a9d769444 chore: fix the docstring of PredTrans.conjunctive (#10691) 2025-10-07 08:56:13 +00:00
Sebastian Ullrich
15636a347f fix: induction incrementality on removal of extraneous case (#10679)
This PR fixes an issue where "Invalid alternative name" errors from
`induction` stick around after removing the offending alternative.
2025-10-07 08:24:41 +00:00
Sebastian Ullrich
1ecdf8ddfa chore: simplify and extend Modulize.lean (#10692)
Take explicit list of files instead of asking Lake, take `--meta` flag
instead of guessing based on module name.
2025-10-07 08:22:52 +00:00
Chris Henson
54c6efea95 doc: typo in docstring of Std.Time.DateTime.now (#10668)
This PR fixes a duplicated docstring for `Std.Time.DateTime.now`.
2025-10-07 04:55:31 +00:00
Leonardo de Moura
b13f7e25ec feat: add show_* and instantiate grind tactics (#10690)
This PR adds the `instantiate`, `show_true`, `show_false`,
`show_asserted`, and `show_eqcs` tactics for the `grind` interactive
mode. The `show` tactic take an optional "filter" and are used to probe
the `grind` state. Example:
```lean
example (as bs cs : Array α) (v₁ v₂ : α)
        (i₁ i₂ j : Nat)
        (h₁ : i₁ < as.size)
        (h₂ : bs = as.set i₁ v₁)
        (h₃ : i₂ < bs.size)
        (h₃ : cs = bs.set i₂ v₂)
        (h₄ : i₁ ≠ j ∧ i₂ ≠ j)
        (h₅ : j < cs.size)
        (h₆ : j < as.size)
        : cs[j] = as[j] := by
  grind =>
    instantiate
    -- Display asserted facts with `generation > 0`
    show_asserted gen > 0
    -- Display propositions known to be `True`, containing `j`, and `generation > 0`
    show_true j && gen > 0
    -- Display equivalence classes with terms that contain `as` or `bs`
    show_eqcs as || bs
    instantiate
```

This PR also fixes a bug in the `grind` interactive mode initialization
procedure.
2025-10-07 03:36:22 +00:00
Sofia Rodrigues
6964a15b5d feat: add Std.CancellationToken type (#10510)
This PR adds a `Std.CancellationToken` type
2025-10-07 03:21:45 +00:00
Sofia Rodrigues
ad701b577b feat: add StreamMap (#10400)
This PR adds the StreamMap type that enables multiplexing in
asynchronous streams.

This PR depends on: #10366, #10367 and #10370.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
2025-10-06 23:39:44 +00:00
Henrik Böving
1f7374a5d6 fix: RC dec insertion for unused variables (#10689)
This PR fixes an oversight in the RC insertion phase in the code
generator.

If the code generator encounters a `let` that is unused (which is
perfectly reasonable as at this
phase we are in an impure IR and as such allow for side effects to
happen so we cannot remove all
unused `let`) it didn't insert a `dec` instruction for this variable.
This has previously gone
unnoticed because at this point in the compiler basically all unused
lets are removed already
anyways. However with the `IO`/`ST` token erasure coming up they will be
very frequent.
2025-10-06 22:05:17 +00:00
Mac Malone
aa3d409eb6 refactor: lake: mv tests/examples to top-level tests dir (#10688)
This PR moves Lake's test infrastructure from `src/lake` to
`tests/lake`.
2025-10-06 21:47:57 +00:00
Paul Reichert
7771b8079c refactor: improve naming in the range API (#10537)
This PR renames some declarations in the range API for better
consistency and readability. For example,
`UpwardEnumerable.succMany?_succ?` is now called `succMany?_add_one`, in
order to (a) correct the erroneous use of `succ?` instead of `succ`
(=`Nat.succ`) and (b) distinguish the successor of natural numbers
(`add_one`) from the successor of the upward-enumerable type (`succ?` or
`succ`).
2025-10-06 20:51:09 +00:00
Mac Malone
43d4c8fe9f feat: IO.FS.hardLink (#10676)
This PR adds the `IO.FS.hardLink` function, which can be used to create
hard links.

This is implemented via libuv's `uv_fs_link` function.

Lake hopes to make use of this function to decrease the storage cost of
restoring artifacts.

This PR also fixes some C implementation issues found in nearby similar
functions.
2025-10-06 18:22:07 +00:00
Sofia Rodrigues
4898f28c12 feat: add Std.Broadcast type (#10369)
This PR adds a multi-consumer, multi-producer channel to Std.Sync.

This PR depends on: #10366, #10367 and #10370.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
2025-10-06 17:47:18 +00:00
Paul Reichert
16400e2aa3 feat: add lemmas about iterator fold and map interactions (#10653)
This PR adds equational lemmas about (filter-)mapping and then folding
iterators.
2025-10-06 16:12:13 +00:00
Markus Himmel
d228cd3edd feat: LT and LE instances on new position types (#10685)
This PR introduces `LT` and `LE` instances on `String.ValidPos` and
`String.Slice.Pos`.
2025-10-06 16:06:16 +00:00
Joachim Breitner
232a0495b0 chore: remove public section from end of files (#10684)
This PR removes `public section` lines from end of files; they look a
bit silly there.
2025-10-06 13:30:48 +00:00
Joachim Breitner
30f41fe542 fix: instance name for deriving ToExpr (#10682)
This PR changes the instance name for `deriving ToExpr` to be consistent
with other derived instance since #10271. Fixes #10678.
2025-10-06 11:46:46 +00:00
Leonardo de Moura
fbfb0757ca feat: grind interactive mode basic tactics (#10677)
This PR implements the basic tactics for the new `grind` interactive
mode. While many additional `grind` tactics will be added later, the
foundational framework is already operational. The following `grind`
tactics are currently implemented: `skip`, `done`, `finish`, `lia`, and
`ring`.
This PR also removes the notion of `grind` fallback procedure since it
is subsumed by the new framework. Examples:
```lean
example (x y : Nat) : x ≥ y + 1 → x > 0 := by
  grind => skip; lia; done

open Lean Grind

example [CommRing α] (a b c : α)
  : a + b + c = 3 →
    a^2 + b^2 + c^2 = 5 →
    a^3 + b^3 + c^3 = 7 →
    a^4 + b^4 + c^4 = 9 := by
  grind => ring
```
2025-10-06 01:08:26 +00:00
Sebastian Ullrich
ffb6142ee7 chore: CI: update macOS images (#10666) 2025-10-05 16:06:03 +00:00
Marc Huisinga
7b3c22cebb test: disable flaky interactive diag tests (#10673) 2025-10-05 09:38:41 +00:00
Lean stage0 autoupdater
1ac81c6a7a chore: update stage0 2025-10-05 02:59:23 +00:00
Mac Malone
662dc10447 fix: lake: outdated traces w/ cache (#10672)
This PR fixes an issue with the Lake artifact cache where trace files
were not correctly updated when switching between different cached
builds.
2025-10-05 00:44:43 +00:00
Marc Huisinga
7688919765 test: temporarily disable all new tests that use waitForILeans (#10669)
Due to the flaky test failure at
https://github.com/leanprover/lean4/actions/runs/18241144163/job/51943212141
2025-10-04 09:25:43 +00:00
Rob23oba
5d3df7b5f4 fix: some ExtraModUses (#10620)
This PR records extra mod uses that previously caused wrong unnecessary
import reports from shake.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-10-03 15:50:40 +00:00
Marc Huisinga
643da1ea1b test: disable flaky tests (#10665) 2025-10-03 14:31:39 +00:00
Marc Huisinga
3d75c2ce2b fix: eliminate potential source of inlay hint flakiness (#10664)
This PR fixes one potential source of inlay hint flakiness.

In the old `IO.waitAny` implementation, we could rely on the fact that
if all tasks in the list were finished, `IO.waitAny` would pick the
first finished one. In the new implementation (#9732), this isn't the
case anymore for fairness reasons, but this also means that in
`IO.AsyncList.getFinishedPrefixWithTimeout`, it can happen that we don't
scan the full finished command snapshot prefix because we pick the
timeout task before the finished snapshot task. This is likely the cause
of a flaky test failure
[here](https://github.com/leanprover/lean4/actions/runs/18215430028/job/51863870111),
where the inlay hint test yielded no result (the timeout task has an
edit delay of 0ms in the first inlay hint request that is emitted,
finishes immediately and can thus immediately cause the finished prefix
to be skipped with the new `waitAny` implementation).

This PR fixes this issue by adding a `hasFinished` check before the
`waitAny` to ensure that we always scan the finished prefix and don't
need to rely on a brittle invariant that doesn't hold anymore. It also
converts some `Task.get`s to `IO.wait` for safety so that the compiler
can't re-order them.
2025-10-03 10:54:36 +00:00
David Thrane Christiansen
b979fa012b fix: verso docstring {name} role suggestion overload (#10663)
This PR disables `{name}` suggestions for `.anonymous` and adds syntax
suggestions.

When the provided name can't be resolved, the `{name}` role suggests
fully-qualified variants. But if the name is a syntax error, it
attempted to suggest names that had `.anonymous` as a suffix; the
resulting list of suggestions of all names in Lean's environment
overloaded the language server.
2025-10-03 09:33:53 +00:00
Sebastian Ullrich
288b7d2023 chore: further cleanup from shaking Init (#10658) 2025-10-02 17:29:00 +00:00
Markus Himmel
5c707d936c chore: rename Stream to Std.Stream (#10645)
This PR renames `Stream` to `Std.Stream` so that the name becomes
available to mathlib after a deprecation cycle.
2025-10-02 15:25:56 +00:00
Joachim Breitner
5a2e46b021 fix: equational theorem generation: avoid reducing at transparency all (#10654)
This PR avoid reducing at transparency all in equational theorem
generation. Fixes #10651.
2025-10-02 13:55:32 +00:00
Sebastian Graf
24c86fc05d fix: improve error message for mstart when goal is not a Prop (#10650)
This PR improves the error message for `mstart` when the goal is not a
`Prop`.
2025-10-02 08:46:29 +00:00
Sebastian Ullrich
d17160518c chore: module system fixes and refinements from Mathlib porting (#10643) 2025-10-02 08:28:08 +00:00
Paul Reichert
89686fcd02 refactor: replace PRange shape α with Rcc α and eight other types (#10319)
This PR "monomorphizes" the structure `Std.PRange shape α`, replacing it
with nine distinct structures `Std.Rcc`, `Std.Rco`, `Std.Rci` etc., one
for each possible shape of a range's bounds. This change was necessary
because the shape polymorphism is detrimental to attempts of automation.

**BREAKING CHANGE:** While range/slice notation itself is unchanged,
this essentially breaks the entire remaining (polymorphic) range and
slice API except for the dot-notation(`toList`, `iter`, ...). It is not
possible to deprecate old declarations that were formulated in a
shape-polymorphic way that is not available anymore.
2025-10-02 06:45:11 +00:00
David Thrane Christiansen
0b2193c771 chore: docstring review for ByteArray (#10632)
This PR adds missing docstrings for ByteArray and makes existing ones
consistent with our style.
2025-10-02 04:20:18 +00:00
David Thrane Christiansen
2c6576b269 chore: missing docstring + style updates for String docs (#10640)
This PR adds a missing docstring and applies our style guide to parts of
the String API.
2025-10-02 04:19:55 +00:00
Markus Himmel
2cca32ccc3 chore: use UTF8 instead of Utf8 in identifiers (#10636)
This PR renames `String.getUtf8Byte` to `String.getUTF8Byte` in order to
adhere to the standard library naming convention.
2025-10-01 17:57:32 +00:00
Sebastian Graf
784a063092 fix: try synthesizing synthetic MVars in mspec (#10644)
This PR explicitly tries to synthesize synthetic MVars in `mspec`. Doing
so resolves a bug triggered by use of the loop invariant lemma for
`Std.PRange`.
2025-10-01 16:29:12 +00:00
Sebastian Graf
ba52e9393c feat: LawfulMonad and WPMonad instances for Option and OptionT (#9932)
This PR adds `LawfulMonad` and `WPMonad` instances for `Option` and
`OptionT`.
2025-10-01 16:16:07 +00:00
Paul Reichert
1efefc25a5 fix: expose Int* definitions for simprocs and decide (fixes #10546) (#10631)
This PR exposes the definitions about `Int*`. The main reason is that
the `SInt` simprocs require many of them to be exposed. Furthermore,
`decide` now works with `Int*` operations. This fixes #10631.
2025-10-01 15:53:02 +00:00
Sebastian Graf
c920326f0b feat: introduce List.Cursor.pos as an abbreviation for prefix.length (#10642)
This PR introduces `List.Cursor.pos` as an abbreviation for
`prefix.length`.
2025-10-01 15:28:30 +00:00
Sebastian Graf
63354ce594 fix: spurious invariant instantiation in mspec by rfl (#10641)
This PR ensures that the `mspec` and `mvcgen` tactics no longer
spuriously instantiate loop invariants by `rfl`.
2025-10-01 15:03:09 +00:00
Sebastian Graf
3095c9d4df fix: hygiene for goals generated by mvcgen (#10639)
This PR fixes hygiene of the local context for *all* goals generated by
`mvcgen`, not just those that get a fresh MVar as in #9781.
2025-10-01 14:13:15 +00:00
Sebastian Graf
689b3aa8d7 feat: disable "experimental" warning for mvcgen (#10638)
This PR disables the "experimental" warning for `mvcgen` by changing its
default.
2025-10-01 14:10:40 +00:00
Lean stage0 autoupdater
d9058225a9 chore: update stage0 2025-10-01 14:32:36 +00:00
Markus Himmel
29c2b86ef4 chore: String.getUTF8Byte (#10637)
This PR adds the function `String.getUTF8Byte` ahead of a more
comprehensive PR to use `UTF8` instead of `Utf8` in identifiers.
2025-10-01 13:59:42 +00:00
Lean stage0 autoupdater
ee8f0cca33 chore: update stage0 2025-10-01 12:32:50 +00:00
Markus Himmel
5bfbe2a875 refactor: incorporate UTF8 material from String.Extra into String.Basic (#10634)
This PR defines `ByteArray.validateUTF8`, uses it to show that
`ByteArray.IsValidUtf8` is decidable and redefines `String.fromUTF8` and
friends to use it.

The functions `String.validateUTF8` and `String.utf8DecodeChar?` are
deprecated in favor of the identically named functions in the
`ByteArray` namespace.
2025-10-01 11:33:29 +00:00
Markus Himmel
9dc1faf327 chore: add an internal String function (#10635)
This PR adds an internal `String` function ahead of an upcoming PR.
2025-10-01 11:12:35 +00:00
Lean stage0 autoupdater
663d4d2c79 chore: update stage0 2025-10-01 08:21:46 +00:00
Markus Himmel
81ea922025 chore: rename String.Pos to String.Pos.Raw (#10624)
This PR renames `String.Pos` to `String.Pos.Raw`.

After an abbreviated deprecation cycle, we will then rename
`String.ValidPos` to `String.Pos`.
2025-10-01 07:45:24 +00:00
Henrik Böving
d88e417cda refactor: tame down dead let eliminator in lambda RC (#10626)
This PR reduces the aggressiveness of the dead let eliminator from
lambda RC.

The motivation for this is that all other passes in lambda RC respect
impurity but the dead let eliminator still operates under the assumption
of purity. There is a couple of motivations for the elim dead let
elaborator:
- unused projections introduced by the ToIR translation
- the elim dead branch pass introducing new opportunities
- closed term extraction introducing new opportunities
2025-09-30 19:51:16 +00:00
Marc Huisinga
dfd3d18530 test: improve language server test coverage (#10574)
This PR significantly improves the test coverage of the language server,
providing at least a single basic test for every request that is used by
the client. It also implements infrastructure for testing all of these
requests, e.g. the ability to run interactive tests in a project context
and refactors the interactive test runner to be more maintainable.
Finally, it also fixes a small bug with the recently implemented unknown
identifier code actions for auto-implicits (#10442) that was discovered
in testing, where the "import all unambiguous unknown identifiers" code
action didn't work correctly on auto-implicit identifiers.
2025-09-30 11:15:03 +00:00
Lean stage0 autoupdater
7d55c033e1 chore: update stage0 2025-09-30 01:46:26 +00:00
Mac Malone
5d8498888b feat: lake: use system cache for bootstrap (#10621)
This PR alters the Lake directory detection so that the core build
(i.e., `bootstrap = true`) is stored in the user cache directory (if
available) and never in a toolchain-specific directory.

It is also fixes some issues with cache environment configuration
discovered along the way.
2025-09-30 00:57:45 +00:00
Mac Malone
5ede2bfcf2 chore: use libPrefixOnWindows in core build (#10617)
This PR switches the core build Lake configuration file to use
`libPrefixOnWindows` rather than a CMake hack.

It also removes some dead TOML variables from the CMake configuration.
2025-09-29 20:07:02 +00:00
Markus Himmel
c039e29a3f perf: shorten critical build path around String.Basic (#10614)
This PR cuts some edges from the import graph.

Specifically:
- `TreeMap` and `HashMap` no longer depend on `String`, so now the
expensive things are all in parallel instead of partially in sequence
- `Omega` no longer relies on `List` lemmas
- The section of the import graph between `Init.Omega` and
`Init.Data.Bitvec.Lemmas` is cleaned up a bit
2025-09-29 19:45:21 +00:00
Kyle Miller
356d1f64bf fix: instantiate mvars in types of mvars in abstractMVars (#10612)
This PR fixes an issue reported [on
Zulip](https://leanprover.zulipchat.com/#narrow/channel/239415-metaprogramming-.2F-tactics/topic/.60abstractMVars.60.20not.20instantiating.20level.20mvars/near/541918246)
where `abstractMVars` (which is used in typeclass inference and `simp`
argument elaboration) was not instantiating metavariables in the types
of metavariables, causing it to abstract already-assigned metavariables.

This also eliminates an unnecessary `instantiateMVars` and documents the
invariant that the argument to `abstractExprMVars` must have its
metavariables already instantiated.
2025-09-29 16:33:10 +00:00
Marc Huisinga
9f2ce635ae fix: unknown identifier code actions with nested open (#10619)
This PR fixes a bug in the unknown identifier code actions where it
would yield non-sensical suggestions for nested `open` declarations like
`open Foo.Bar`.
2025-09-29 15:44:56 +00:00
Sebastian Graf
76403367ba fix: remove superfluous Monad instances from some spec lemmas (#10564) (#10618)
This PR removes superfluous `Monad` instances from the spec lemmas of
the `MonadExceptOf` lifting framework.

It also adds a bit of documentation and more tracing to `mvcgen`.

Fixes #10564.
2025-09-29 15:02:43 +00:00
Marc Huisinga
c016bb9434 fix: non-LSP-compliant FileSystemWatcher (#10609)
This PR fixes an LSP-non-compliance in the `FileSystemWatcher` that was
introduced in #925.

Closes #10597.
2025-09-29 14:16:09 +00:00
Lean stage0 autoupdater
239c348239 chore: update stage0 2025-09-29 14:24:13 +00:00
Henrik Böving
b82303e9b3 feat: consistent type ABI regardless of transparency (#10610)
This PR ensures that even if a type is marked as `irreducible` the
compiler can see through it in
order to discover functions hidden behind type aliases.
2025-09-29 13:31:41 +00:00
Mac Malone
6f3fef9373 fix: lake: add lake help cache (#10616)
This PR fixes an oversight where `lake cache help` existed but `lake
help cache` (and by extension `lake cache --help`) did not.
2025-09-29 12:41:28 +00:00
David Thrane Christiansen
4338a8be32 fix: better error message on missing declaration name for docstring (#10608)
This PR fixes a bad error message due to elaborating partial syntax with
Verso docstrings.

When elaborating partial syntax, the elaborator sometimes attempts to
add a docstring for a declaration that it didn't parse a name for. The
name defaults to anonymous, but inserting the docs for the anonymous
name throws a panic about being on the wrong async branch.

With this change, the reported error is the expected parser error
instead, which is much friendlier.
2025-09-29 06:26:08 +00:00
Lean stage0 autoupdater
19f6c168ef chore: update stage0 2025-09-29 00:32:08 +00:00
Leonardo de Moura
eba8bf3347 feat: infrastructure for grind interactive mode (#10607)
This PR adds infrastructure for the upcoming `grind` tactic mode, which
will be similar to the `conv` mode. The goal is to extend `grind` from a
terminal tactic into an interactive mode: `grind => …`.

It will serve as the foundation for `ungrind`, the process of converting
an expensive (and potentially fragile) `grind` proof into a robust
script. This mode will include tactics for expensive reasoning steps
such as cutsat model-based search, Gröbner basis computation,
E-matching, case splits, and more.

It will also provide robust, succinct references to facts and terms:
labels, structural matches, and anchors (e.g., `#abcd`).
2025-09-28 23:46:49 +00:00
David Thrane Christiansen
8c69b1eaec feat: suggest qualified names while editing Verso docstrings (#10584)
This PR causes Verso docstrings to search for a name in the environment
that is at least as long as the current name, providing it as a
suggestion.
2025-09-28 22:02:26 +00:00
Sebastian Ullrich
fd3f51012f feat: shake import minimizer aware of the module system and arbitrary elaboration dependencies (#10575)
This PR adds the necessary infrastructure for recording elaboration
dependencies that may not be apparent from the resulting environment
such as notations and other metaprograms. An adapted version of `shake`
from Mathlib is added to `script/` but may be moved to another location
or repo in the future.
2025-09-28 16:00:00 +00:00
Sebastian Ullrich
8b2fea1ec7 perf: avoid blocking wait on kernel env on some interpreter entries (#10591) 2025-09-28 12:52:24 +00:00
Lean stage0 autoupdater
9b1109c55d chore: update stage0 2025-09-28 05:44:06 +00:00
Leonardo de Moura
55b35c6e38 chore: grind examples (#10605)
Examples for `grind` demo.
2025-09-28 05:19:04 +00:00
Leonardo de Moura
3ce5097c3c feat: process grind core equalities in grind order (#10604)
This PR implements the method `processNewEq` in `grind order`. It is
responsible for processing equalities propagated by the `grind` E-graph.
2025-09-28 04:19:35 +00:00
Mac Malone
b6bfc9733c fix: lake: module artifact restoration for ir/bc (#10602)
This PR corrects the file path where Lake copies module `.ir` / `.bc`
artifacts.
2025-09-28 04:14:17 +00:00
Leonardo de Moura
8637bd296e fix: isPartialOrder in grind order (#10601)
This PR fixes a panic in `grind order` when order is not a partial
order.
2025-09-28 02:19:29 +00:00
Leonardo de Moura
6881177e38 feat: grind order negative constraints (#10600)
This PR implements support for negative constraints in `grind order`.
Examples:

```lean
open Lean Grind
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsLinearPreorder α]
    (a b c d : α) : a ≤ b → ¬ (c ≤ b) → ¬ (d ≤ c) → d < a → False := by
  grind -linarith (splits := 0)

example [LE α] [Std.IsLinearPreorder α]
    (a b c d : α) : a ≤ b → ¬ (c ≤ b) → ¬ (d ≤ c) → ¬ (a ≤ d) → False := by
  grind -linarith (splits := 0)

example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsLinearPreorder α] [CommRing α] [OrderedRing α]
    (a b c d : α) : a - b ≤ 5 → ¬ (c ≤ b) → ¬ (d ≤ c + 2) → d ≤ a - 8 → False := by
  grind -linarith (splits := 0)
```
2025-09-28 01:50:27 +00:00
Leonardo de Moura
409daac2cb fix: Nat adapter in grind order (#10599)
This PR fixes the support for `Nat` in `grind order`. This module uses
the `Nat.ToInt` adapter.
2025-09-28 00:26:37 +00:00
Leonardo de Moura
62fa92ec4a feat: grind order positive constraints (#10598)
This PR implements support for positive constraints in `grind order`.
The new module can already solve problems such as:

```lean
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α]
    (a b c : α) : a ≤ b → b ≤ c → c < a → False := by
  grind

example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α]
    (a b c d : α) : a ≤ b → b ≤ c → c < d → d ≤ a → False := by
  grind

example [LE α] [Std.IsPreorder α]
    (a b c : α) : a ≤ b → b ≤ c → a ≤ c := by
  grind

example [LE α] [Std.IsPreorder α]
    (a b c d : α) : a ≤ b → b ≤ c → c ≤ d → a ≤ d := by
  grind
```

It also generalizes support for offset constraints in `grind` to rings.
The new module implements theory propagation and reduces the number of
case splits required to solve problems:

```lean
example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [Ring α] [OrderedRing α]
    (a b : α) : a ≤ 5 → b ≤ 8 → a > 6 ∨ b > 10 → False := by
  grind -linarith (splits := 0)

example [LE α] [LT α] [Std.LawfulOrderLT α] [Std.IsPreorder α] [CommRing α] [OrderedRing α]
    (a b c : α) : a + b*c + 2*c ≤ 5 → a + c > 5 - c - c*b → False := by
  grind -linarith (splits := 0)

example (a b : Int) (h : a + b > 5) : (if a + b ≤ 0 then b else a) = a := by
  grind -linarith -cutsat (splits := 0)
```

We still need to implement support for negated constraints.
2025-09-27 23:22:09 +00:00
Leonardo de Moura
0504e32bb7 feat: add addEdge to grind order (#10596)
This PR implements the function for adding new edges to the graph used
by `grind order`. The graph maintains the transitive closure of all
asserted constraints.
2025-09-27 18:18:41 +00:00
Mac Malone
fbfc7694a0 fix: only pass known CMake build types to Lake (#10595)
This PR ensures that Lake only receives recognized CMake build types
from CMake. This fixes an issue with #10581 which broke the
`RelWithAssert` build.
2025-09-27 17:47:15 +00:00
Leonardo de Moura
69b8b0098c feat: proofs for theory propagation in grind order (#10594)
This PR implements proof construction for theory propagation in `grind
order`.
2025-09-27 16:36:21 +00:00
Leonardo de Moura
69c8f13bf2 feat: proof construction for grind order (#10590)
This PR implements proof term construction for `grind order`.
2025-09-27 05:30:32 +00:00
Leonardo de Moura
39beb25f16 feat: helper theorems for grind order (#10589)
This PR adds helper theorems for implementing  `grind order`
2025-09-27 04:04:44 +00:00
Mac Malone
6d5efd79b9 chore: lake: restoreAllArtifacts / CMake build types in TOML schema (#10588)
This PR adds `restoreAllArtifacts` and the CMake build types to the Lake
TOML schema.

I forgot to do this in #10576 and #10578.
2025-09-27 03:38:22 +00:00
Mac Malone
b37d2ce2b9 chore: use CMake build type in Lake core build (#10581)
This PR alters the core build Lake configuration file to use the
`CMAKE_BUILD_TYPE` for Lake's `buildType`.
2025-09-27 03:38:12 +00:00
Mac Malone
18832eb600 fix: lake: ill-formed build output handling (#10586)
This PR makes Lake no longer error if build outputs found in a trace
file (or in the artifact cache) are ill-formed.

This is caused a problem with the CI cache and is just generally too
strict.
2025-09-27 03:35:57 +00:00
Mac Malone
05300f7b51 chore: restoreAllArtifacts = true for core (#10582)
This PR sets `restoreAllArtifacts = true` in the core build Lake
configuration file.
2025-09-27 03:30:21 +00:00
Leonardo de Moura
0bf7741a3e feat: multiple grind propagators per declaration (#10583)
This PR allows users to declare additional `grind` constraint
propagators for declarations that already include propagators in core.
2025-09-27 02:04:03 +00:00
Mac Malone
f80d6e7d38 refactor: lake: libPrefixOnWindows on libName (#10579)
This PR alters `libPrefixOnWindows` behavior to add the `lib` prefix to
the library's `libName` rather than just the file path. This means that
Lake's `-l` will now have the prefix on Windows. While this should not
matter to a MSYS2 build (which accepts both `lib`-prefixed and
unprefixed variants), it should ensure compatibility with MSVC (if that
is ever an issue).
2025-09-27 01:54:23 +00:00
Mac Malone
5b8d4d7210 chore: invalidate Lake CI cache (#10587)
This PR invalidates the CI cache for the Linux Lake build job by bumping
the version of the CI cache key.

The CI cache is broken due to a change in the output format in build
traces. This will be fixed in #10586, but this should prevent further
breakages of PRs in the meantime.
2025-09-27 01:11:23 +00:00
Lean stage0 autoupdater
db8c77a8fa chore: update stage0 2025-09-26 22:39:54 +00:00
Mac Malone
7ee3079afb feat: lake: CMake build types (#10578)
This PR adds support for the CMake spelling of a build type (i.e.,
capitalized) to Lake's `buildType` configuration option.
2025-09-26 21:06:12 +00:00
Mac Malone
c3d9d0d931 feat: lake: restoreAllArtifacts (#10576)
This PR adds a new package configuration option: `restoreAllArtifacts`.
When set to `true` and the Lake local artifact cache is enabled, Lake
will copy all cached artifacts into the build directory. This ensures
they are available for external consumers who expect build results to be
in the build directory.
2025-09-26 20:58:32 +00:00
Mac Malone
e98d7dd603 feat: lake: Reservoir-versioned dependencies (#10551)
This PR enables Reservoir packages to be required as dependencies at a
specific package version (i.e., the `version` specified in the package's
configuration file).
2025-09-26 20:52:54 +00:00
Mac Malone
6102f00322 chore: rm src/lake/lakefile.toml (#10580)
This file is essentially just for me and can cause problems with the
language server, so I have removed it from the committed code (and left
an ignored version on my own setup).
2025-09-26 20:51:02 +00:00
Sebastian Ullrich
646f2fabbf fix: allow meta decls in #eval (#10545) 2025-09-26 15:10:33 +00:00
Sebastian Ullrich
f4a0259344 chore: cleanups uncovered by Shake (#10572)
* Wrap proof subterms in `by exact` so dependencies can be demoted to
private `import`s
* Remove trivial instance re-definitions that may cause name collisions
on import changes
* Remove unused `open`s that may fail on import removals
2025-09-26 14:38:30 +00:00
Sebastian Graf
3f816156cc fix: immediately replace main goal in SPred proof mode tactics (#10571)
This PR ensures that `SPred` proof mode tactics such as `mspec`,
`mintro`, etc. immediately replace the main goal when entering the proof
mode. This prevents `No goals to be solved` errors.
2025-09-26 13:41:38 +00:00
Sebastian Ullrich
c92ec361cd chore: CommandElabM.liftCoreM should not reset InfoState.lazyAssignment (#10518)
Fixes #10408
2025-09-26 13:37:40 +00:00
Sebastian Ullrich
49cff79712 fix: privacy checks and import all (#10550)
This PR ensures private declarations are accessible from the private
scope iff they are local or imported through an `import all` chain,
including for anonymous notation and structure instance notation.
2025-09-26 13:26:10 +00:00
Sebastian Ullrich
2677ca8fb4 fix: import-merging theorems under the module system (#10556) 2025-09-26 13:02:51 +00:00
Sebastian Graf
78b09d5dcc feat: support case label like syntax in mvcgen invariants (#10570)
This PR adds support for case label like syntax in `mvcgen invariants`
in order to refer to inaccessible names. Example:

```lean
def copy (l : List Nat) : Id (Array Nat) := do
  let mut acc := #[]
  for x in l do
    acc := acc.push x
  return acc

theorem copy_labelled_invariants (l : List Nat) : ⦃⌜True⌝⦄ copy l ⦃⇓ r => ⌜r = l.toArray⌝⦄ := by
  mvcgen [copy] invariants
  | inv1 acc => ⇓ ⟨xs, letMuts⟩ => ⌜acc = l.toArray⌝
  with admit
```
2025-09-26 12:57:49 +00:00
Sebastian Ullrich
a164ae5073 chore: overhaul meta error messages (#10569) 2025-09-26 12:56:46 +00:00
Sebastian Ullrich
2c54386555 fix: Prop instances should be elaborated in the private scope (#10568) 2025-09-26 12:16:09 +00:00
Sebastian Graf
62fd973b28 fix: make getArg!' compute the correct arg index to access (#10567)
This PR fixes argument index calculation in `Lean.Expr.getArg!'`.
2025-09-26 11:54:49 +00:00
Sebastian Graf
71e09ca883 feat: concrete invariant? suggestions based on start and end (#10566)
This PR improves `mvcgen invariants?` to suggest concrete invariants
based on how invariants are used in VCs.
These suggestions are intentionally simplistic and boil down to "this
holds at the start of the loop and this must hold at the end of the
loop":

```lean
def mySum (l : List Nat) : Nat := Id.run do
  let mut acc := 0
  for x in l do
    acc := acc + x
  return acc

/--
info: Try this:
  invariants
    · ⇓⟨xs, letMuts⟩ => ⌜xs.prefix = [] ∧ letMuts = 0 ∨ xs.suffix = [] ∧ letMuts = l.sum⌝
-/
#guard_msgs (info) in
theorem mySum_suggest_invariant (l : List Nat) : mySum l = l.sum := by
  generalize h : mySum l = r
  apply Id.of_wp_run_eq h
  mvcgen invariants?
  all_goals admit
```

It still is the user's job to weaken this invariant such that it
interpolates over all loop iterations, but it *is* a good starting point
for iterating. It is also useful because the user does not need to
remember the exact syntax.
2025-09-26 11:37:14 +00:00
Kim Morrison
e6dd41255b feat: upstream ReduceEval instances from quote4 (#10563)
This PR moves some `ReduceEval` instances about basic types up from the
`quote4` library.
2025-09-26 04:02:55 +00:00
Leonardo de Moura
cfc46ac17f feat: internalization for grind order (#10562)
This PR simplifies the `grind order` module, and internalizes the order
constraints. It removes the `Offset` type class because it introduced
too much complexity. We now cover the same use cases with a simpler
approach:
- Any type that implements at least `Std.IsPreorder`
- Arbitrary ordered rings.
- `Nat` by the `Nat.ToInt` adapter.
2025-09-26 03:49:06 +00:00
Mac Malone
7c0868d562 refactor: lake: introduce LogConfig (#10468)
This PR refactors the Lake log monads to take a `LogConfig` structure
when run (rather than multiple arguments). This breaking change should
help minimize future breakages due to changes in configurations options.

In addition, the CLI logging monad stack has been polished up and
`LogIO` now supports the `failLv` configuration option.
2025-09-26 02:44:51 +00:00
Mac Malone
28fb4bb1b2 feat: lake cache (& remote cache support) (#10188)
This PR adds support for remote artifact caches (e.g., Reservoir) to
Lake. As part of this support, a new suite of `lake cache` CLI commands
has been introduced to help manage Lake's cache. Also, the existing
local cache support has been overhauled for better interplay with the
new remote support.

**Cache CLI**

Artifacts are uploaded to a remote cache via `lake cache put`. This
command takes a JSON Lines input-to-outputs file which describes the
output artifacts for a build (indexed by its input hash). This file can
be produced by a run of `lake build` with the new `-o` option. Lake will
write the input-to-outputs mappings of thee root package artifacts
traversed by the build to the file specified via `-o`. This file can
then be passed to `lake cache put` to upload both it and the built
artifacts from the local cache to the remote cache.

The remote cache service can be customized using the following
environment variables:

* `LAKE_CACHE_KEY`: This is the authorization key for the remote cache.
Lake uploads artifacts via `curl` using the AWS Signature Version 4
protocol, so this should be the S3 `<key>:<secret>` pair expected by
`curl`.

* `LAKE_CACHE_ARTIFACT_ENDPOINT`: This is the base URL to upload (or
download) artifacts to a given remote cache. Artifacts will be stored at
`<endpoint>/<scope/<content-hash>.art`.

* `LAKE_CACHE_REVISION_ENDPOINT`: This is the base URL to upload (or
download) input-to-output mappings to a given remote cache. Mappings are
indexed by the Git revision of the package, and are stored at
`<endpoint>/<scope/<rev>.jsonl`.

The `<scope>` is provided through the `--scope` option to `lake cache
put`. This option is used to prevent one package from overwriting the
artifacts/mappings of another. Lake artifact hashes and Git revisions
hashes are not cryptographically secure, so it is not safe for a service
to store untrusted files across packages in a single flat store.

Once artifacts are available in a remote cache, the `lake cache get`
command can be used to retrieve them. By default, it will fetch
artifacts for the root package's dependencies from Reservoir using its
API. But, like `cache put`, it can be configured to use a custom
endpoint with the above environment variables and an explicit `--scope`.
When so configured, `cache get` will instead download artifacts for the
root package. Lake only downloads artifacts for a single package in this
case, because it cannot deduce the necessary package scopes without
Reservoir.

**Significant local cache changes**

* Lake now always has a cache directory. If Lake cannot find a good
candidate directory on the system for the cache, it will instead store
the cache at `.lake/cache` within the workspace.

* If the local cache is disabled, Lake will not save built artifacts to
the cache. However, Lake will, nonetheless, always attempt to lookup
build artifacts in the cache. If found, the cached artifact will be
copied to the the build location ("restored").

* Input-to-outputs mappings in the local cache are no longer stored in a
single file for a package, but rather in individual files per input (in
the `outputs` subdirectory of the cache).

* Outputs in a trace file, outputs file, or mappings file are now an
`ArtifactDescr`, which is currently composed of both the content hash
and the file extension.

* Trace files now contain a date-based `schemaVersion` to help make
version to version migration easier. Hashes in JSON and in artifacts
names now use a 16-digit hexadecimal encoding (instead of a variable
decimal encoding).

* `buildArtifactUnlessUpToDate` now returns an `Artifact` instead of a
`FilePath`.

**NOTE:** The Lake local cache is still disabled by default. This means
that built artifacts, by default, will not be placed in the cache
directory, and thus will not be available for `lake cache put` to
upload. Users must first explicitly enable the cache by either setting
the `LAKE_ARTIFACT_CACHE` environment variable to a truthy value or by
setting the `enableArtifactCache` package configuration option to
`true`.
2025-09-26 01:13:43 +00:00
Robert J. Simmons
2231d9b488 feat: improve error messages for ambiguous 3.toDecmial syntax (#10488)
This PR changes the way that scientific numerals are parsed in order to
give better error messages for (invalid) syntax like `32.succ`.

Example:

```lean4
#check 32.succ
```

Before, the error message is:

```
unexpected identifier; expected command
```

This is because `32.` parses as a complete float, and `#check 32.`
parses as a complete command, so `succ` is being read as the start of a
new command.

With this change, the error message will move from the `succ` token to
the `32` token (which isn't totally ideal from my perspective) but gives
a less misleading error message and corresponding suggestion:

```
unexpected identifier after decimal point; consider parenthesizing the number
```
2025-09-26 01:12:10 +00:00
David Thrane Christiansen
e72bf59385 feat: more metadata for Verso docstrings (#10560)
This PR adds highlighted Lean code to Verso docstrings and fixes smaller
quality-of-life issues.
2025-09-25 23:51:51 +00:00
Mac Malone
343328b7df feat: lake: rename dependencies (#10452)
This PR refactors Lake's package naming procedure to allow packages to
be renamed by the consumer. With this, users can now require a package
using a different name than the one it was defined with.

This is support will be used in the future to enable seamlessly
including the same package at multiple different versions within the
same workspace.

In a Lake package configuration file written in Lean, the current
package's assigned name is now accessed through `__name__` instead of
the previous `_package.name`. A deprecation warning has been added to
`_package.name` to assist in migration.
2025-09-25 22:10:39 +00:00
Leonardo de Moura
5b9befcdbf feat: infrastructure for grind order (#10553)
This PR implements infrastructure for the new `grind order` module.
2025-09-25 17:53:43 +00:00
Alex Keizer
188ef680da chore: ensure pass refers to SpecResult.pass in GuardMsgs (#10539)
This PR adds a `.` in front of `pass` in the `#guard_msgs`
implementation.

Previously, the match arm read `| pass => ...`. Presumably, `pass` was
intended to mean `SpecResult.pass`, but, this isn't in scope, so instead
`pass` here is a catch-all variable. By adding a dot, we ensure we
actually refer to the constant. Note that this was the last case in the
pattern-match, and since all other constructors were correctly
referenced, the only case that went to the fallback was
`SpecResult.pass`, so the code did the right thing. Still, by fixing
this, we prevent a surprise in the event that a new `SpecResult`
constructor is added.
2025-09-25 13:50:46 +00:00
Henrik Böving
5fd8c1b94d feat: new String.Slice API (#10514)
This PR defines the new `String.Slice` API.

Many of the core design principles of the API are taken over from Rust's
[string
library](https://doc.rust-lang.org/stable/std/string/struct.String.html).
2025-09-25 12:18:52 +00:00
Sebastian Ullrich
5ef7b45afa doc: meta modifier (#10554) 2025-09-25 11:45:54 +00:00
Mario Carneiro
9f41f3324a fix: make Substring.beq reflexive (#10552)
This PR ensures that `Substring.beq` is reflexive, and in particular
satisfies the equivalence `ss1 == ss2 <-> ss1.toString = ss2.toString`.

Closes #10511.

Note: I also fixed a strange line in the `String.extract` documentation
which looks like it may have been a copypasta, and added another example
to show how invalid UTF8 positions work, but the doc also makes a point
of saying that it is unspecified so maybe it would be better not to have
the example? 🤷
2025-09-25 05:08:41 +00:00
Henrik Böving
055060990c fix: use _Exit in the language server (#10538)
This PR fixes deadlocking `exit` calls in the language server.

We have previously observed deadlocking calls to `exit` inside of the
language server and deemed them irrelevant. However, child processes of
these deadlocking exiting processes can continue to consume a large
amount of CPU as they try to compile a library etc. Hence, this PR
switches to the MT safe `_Exit` inside of the language server,
in order to ensure the server finishes when it is told to.
2025-09-24 14:44:16 +00:00
Sebastian Graf
4c44f4ef7c chore: add fixed test case for #9363 (#10547) 2025-09-24 14:32:08 +00:00
Markus Himmel
d6cd738ab4 feat: redefine String, part two (#10457)
This PR introduces safe alternatives to `String.Pos` and `Substring`
that can only represent valid positions/slices.

Specifically, the PR

- introduces the predicate `String.Pos.IsValid`;
- proves several nontrivial equivalent conditions for
`String.Pos.IsValid`;
- introduces `String.ValidPos`, which is a `String.Pos` with an
`IsValid` proof;
- introduces `String.Slice`, which is like `Substring` but made from
`String.ValidPos` instead of `Pos`;
- introduces `String.Pos.IsValidForSlice`, which is like
`String.Pos.IsValid` but for slices;
- introduces `String.Slice.Pos`, which is like `String.ValidPos` but for
slices;
- introduces various functions for converting between the two types of
positions.

The API added in this PR is not complete. It will be expanded in future
PRs with addional operations and verification.
2025-09-24 13:36:55 +00:00
Markus Himmel
68409ef6fd chore: turn some crashes into errors (#8402)
This PR prevents some nonsensical code from crashing the server.

Specifically, the kernel is changed to
- properly check that passed expressions do not contain loose bvars,
which could lead to a segmentation fault on a well-crafted input
(discovered through fuzzing), and
- check that constants generated when creating a new inductive type do
not overwrite each other, which could lead to the kernel taking
something out of the environment and then casting it to something it
isn't.

Partially addresses #8258, but let's keep that one open until the error
message is a little better.

Fixes #10492.
2025-09-24 13:04:18 +00:00
Joachim Breitner
ca1101dddd feat: #print T.rec to show more information (#10543)
This PR lets `#print T.rec` show more information about a recursor, in
particular it's reduction rules.
2025-09-24 12:22:00 +00:00
Sebastian Graf
ce7a4f50be chore: add spec lemmas for MonadControl (#10544) 2025-09-24 12:16:06 +00:00
Sebastian Graf
eb9dd9a9e3 chore: add some missing spec lemmas (#10540) 2025-09-24 12:08:12 +00:00
Markus Himmel
b6198434f2 fix: String regressions (#10523)
This PR fixes some regressions introduced by #10304.
2025-09-24 12:01:50 +00:00
Joachim Breitner
1374445081 chore: update bench/riskv-ast.lean (#10505)
This PR disables `trace.profiler` in `bench/riskv-ast.lean`. We don't
want to optimize the trace profiler, but normal code.

While at it, I removed the `#exit` to cover more of the file.

While at it, also import the latest from from upstream.
2025-09-24 11:46:26 +00:00
Joachim Breitner
9df345e322 fix: .congr_simp for non-defs (#10508)
This PR allows `.congr_simp` theorems to be created not just for
definitoins, but any constant. This is important to make the machinery
work across module boundaries.

It also moves the `enableRealizationsForConst` for constructors to a
more sensible
place, and enables it for axioms.
2025-09-24 11:45:49 +00:00
Kim Morrison
3b2705d0df feat: helper functions for premise selection API (#10512)
This PR adds some helper functions for the premise selection API, to
assist implementers.

---------

Co-authored-by: Thomas Zhu <thomas.zhu.sh@hotmail.com>
2025-09-24 11:45:40 +00:00
Sebastian Ullrich
44a2b085c4 feat: scripts/Modulize.lean (#10460)
This PR introduces a simple script that adjusts module headers in a
package for use of the module system, without further minimizing import
or annotation use.

---------

Co-authored-by: Kim Morrison <477956+kim-em@users.noreply.github.com>
2025-09-24 11:40:17 +00:00
Joachim Breitner
7f18c734eb fix: simpHaveTelescope: calculate used fvars transitiviely (#10536)
This PR fixes `simp` in `-zeta -zetaUnused` mode from producing
incorrect proofs if in a `have` telescope a variable occurrs in the
type of the body only transitively. Fixes #10353.
2025-09-24 11:30:09 +00:00
Sebastian Ullrich
ac6ae51bce chore: minor module system fixes from batteries port (#10496) 2025-09-24 08:59:23 +00:00
Lean stage0 autoupdater
fd4a8c5407 chore: update stage0 2025-09-24 08:23:57 +00:00
Henrik Böving
2e5bbf4596 fix: #guard should work with the module system (#10535)
This PR ensures that `#guard` can be called under the module system
without issues.
2025-09-24 07:38:10 +00:00
David Thrane Christiansen
00b74e02cd feat: docstring role for module names, plus improved suggestions (#10533)
This PR adds a docstring role for module names, called `module`. It also
improves the suggestions provided for code elements, making them more
relevant and proposing `lit`.
2025-09-24 07:32:27 +00:00
Marc Huisinga
90db9ef006 feat: unknown identifier code actions for auto-implicits (#10442)
This PR ensures that unknown identifier code actions are provided on
auto-implicits.

Closes #8837.
2025-09-24 07:28:06 +00:00
Kim Morrison
3ddda9ae4d chore: adjust List.countP grind annotations (#10532) 2025-09-24 07:07:11 +00:00
Kim Morrison
ac0b82933f chore: add variant of Rat.ofScientific_def for grind (#10534) 2025-09-24 06:37:46 +00:00
Kim Morrison
d8219a37ef feat: grind linarith synthesis issues explain changes in behaviour (#10448)
This PR modifies the "issues" grind diagnostics prints. Previously we
would just describe synthesis failures. These messages were confusing to
users, as in fact the linarith module continues to work, but less
capably. For most of the issues, we now explain the resulting change in
behaviour. There is a still a TODO to explain the change when
`IsOrderedRing` is not available.
2025-09-24 04:02:35 +00:00
thorimur
7ea7acc687 chore: lower monad of addSuggestion(s) to CoreM (#10526) 2025-09-24 03:35:34 +00:00
Sofia Rodrigues
161a1c06a2 feat: add Std.Notify type (#10368)
This PR adds `Notify` that is a structure that is similar to `CondVar`
but it's used for concurrency. The main difference between
`Std.Sync.Notify` and `Std.Condvar` is that depends on a `Std.Mutex` and
blocks the entire thread that the `Task` is using while waiting. If I
try to use it with async and a lot of `Task`s like this:

```lean
def condvar : Async Unit := do
  let condvar ← Std.Condvar.new
  let mutex ← Std.Mutex.new false

  for i in [0:threads] do
    background do
      IO.println s!"start {i + 1}"
      await =<< (show IO (ETask _ _) from IO.asTask (mutex.atomically (condvar.wait mutex)))
      IO.println s!"end {i + 1}"

  IO.sleep 2000
  condvar.notifyAll
```

It causes some weird behavior because some tasks start running and get
notified, while others don’t, because `condvar.wait` blocks the `Task`
entire task and right now afaik it blocks an entire thread and cannot be
paused while doing blocking operations like that.

`Notify` uses `Promise`s so it’s better suited for concurrency. The
`Task` is not blocked while waiting for a notification which makes it
simpler for use cases that just involve notifying:

```lean
def notify : Async Unit := do
  let notify ← Std.Notify.new

  for i in [0:threads] do
    background do
      IO.println s!"start {i}"
      notify.wait
      IO.println s!"end {i}"

  IO.sleep 2000
  notify.notify
```

This PR depends on: #10366, #10367 and #10370.
2025-09-24 03:35:08 +00:00
Kim Morrison
781e3c6add chore: remove unhelpful grind annotations (#10435)
This PR removes some `grind` annotations for `Array.attach` and related
functions. These lemmas introduce lambda on the right hand side which
`grind` can't do much with. I've added a test file that verifies that
the theorems with removed annotations can actually be proved already by
grind. Removing the annotations will help with excessive instantiation.
2025-09-24 03:02:46 +00:00
Leonardo de Moura
b73b8a7edf feat: helper ordered ring theorems (#10529)
This PR adds some helper theorems for the upcoming `grind order` solver.
2025-09-24 03:01:19 +00:00
Sofia Rodrigues
94e5b66dfe feat: add AsyncStream, AsyncWrite and AsyncRead type classes (#10370)
This PR adds async type classes for streams.
2025-09-23 23:30:33 +00:00
Joachim Breitner
8443600762 chore: assert hasLooseBVar before shifting (#10528)
This assumptions seems to be violated in #10353, so maybe worth
asserting it here to more quickly stumble over it.
2025-09-23 20:49:04 +00:00
Garmelon
8b64425033 chore: set temci tags for the radar bench script (#10527)
The radar bench scripts at
https://github.com/leanprover/radar-bench-lean4/ split up the benchmarks
between the two runners based on the tags: One runner filters by the tag
`stdlib` while the other filters by the tag `other`. Only benchmarks
using one of these tags will be run, and any benchmark tagged with both
will waste electricity.

As far as I know, the tags are unused otherwise, so I just replaced all
the old tags.
2025-09-23 19:51:10 +00:00
David Thrane Christiansen
d96fd949ff fix: invalid docstring suggestions for attributes (#10522)
This also exposed an issue with `#guard_msgs` in Verso mode where the
docstring would log parse errors as if it contained Verso, even though
it actually worked. This has been fixed, and error messages improved as
well.
2025-09-23 16:18:21 +00:00
Sebastian Ullrich
d33aece210 feat: list definitions in defeq problems that could not be unfolded for lack of @[expose] (#10158)
This PR adds information about definitions blocked from unfolding via
the module system to type defeq errors.
2025-09-23 16:13:39 +00:00
Sebastian Graf
9a7bab5f90 chore: add documentation for mvcgen related definitions (#10525) 2025-09-23 15:59:58 +00:00
Kim Morrison
e2f87ed215 chore: lemma for unfolding eraseIdxIfInBounds (#10520) 2025-09-23 13:08:41 +00:00
Tom Levy
e42892cfb6 doc: fix comment about String.fromUTF8 replacing invalid chars (#10240)
Hi, the doc of `String.fromUTF8` previously said invalid characters are
replaced with 'A'. But the parameter `h : validateUTF8 a` guarantees
there are no invalid characters, so that explanation doesn't make sense
to me. This PR deletes that explanation (and fixes some unrelated
typos).

I also have a patch that uses `h` to prove each of the characters is
valid, eliminating the need for a default character
([pr/chore-String-fromUTF8-prove-valid](27f1ff36b2)),
would you be interested in merging that?

<details>
<summary>Notes on invalid characters from unchecked C++</summary>
I don't know if this function may be called from unchecked C++ with
invalid characters. If it may, I'm not sure what would happen with my
patched function... I'm not familiar with Lean's safety model, but it
seems like a bad idea to have a Lean function that takes a proof of a
proposition but is expected to operate in a certain way even if the
proposition is false. I think the safe approach is to have two functions
-- one that takes a proof and is only called from Lean, and another that
doesn't take a proof and replaces invalid chars (for use from C++, not
sure whether it's useful from Lean); I'd prefer to go even further and
report an error instead of silently replacing invalid characters (I'm
not sure if there is any easy way to report errors/panic in Lean code
called from C++).
</details>
2025-09-23 10:19:20 +00:00
Sebastian Ullrich
cc5c070328 fix: inline/specialize may only refer to publicly imported decls for now (#10494)
This PR resolves a potential bad interaction between the compiler and
the module system where references to declarations not imported are
brought into scope by inlining or specializing. We now proactively check
that declarations to be inlined/specialized only reference public
imports. The intention is to later resolve this limitation by moving out
compilation into a separate build step with its own import/incremental
system.
2025-09-23 09:58:14 +00:00
David Thrane Christiansen
f122454ef6 chore: cleanup and better docs for #10479 (#10504)
This PR cleans up a half-reverted refactor and adds documentation to
#10479.
2025-09-23 09:02:07 +00:00
Sebastian Graf
02f482129a fix: Use @[tactic_alt] for bv_decide, mvcgen and similar tactics (#10506)
This PR annotates the shadowing main definitions of `bv_decide`,
`mvcgen` and similar tactics in `Std` with the semantically richer
`tactic_alt` attribute so that `verso` will not warn about overloads.

This fixes leanprover/verso#535.
2025-09-23 07:40:02 +00:00
Kim Morrison
0807f73171 feat: basic premise selection algorithm based on MePo (#7844)
This PR adds a simple implementation of MePo, from "Lightweight
relevance filtering for machine-generated resolution problems" by Meng
and Paulson.

This needs tuning, but is already useful as a baseline or test case.

---------

Co-authored-by: Thomas Zhu <thomas.zhu.sh@hotmail.com>
2025-09-23 06:40:22 +00:00
Lean stage0 autoupdater
27fa5b0bb5 chore: update stage0 2025-09-23 06:22:49 +00:00
Alex Meiburg
8f9966ba74 doc: fix to new name for "Associative" in ac_rfl / ac_nf docstring (#10458)
This PR fixes the docstring for ac_rfl and ac_nf to correctly refer to
`Std.Associative` instead of the old name `Associative`; ditto
`Commutative`.
2025-09-23 05:52:05 +00:00
Sofia Rodrigues
eabd7309b7 feat: add vectored write and fix rc issue in tcp and udp cancel function (#10487)
This PR adds vectored write and fix rc issues in tcp and udp cancel
functions.
2025-09-22 17:02:57 +00:00
Sebastian Graf
795d13ddce feat: account for tactic_alt in missing docs linter (#10507)
This PR makes the missing docs linter aware of `tactic_alt`.
2025-09-22 16:23:24 +00:00
Kim Morrison
2b23afdfab chore: remove >6 month old deprecations (#10446) 2025-09-22 12:47:11 +00:00
Kim Morrison
20b0bd0a20 chore: upstream rangeOfStx? from Batteries (#10490)
This PR upstreams a helper function that is used in ProofWidgets.

---------

Co-authored-by: Marc Huisinga <mhuisi@protonmail.com>
2025-09-22 12:21:14 +00:00
Kim Morrison
979c2b4af0 chore: add grind annotations for List.not_mem_nil (#10493) 2025-09-22 12:18:03 +00:00
Kim Morrison
b3cd5999e7 chore: normalize empty ByteArrays to .empty (#10501) 2025-09-22 12:06:29 +00:00
Kim Morrison
a4dcb25f69 chore: add limited public API for builtinRpcProcedures (#10499)
This is not a complete public API, just enough to avoid an `open
private` in ProofWidgets.
2025-09-22 11:20:25 +00:00
Henrik Böving
85ce814689 fix: constant folding for UIntX (#10495)
This PR fixes constant folding for UIntX in the code generator. This
optimization was previously simply dead code due to the way that uint
literals are encoded.
2025-09-22 10:06:24 +00:00
Leonardo de Moura
9fc18b8ab4 doc: extra grind docstrings (#10486)
This PR adds and expands `grind` related docstrings.
2025-09-22 03:27:48 +00:00
Leonardo de Moura
852a3db447 chore: improve grind imports (#10491) 2025-09-22 01:25:41 +00:00
Lean stage0 autoupdater
d0d5d4ca39 chore: update stage0 2025-09-21 11:13:12 +00:00
Sebastian Ullrich
b32f3e8930 chore: revert "feat: add vectored write and fix rc issue in tcp and udp cancel functions" (#10485)
Reverts leanprover/lean4#10367 due to Windows build failure
2025-09-21 10:43:46 +00:00
David Thrane Christiansen
34f5fba54d chore: remove bootstrapping workaround (#10484)
This PR removes temporary bootstrapping workarounds introduced in PR
#10479.
2025-09-21 07:36:49 +00:00
Leonardo de Moura
4c9601e60f feat: support for injective functions in grind (#10483)
This PR completes support for injective functions in grind. See
examples:
```lean

/-! Add some injectivity theorems. -/

def double (x : Nat) := 2*x

@[grind inj] theorem double_inj : Function.Injective double := by
  grind [Function.Injective, double]

structure InjFn (α : Type) (β : Type) where
  f : α → β
  h : Function.Injective f

instance : CoeFun (InjFn α β) (fun _ => α → β) where
  coe s := s.f

@[grind inj] theorem fn_inj (F : InjFn α β) : Function.Injective (F : α → β) := by
  grind [Function.Injective, cases InjFn]

def toList (a : α) : List α := [a]

@[grind inj] theorem toList_inj : Function.Injective (toList : α → List α) := by
  grind [Function.Injective, toList]

/-! Examples -/

example (x y : Nat) : toList (double x) = toList (double y) → x = y := by
  grind

example (f : InjFn (List Nat) α) (x y z : Nat)
    : f (toList (double x)) = f (toList y) →
      y = double z →
      x = z := by
  grind
```
2025-09-21 06:31:46 +00:00
Leonardo de Moura
42be7bb5c7 fix: [grind inj] attribute (#10482)
This PR fixes symbol collection for the `@[grind inj]` attribute.
2025-09-21 04:14:17 +00:00
Leonardo de Moura
5f68c1662d refactor: generalize theorem activation in grind (#10481)
This PR generalizes the theorem activation function used in `grind`. 
The goal is to reuse it to implement the injective function module.
2025-09-21 02:50:55 +00:00
Leonardo de Moura
2d14d51935 fix: equality resolution in grind (#10480)
This PR fixes a bug in the equality resolution frontend used in `grind`.
2025-09-21 02:40:38 +00:00
Lean stage0 autoupdater
7cbeb14e46 chore: update stage0 2025-09-20 22:47:35 +00:00
David Thrane Christiansen
cee2886154 feat: improvements to Verso docstrings (#10479)
This PR implements module docstrings in Verso syntax, as well as adding
a number of improvements and fixes to Verso docstrings in general. In
particular, they now have language server support and are parsed at
parse time rather than elaboration time, so the snapshot's syntax tree
includes the parsed documentation.
2025-09-20 22:05:57 +00:00
Leonardo de Moura
35764213fc fix: grind sort internalization (#10477)
This PR ensures sorts are internalized by `grind`.
2025-09-20 18:31:20 +00:00
Sofia Rodrigues
6b92cbdfa4 feat: add vectored write and fix rc issue in tcp and udp cancel functions (#10367)
This PR adds vectored write for TCP and UDP (that helps a lot with not
copying the arrays over and over) and fix a RC issue in TCP and UDP
cancel functions with the line `lean_dec((lean_object*)udp_socket);` and
a similar one that tries to decrement the object inside of the `socket`.
2025-09-20 17:01:20 +00:00
Leonardo de Moura
72bb7cf364 fix: infer_let in the kernel (#10476)
This PR fixes the dead `let` elimination code in the kernel's
`infer_let` function.

Closes #10475
2025-09-20 16:26:46 +00:00
Sofia Rodrigues
4881c3042e refactor: replace Task with Async and minor changes to some basic Async functions (#10366)
This PR refactors the Async module to use the `Async` type in all of the
`Async` files.
2025-09-20 16:23:06 +00:00
Leonardo de Moura
ec7add0b48 doc: ! modifier in grind parameters (#10474)
This PR adds a doc string for the `!` parameter modifier in `grind`.
2025-09-20 08:06:05 +00:00
Leonardo de Moura
9b842b7554 fix: message context in grind code actions (#10473)
This PR ensures the code action messages produced by `grind` include the
full context
2025-09-20 08:02:12 +00:00
Leonardo de Moura
fc718eac88 feat: code action for grind parameters (#10472)
This PR adds a code action for `grind` parameters. We need to use
`set_option grind.param.codeAction true` to enable the option. The PR
also adds a modifier to instruct `grind` to use the "default" pattern
inference strategy.
2025-09-20 07:30:39 +00:00
Michał Dobranowski
8b3c82cce2 fix: lake: GH action template condition (#10459)
This PR fixes a conditional check in a GitHub Action template generated
by Lake.

Closes #10420.
2025-09-20 06:33:42 +00:00
Mac Malone
0d1b7e6c88 chore: lake: fix tests/lean (#10470)
The ordering of the `--setup` JSON object changed at some point,
breaking this test. This PR fixes it by avoiding the potential for such
breakages.
2025-09-20 02:11:50 +00:00
Leonardo de Moura
d898c9ed17 fix: grind canonicalizer (#10469)
This PR fixes an incorrect optimization in the `grind` canonicalizer.
See the new test for an example that exposes the problem.
2025-09-20 01:24:54 +00:00
Leonardo de Moura
c6abc3c036 feat: improve grind diagnostics (#10466)
This PR reduces noise in the 'Equivalence classes' section of the
`grind` diagnostics. It now uses a notion of *support expressions*.
Right now, it is hard-coded, but we will probably make it extensible in
the future. The current definition is

- `match`, `ite` and `dite`-applications. They have builtin support in
`grind`.
- Cast-like applications used by `grind`: `toQ`, `toInt`, `Nat.cast`,
`Int.cast`, and `cast`
- `grind` gadget applications (e.g., `Grind.nestedDecidable`)
- Projections of constructors (e.g., `{ x := 1, y := 2}.x`)
- Auxiliary arithmetic terms constructed by solvers such as `cutsat` and
`ring`.

If an equivalence class contains at most one non-support term, it goes
into the “others” bucket. Otherwise, we display the non-support elements
and place the support terms in a child node.

**BEFORE**:
<img width="1397" height="1558" alt="image"
src="https://github.com/user-attachments/assets/4fd4de31-7300-4158-908b-247024381243"
/>

**AFTER**:
<img width="840" height="340" alt="image"
src="https://github.com/user-attachments/assets/05020f34-4ade-49bf-8ccc-9eb0ba53c861"
/>

**Remark**: No information is lost; it is just grouped differently."
2025-09-19 23:44:30 +00:00
Leonardo de Moura
d07862db2a chore: skip cast-like operations in grind mbtc (#10465)
This PR skips cast-like helper `grind` functions during `grind mbtc`
2025-09-19 21:12:25 +00:00
Leonardo de Moura
8a79ef3633 chore: missing grind normalization (#10463)
This PR adds `Nat.sub_zero` as a `grind` normalization rule.
2025-09-19 18:50:39 +00:00
Leonardo de Moura
b1c82f776b chore: mbtc in grind cutsat (#10462)
Minor improvement to `grind mbtc` in `cutsat`.
2025-09-19 18:47:10 +00:00
Leonardo de Moura
f278f31469 fix: unnecessary case-splits in grind mbtc (#10461)
This PR fixes unnecessary case splits generated by the `grind mbtc`
module. Here, `mbtc` stands for model-based theory combination.
2025-09-19 17:24:57 +00:00
Joachim Breitner
38b4062edb feat: linear-size Ord instance (#10270)
This PR adds an alternative implementation of `Deriving Ord` based on
comparing `.ctorIdx` and using a dedicated matcher for comparing same
constructors (added in #10152). The new option
`deriving.ord.linear_construction_threshold` sets the constructor count
threshold (10 by default) for using the new construction.

It also (unconditionally) changes the implementation for enumeration
types to simply compare the `ctorIdx`.
2025-09-19 14:13:57 +00:00
Sebastian Graf
ae8dc414c3 feat: mvcgen invariants? to scaffold initial invariants (#10456)
This PR implements `mvcgen invariants?` for providing initial invariant
skeletons for the user to flesh out. When the loop body has an early
return, it will helpfully suggest `Invariant.withEarlyReturn ...` as a
skeleton.

```lean
def mySum (l : List Nat) : Nat := Id.run do
  let mut acc := 0
  for x in l do
    acc := acc + x
  return acc

/--
info: Try this:
  invariants
    · ⇓⟨xs, acc⟩ => _
-/
#guard_msgs (info) in
theorem mySum_suggest_invariant (l : List Nat) : mySum l = l.sum := by
  generalize h : mySum l = r
  apply Id.of_wp_run_eq h
  mvcgen invariants?
  all_goals admit

def nodup (l : List Int) : Bool := Id.run do
  let mut seen : HashSet Int := ∅
  for x in l do
    if x ∈ seen then
      return false
    seen := seen.insert x
  return true

/--
info: Try this:
  invariants
    · Invariant.withEarlyReturn (onReturn := fun r acc => _) (onContinue := fun xs acc => _)
-/
#guard_msgs (info) in
theorem nodup_suggest_invariant (l : List Int) : nodup l ↔ l.Nodup := by
  generalize h : nodup l = r
  apply Id.of_wp_run_eq h
  mvcgen invariants?
  all_goals admit
```
2025-09-19 14:05:24 +00:00
Sebastian Ullrich
7822ee4500 fix: check that compiler does not infer inconsistent types between modules (#10418)
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.
2025-09-19 12:36:47 +00:00
Joachim Breitner
8f22c56420 refactor: less public section in Eqns.lean files (#10454) 2025-09-19 11:52:56 +00:00
Joachim Breitner
0e122870be perf: mkNoConfusionCtors: cheaper inferType (#10455)
This PR changes `mkNoConfusionCtors` so that its use of `inferType` does
not have to reduce `noConfusionType`, to make #10315 really effective.
2025-09-19 10:51:17 +00:00
Sebastian Graf
13c23877d4 fix: reduce through lets in mvcgen main loop (#10453)
This PR makes `mvcgen` reduce through `let`s, so that it progresses over
`(have t := 42; fun _ => foo t) 23` by reduction to `have t := 42; foo
t` and then introducing `t`.
2025-09-19 08:21:04 +00:00
Kim Morrison
7fba12f8f7 chore: add test for website primes example (#10451)
(This test is currently failing. We either need to change the failing
line to `grind [!factorial_pos]`, or again change the behaviour of
grind.)
2025-09-19 04:56:28 +00:00
Kim Morrison
abb487a0c0 chore: include lean-lang.org in release checklist (#10450) 2025-09-19 03:46:32 +00:00
Leonardo de Moura
1091053824 chore: reportIssue! at grind ematch (#10449)
This PR ensures that issues reported by the E-matching module are
displayed only when `set_option grind.debug true` is enabled. Users
reported that these messages are too distracting and not very useful.
They are more valuable for library developers when annotating their
libraries.
2025-09-19 02:43:03 +00:00
Leonardo de Moura
545bd8a96c feat: add [grind inj] attribute (#10447)
This PR adds the `[grind inj]` attribute for marking injectivity
theorems for `grind`.
2025-09-19 00:49:05 +00:00
Sebastian Ullrich
2f9618f76b chore: make def used by proofwidgets public again (#10437) 2025-09-18 21:30:23 +00:00
Joachim Breitner
fa36fcd448 feat: linear-size BEq instance (#10268)
This PR adds an alternative implementation of `DerivingBEq` based on
comparing `.ctorIdx` and using a dedicated matcher for comparing same
constructors (added in #10152), to avoid the quadratic overhead of the
default match implementation. The new option
`deriving.beq.linear_construction_threshold` sets the constructor count
threshold (10 by default) for using the new construction. Such instances
also allow `deriving ReflBEq, LawfulBeq`, although these proofs for
these properties are still quadratic.
2025-09-18 21:27:25 +00:00
Henrik Böving
9a3b4b2716 fix: overeager inc insertion for large uint constants (#10444)
This PR fixes an overeager insertion of `inc` operations for large uint
constants.


Closes: #10443
2025-09-18 20:54:19 +00:00
Leonardo de Moura
9fb5ab8450 feat: helper definitions for injective function support in grind (#10445)
This PR adds helper definitions in preparation for the upcoming
injective function support in `grind`.
2025-09-18 19:42:15 +00:00
Leonardo de Moura
a62c0bce77 chore: missing grind modifier (#10441) 2025-09-18 14:44:57 +00:00
Lean stage0 autoupdater
3ce554abd7 chore: update stage0 2025-09-18 13:48:00 +00:00
Joachim Breitner
257c347f9f feat: reduceCtorIdx simproc (#10440)
This PR adds the `reduceCtorIdx` simproc which recognizes and reduces
`ctorIdx` applications. This is not on by default yet because it does
not use the discrimination tree (yet).
2025-09-18 13:05:14 +00:00
Sebastian Ullrich
ca1315e3ba fix: backtracking kernel errors under Elab.async (#10438)
This PR fixes an issue where notations and other overloadings would
signal kernel errors even though there exists a successful
interpretation.
2025-09-18 12:33:57 +00:00
Markus Himmel
197bc6cb66 feat: redefine String, part one (#10304)
This PR redefines `String` to be the type of byte arrays `b` for which
`b.IsValidUtf8`.

This moves the data model of strings much closer to the actual data
representation at runtime.

In the near future, we will

- provide variants of `String.Pos` and `Substring` that only allow for
valid positions
- redefine all `String` functions to be much closer to their C++
implementations

In the near-to-medium future we will then provide comprehensive
verification of `String` based on these refactors.
2025-09-18 11:36:52 +00:00
Luisa Cicolini
02ca710872 feat: add BitVec.ctz to bv_decide (#9298)
This PR adds support the Count Trailing Zeros operation `BitVec.ctz` to
the bitvector library and to `bv_decide`, relying on the existing `clz`
circuit. We also build some theory around `BitVec.ctz` (analogous to the
theory existing for `BitVec.clz`) and introduce lemmas
`BitVec.[ctz_eq_reverse_clz, clz_eq_reverse_ctz, ctz_lt_iff_ne_zero,
getLsbD_false_of_lt_ctz, getLsbD_true_ctz_of_ne_zero,
two_pow_ctz_le_toNat_of_ne_zero, reverse_reverse_eq,
reverse_eq_zero_iff]`.

`ctz` operation is common in numerous compiler intrinsics (see
[here](https://clang.llvm.org/docs/LanguageExtensions.html#intrinsics-support-within-constant-expressions))
and architectures (see
[here](https://en.wikipedia.org/wiki/Find_first_set)).

---------

Co-authored-by: Siddharth <siddu.druid@gmail.com>
2025-09-18 08:38:07 +00:00
Kim Morrison
3fbf080d72 chore: update script/release_notes.py for changelog-tactics (#10436) 2025-09-18 07:22:53 +00:00
Kim Morrison
4379002d05 feat: add reprove command for re-proving theorems with a specified tactic (#10434)
This PR adds `reprove N by T`, which effectively elaborates `example
type_of% N := by T`. It supports multiple identifiers. This is useful
for testing tactics.


🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-18 06:29:53 +00:00
Lean stage0 autoupdater
5d50ec90f9 chore: update stage0 2025-09-18 04:56:02 +00:00
Leonardo de Moura
6ca699b1ff feat: enable new E-matching pattern inference procedure in grind (#10432)
This PR enables the new E-matching pattern inference heuristic for
`grind`, implemented in PR #10422.
**Important**: Users can still use the old pattern inference heuristic
by setting:

```lean
set_option backward.grind.inferPattern true
```

In PR #10422, we introduced the new modifier `@[grind!]` for enabling
the minimal indexable subexpression condition. This option can now also
be set in `grind` parameters. Example:

```lean
opaque f : Nat → Nat
opaque fInv : Nat → Nat 
axiom fInv_f : fInv (f x) = x

/-- trace: [grind.ematch.pattern] fInv_f: [f #0] -/
#guard_msgs in 
set_option trace.grind.ematch.pattern true in
example {x y} : f x = f y → x = y := by
  /-
  The modifier `!` instructs `grind` to use the minimal indexable subexpression 
  (i.e., `f x` in this case).   
  -/
  grind [!fInv_f] 
```
2025-09-18 04:13:54 +00:00
Kim Morrison
c2d56fa031 chore: custom steps in release checklist for CSLib (#10433) 2025-09-18 01:12:00 +00:00
Lean stage0 autoupdater
b6d590ccc3 chore: update stage0 2025-09-17 21:44:32 +00:00
Sebastian Ullrich
719765ec5c feat: overhaul meta system (#10362)
This PR refines and clarifies the `meta` phase distinction in the module
system.

* `meta import A` without `public` now has the clarified meaning of
"enable compile-time evaluation of declarations in or above `A` in the
current module, but not downstream". This is now checked statically by
enforcing that public meta defs, which therefore may be referenced from
outside, can only use public meta imports, and that global evaluating
attributes such as `@[term_parser]` can only be applied to public meta
defs.
* `meta def`s may no longer reference non-meta defs even when in the
same module. This clarifies the meta distinction as well as improves
locality of (new) error messages.
* parser references in `syntax` are now also properly tracked as meta
references.
* A `meta import` of an `import` now properly loads only the `.ir` of
the nested module for the purposes of execution instead of also making
its declarations available for general elaboration.
* `initialize` is now no longer being run on import under the module
system, which is now covered by `meta initialize`.
2025-09-17 21:04:29 +00:00
Lean stage0 autoupdater
11b0e7d89c chore: update stage0 2025-09-17 18:46:58 +00:00
Leonardo de Moura
37f3f0e1e2 feat: minimal indexable subexpressions in grind parameters (#10430)
This PR ensures users can select the "minimal indexable subexpression"
condition in `grind` parameters. Example, they can now write `grind [!
-> thmName]`. `grind?` will include the `!` modifier whenever users had
used `@[grind!]`. This PR also fixes a missing case in the new pattern
inference procedure.
It also adjusts some `grind` annotations and tests in preparation for
setting the new pattern inference heuristic as the new default.
2025-09-17 18:04:05 +00:00
Henrik Böving
85645958f9 fix: overeager specialisation reuse in codegen (#10429)
This PR fixes and overeager reuse of specialisation in the code
generator.

The issue was originally discovered in
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Miscompilation.20.28incorrect.20code.29.20in.20new.20compiler/near/540037917
and occurs because the specialisation cache didnt't take the name of
alternatives in pattern matches
into account.
2025-09-17 17:35:40 +00:00
Leonardo de Moura
a80169165e chore: missing grind modifiers and local grind theorems config (#10428)
This PR makes explicit missing `grind` modifiers, and ensures `grind`
uses "minIndexable" for local theorems.
2025-09-17 16:15:16 +00:00
Robert J. Simmons
8dca311ba5 doc: update URLs that are currently pointing to redirects (#10397)
This PR updates several URLs that are currently pointing to redirects on
lean-lang.org, most importantly a few in the top-level README
2025-09-17 15:50:07 +00:00
Lean stage0 autoupdater
e6dfde1ad6 chore: update stage0 2025-09-17 14:32:29 +00:00
Joachim Breitner
e532ce95ce refactor: change how equations for structural recursion are proved (#10415)
This PR changes the order of steps tried when proving equational
theorems for structural recursion. In order to avoid goals that `split`
cannot handle, avoid unfolding the LHS of the equation to `.brecOn` and
`.rec` until after the RHS has been split into its final cases.

Fixes: #10195
2025-09-17 13:46:45 +00:00
Joachim Breitner
e74b81169d feat: split to generalize proof discriminants (#10425)
This PR lets the `split` tactic generalize discriminants that are not
free variables and proofs using `generalize`. If the only
non-fvar-discriminants are proofs, then this avoids the more elaborate
generalization strategy of `split`, which can fail with dependent
motives, thus mitigating issue #10424.
2025-09-17 12:18:30 +00:00
Markus Himmel
cf8ffc28d3 chore: kernel changes ahead of String redefinition (#10330)
This PR changes the defeq algorithm to perform `whnf` on the `String.mk`
expression it creates for string literals.

This is currently a no-op, but will no longer be one once `String` is
redefined so that `String.mk` is a regular function instead of a
constructor.
2025-09-17 09:12:07 +00:00
Marc Huisinga
d625aaa96f feat: server-side for trace search (#10365)
This PR implements the server-side for a new trace search mechanism in
the InfoView.

Demo:
![Search
demo](https://github.com/user-attachments/assets/f8f1cdfd-a4f2-4258-8cb8-360f64ea06e9)
2025-09-17 08:58:56 +00:00
Lean stage0 autoupdater
89e4f9815f chore: update stage0 2025-09-17 09:11:32 +00:00
Sebastian Ullrich
9002cc8761 fix: elaborate private inductive ctor in the private scope (#10423) 2025-09-17 08:39:27 +00:00
Lean stage0 autoupdater
5a7d663624 chore: update stage0 2025-09-17 03:26:25 +00:00
Leonardo de Moura
efb398b040 feat: new grind pattern inference heuristic and code action (#10422)
This PR implements the new E-matching pattern inference heuristic for
`grind`. It is not enabled yet. You can activate the new behavior using
`set_option backward.grind.inferPattern false`. Here is a summary of the
new behavior.

* `[grind =]`, `[grind =_]`, `[grind _=_]`, `[grind <-=]`: no changes;
we keep the current behavior.
  
* `[grind ->]`, `[grind <-]`, `[grind =>]`, `[grind <=]`: we stop using
the *minimal indexable subexpression* and instead use the first
indexable one.

* `[grind! <mod>]`: behaves like `[grind <mod>]` but uses the minimal
indexable subexpression restriction. We generate an error if the user
writes `[grind! =]`, `[grind! =_]`, `[grind! _=_]`, or `[grind! <-=]`,
since there is no pattern search in these cases.
  
* `[grind]`: it tries `=`, `=_`, `<-`, `->`, `<=`, `=>` with and without
the minimal indexable subexpression restriction. For the ones that work,
we generate a code action to encourage users to select the one they
prefer.

* `[grind!]`: it tries `<-`, `->`, `<=`, `=>` using the minimal
indexable subexpression restriction. For the ones that work, we generate
a code action to encourage users to select the one they prefer.

* `[grind? <mod>]`: where `<mod>` is one of the modifiers above, it
behaves like `[grind <mod>]` but also displays the pattern.
  
Example:
```lean
/--
info: Try these:
  • [grind =] for pattern: [f (g #0)]
  • [grind =_] for pattern: [r #0 #0]
  • [grind! ←] for pattern: [g #0]
-/
#guard_msgs in
@[grind] axiom fg₇ : f (g x) = r x x
```
2025-09-17 02:44:11 +00:00
Leonardo de Moura
4cbd1a439a feat: non-commutative semiring normalizer in grind (#10421)
This PR adds a normalizer for non-commutative semirings to `grind`.
Examples:
```lean
open Lean.Grind
variable (R : Type u) [Semiring R]

example (a b c : R) : a * (b + c) = a * c + a * b := by grind
example (a b : R) : (a + 2 * b)^2 = a^2 + 2 * a * b + 2 * b * a + 4 * b^2 := by grind
example (a b : R) : b^2 + (a + 2 * b)^2 = a^2 + 2 * a * b + b * (1+1) * a * 1 + 5 * b^2 := by grind
example (a b : R) : a^3 + a^2*b + a*b*a + b*a^2 + a*b^2 + b*a*b + b^2*a + b^3 = (a+b)^3 := by grind
```
2025-09-16 20:15:38 +00:00
Leonardo de Moura
20873d5d72 feat: helper theorem for normalizing non-commutative semirings (#10419)
This PR adds the helper theorem `eq_normS_nc` for normalizing
non-commutative semirings. We will use this theorem to justify
normalization steps in the `grind ring` module.
2025-09-16 18:09:34 +00:00
Leonardo de Moura
4c1830e5ae refactor: semiring support in grind ring (#10403)
This PR reduces a bit of redundancy in the `grind ring`.
2025-09-16 17:37:55 +00:00
Joachim Breitner
7b75db7c6e refactor: use deriving LawfulBEq in Init (#10411)
This PR starts using `deriving LawfulBEq` in `Init`, removing some hairy
hand-rolled proofs.
2025-09-16 16:26:32 +00:00
Joachim Breitner
8d418201a6 fix: use with_reducible in deriving_LawfulEq_tactic_step (#10417)
This PR changes the automation in `deriving_LawfulEq_tactic_step` to use
`with_reducible` when asserting the shape of the goal using `change`, so
that we do not accidentally unfold `x == x'` calls here. Fixes #10416.
2025-09-16 16:07:42 +00:00
Lean stage0 autoupdater
850a4c897f chore: update stage0 2025-09-16 13:43:34 +00:00
Joachim Breitner
186f5a6960 feat: deriving ReflBEq and LawfulBEq (#10351)
This PR adds the ability to do `deriving ReflBEq, LawfulBEq`. Both
classes have to listed in the `deriving` clause. For `ReflBEq`, a simple
`simp`-based proof is used. For `LawfulBEq`, a dedicated,
syntax-directed tactic is used that should work for derived `BEq`
instances. This is meant to work with `deriving BEq` (but you can try to
use it on hand-rolled `@[methods_specs] instance : BEq…` instances).
Does not support mutual or nested inductives.
2025-09-16 12:58:01 +00:00
Lean stage0 autoupdater
917715c862 chore: update stage0 2025-09-16 11:06:37 +00:00
Joachim Breitner
50435417ac chore: remove comment from src/stdlib_flags.h (#10409)
This PR removes an update-stage0-comment from
`src/stdlib_flags.h`. Again. Sorry for that.
2025-09-16 10:39:27 +00:00
Joachim Breitner
9deff2751f refactor: use reduceBEq in Init (#10398)
This PR uses the `reduceBEq` simproc in Init, but mostly only for
testing, because afer #10351 this code will be derived.
2025-09-16 10:35:46 +00:00
Joachim Breitner
f3d93970dc feat: @[method_specs_simp] in Init (#10407)
This PR adds `@[method_specs_simp]` in `Init` for type classes like
`HAppend`.
2025-09-16 10:27:33 +00:00
Lean stage0 autoupdater
d1577fda7a chore: update stage0 2025-09-16 09:49:47 +00:00
Joachim Breitner
ca10fd7c4f fix: method spec theorems to be private when appropriate (#10406)
This PR improves upon #10302 to properly make the method spec theorems
private if the implementation function is not exposed.
2025-09-16 09:20:04 +00:00
Kim Morrison
a1cd945e82 chore: remove deprecated Xor (#10404) 2025-09-16 03:41:20 +00:00
Kim Morrison
9c372b9bc2 chore: begin development cycle for v4.25.0 (#10402) 2025-09-16 00:25:06 +00:00
Kim Morrison
38214ac121 chore: fix to release scripts (#10401) 2025-09-16 00:23:55 +00:00
Lean stage0 autoupdater
6d30aeefe5 chore: update stage0 2025-09-15 17:51:09 +00:00
Kyle Miller
112fa51e08 fix: keep abstract nested proofs procedure from hiding sorry warning (#10388)
This PR fixes a bug where definitions with nested proofs that contain
`sorry` might not report "warning: declaration uses 'sorry'" if the
proof has the same type as another nested proof from a previous
declaration. The bug only affected log messages; `#print axioms` would
still correctly report uses of `sorryAx`.

The fix is that now the abstract nested proofs procedure does not
consult the aux lemma cache if the proof contains a `sorry`.

Closes #10196
2025-09-15 17:07:49 +00:00
David Thrane Christiansen
9b53e39804 feat: activate Verso docstring builtins (#10386)
This PR activates the builtin expanders for Verso docstrings.
2025-09-15 17:07:33 +00:00
Kyle Miller
ede1acfb44 fix: let anonymous constructor notation elaborate with insufficient arguments (#10391)
This PR gives anonymous constructor notation (`⟨x,y⟩`) an error recovery
mechanism where if there are not enough arguments then synthetic sorries
are inserted for the missing arguments and an error is logged, rather
than outright failing.

Closes #9591.
2025-09-15 16:44:34 +00:00
Kyle Miller
0799e5c4e9 fix: make sure error ranges for if tactic are correct (#10392)
This PR fixes an issue with the `if` tactic where errors were not placed
at the correct source ranges. It also adds some error recovery to avoid
additional errors about unsolved goals on the `if` token when the tactic
has incomplete syntax.

Closes #7972
2025-09-15 16:40:11 +00:00
Lean stage0 autoupdater
32a4c88986 chore: update stage0 2025-09-15 17:07:15 +00:00
Joachim Breitner
4cf3c0ae67 feat: reduceBEq and reduceOrd simprocs (#10394)
This PR adds the `reduceBEq` and `reduceOrd` simprocs. They rewrite
occurrences of `_ == _` resp. `Ord.compare _ _` if both arguments are
constructors and the corresponding instance has been marked with
`@[method_specs]` (introduced in #10302), which now by default is the
case for derived instances.
2025-09-15 16:24:44 +00:00
Lean stage0 autoupdater
06ba748221 chore: update stage0 2025-09-15 15:31:41 +00:00
Joachim Breitner
d2d32f13c0 chore: remove comment from src/stdlib_flags.h (#10396)
This PR removes an update-stage0-comment from
`src/stdlib_flags.h`; these comments should be added to
`stage0/src/stdlib_flags.h`.
2025-09-15 15:03:12 +00:00
Joachim Breitner
9aa6448fa9 feat: use @[method_specs] when deriving BEq and Ord (#10346)
This PR lets `deriving BEq` and `deriving Ord` use `@[method_specs]`
from #10302 when applicable (i.e. when not using `partial`).
2025-09-15 14:58:00 +00:00
Sofia Rodrigues
3bea7e209e feat: add signal handling support using libuv (#9258)
This PR adds support for signal handlers to the Lean standard library.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
2025-09-15 13:09:50 +00:00
Joachim Breitner
88fa4212d7 feat: @[method_specs] to generate specification theorems from class instances (#10302)
This PR introduces the `@[specs]` attribute. It can be applied to
(certain) type class instances and define “specification theorems” for
the class’ operations, by taking the equational theorems of the
implementation function mentioned in the type class instance and
rephrasing them in terms of the overloaded operations. Fixes #5295.

Example:

```
inductive L α where
  | nil  : L α
  | cons : α → L α → L α

def L.beqImpl [BEq α] : L α → L α → Bool
  | nil, nil           => true
  | cons x xs, cons y ys => x == y && L.beqImpl xs ys
  | _, _               => false

@[method_specs] instance [BEq α] : BEq (L α) := ⟨L.beqImpl⟩

/--
info: theorem instBEqL.beq_spec_2.{u_1} : ∀ {α : Type u_1} [inst : BEq α] (x_2 : α) (xs : L α) (y : α) (ys : L α),
  (L.cons x_2 xs == L.cons y ys) = (x_2 == y && xs == ys)
-/
#guard_msgs(pass trace, all) in
#print sig instBEqL.beq_spec_2
```

It also introduces the `method_specs_norm` simpset to allow registering
further normalization of the theorems. The intended use of this is to
rewrite, say, `Append.append` to the `HAppend.hAppend` (i.e. `++`) that
the user wants to see. Library annotations to follow in a separate PR.
2025-09-15 11:17:06 +00:00
David Thrane Christiansen
97464c9d7f fix: trailing whitespace setting for string literals was ignored (#10389)
This PR fixes a bug where string literal parsing ignored its trailing
whitespace setting.
2025-09-15 09:51:56 +00:00
Sebastian Ullrich
8df968de01 feat: have example default to the private scope (#10168) 2025-09-15 09:10:56 +00:00
Lean stage0 autoupdater
d869c38e7b chore: update stage0 2025-09-15 05:12:36 +00:00
Kim Morrison
4d8d502754 chore: remove bad grind annotation on List.eq_nil_of_map_eq_nil (#10356) 2025-09-15 04:33:16 +00:00
David Thrane Christiansen
8e1df86939 feat: improvements to Verso docstrings (#10382)
This PR makes the builtin Verso docstring elaborators bootstrap
correctly, adds the ability to postpone checks (which is necessary for
resolving forward references and bootstrapping issues), and fixes a
minor parser bug.
2025-09-15 04:28:29 +00:00
Kim Morrison
4ff33eaef5 feat: updates to release process for cslib (#10385)
This PR updates the release checklist scripts to handle a corner case in
Cslib.
2025-09-15 01:41:17 +00:00
Kim Morrison
22a4cab8c7 feat: updates to release process for v4.23.0 (#10383)
This PR includes some improvements to the release process, making the
updating of `stable` branches more robust, and including `cslib` in the
release checklist.
2025-09-14 23:52:19 +00:00
Lean stage0 autoupdater
1e12cdddc0 chore: update stage0 2025-09-14 22:54:32 +00:00
Kyle Miller
cab33ac1da feat: syntax name heuristic for unicode(...) (#10381)
This PR sets the `syntax` naming heuristic for `unicode(" → ", " -> ")`
to use `→` rather than `→->`.

Continuation of #10373.
2025-09-14 21:53:48 +00:00
Leonardo de Moura
6b97e41650 feat: sanity check for instances in grind ring (#10380)
This PR implements sanity checks in the `grind ring` module to ensure
the instances synthesized by type class resolution are definitionally
equal to the corresponding ones in the `grind` core classes. The
definitional equality test is performed with reduction restricted to
reducible definitions and instances.
2025-09-14 21:04:40 +00:00
Lean stage0 autoupdater
c2521e94e1 chore: update stage0 2025-09-14 21:03:42 +00:00
Kyle Miller
f771dea78b fix: make sure app elaborator eta feature does not result in capturable variables (#10377)
This PR fixes an issue where the "eta feature" in the app elaborator,
which is invoked when positional arguments are skipped due to named
arguments, results in variables that can be captured by those named
arguments. Now the temporary local variables that implement this feature
get fresh names. The names used for the closed lambda expression still
use the original parameter names.

Closes #6373
2025-09-14 20:19:50 +00:00
Kyle Miller
02a4713875 feat: enable notationItem in "mixfix" notation commands (#10378)
This PR enables using `notation` items in
`infix`/`infixl`/`infixr`/`prefix`/`postfix`. The motivation for this is
to enable being able to use `pp.unicode`-aware parsers. A followup PR
can combine core parsers as such:
```lean
infixr:30 unicode(" ∨ ", " \\/ ") => Or
```

Continuation of #10373.
2025-09-14 18:54:36 +00:00
Kyle Miller
7407534eb8 feat: include := in the atomic part of tactic configuration items (#10379)
This PR modifies the syntax for tactic configurations. Previously just
`(ident` would commit to tactic configuration item parsing, but now it
needs to be `(ident :=`. This enables reliably using tactic
configurations before the `term` category. For example, given `syntax
"my_tac" optConfig term : tactic`, it used to be that `my_tac (x + y)`
would have an error on `+` with "expected `:=`", but now it parses the
term.

An additional rationale is that these are like named arguments; (1)
terms can't begin with named arguments so now there is no parsing
ambiguity and (2) `Parser.Term.namedArgument` indeed already includes
`:=` in the atomic part.
2025-09-14 18:53:47 +00:00
Kyle Miller
3f80e530d3 feat: suppress safe shadowing within fun binders (#10376)
This PR modifies pretty printing of `fun` binders, suppressing the safe
shadowing feature among the binders in the same `fun`. For example,
rather than pretty printing as `fun x x => 0`, we now see `fun x x_1 =>
0`. The calculation is done per `fun`, so for example `fun x => id fun x
=> 0` pretty prints as-is, taking advantage of safe shadowing.

The motivation for this change is that many users have reported that
safe shadowing within the same `fun` is confusing.
2025-09-14 15:54:59 +00:00
Lean stage0 autoupdater
3146f6c651 chore: update stage0 2025-09-14 08:05:12 +00:00
Leonardo de Moura
22aab5c3bb feat: non-commutative ring normalizer in grind (#10375)
This PR adds support for non-commutative ring normalization in `grind`.
The new normalizer also accounts for the `IsCharP` type class. Examples:
```lean
open Lean Grind

variable (R : Type u) [Ring R]
example (a b : R) : (a + 2 * b)^2 = a^2 + 2 * a * b + 2 * b * a + 4 * b^2 := by grind
example (a b : R) : (a + 2 * b)^2 = a^2 + 2 * a * b + -b * (-4) * a - 2*b*a + 4 * b^2 := by grind

variable [IsCharP R 4]
example (a b : R) : (a - b)^2 = a^2 - a * b - b * 5 * a + b^2 := by grind
example (a b : R) : (a - b)^2 = 13*a^2 - a * b - b * 5 * a + b*3*b*3 := by grind
```
2025-09-14 07:35:08 +00:00
Kyle Miller
7e9ea00ac0 feat: add option pp.piBinderNames (#10374)
This PR adds the options `pp.piBinderNames` and
`pp.piBinderNames.hygienic`. Enabling `pp.piBinderNames` causes
non-dependent pi binder names to be pretty printed, rather than be
omitted. When `pp.piBinderNames.hygienic` is false (the default) then
only non-hygienic such biner names are pretty printed. Setting `pp.all`
enables `pp.piBinderNames` if it is not otherwise explicitly set.

Implementation note: this is exposing the secret pretty printer option
`pp.piBinderNames` that was being used within the signature pretty
printer.

Closes #1134.
2025-09-14 05:15:04 +00:00
Kyle Miller
409cbe1da9 fix: make rw collect only new goals, occurs check (#10306)
This PR fixes a few bugs in the `rw` tactic: it could "steal" goals
because they appear in the type of the rewrite, it did not do an occurs
check, and new proof goals would not be synthetic opaque. This PR also
lets the `rfl` tactic assign synthetic opaque metavariables so that it
is equivalent to `exact rfl`.

Implementation note: filtering old vs new is not sufficient. This PR
partially addresses the bug where the rw tactic creates natural
metavariables for each of the goals; now new proof goals are synthetic
opaque.

Metaprogramming API: Instead of `Lean.MVarId.rewrite` prefer
`Lean.Elab.Tactic.elabRewrite` for elaborating rewrite theorems and
applying rewrites to expressions.

Closes #10172
2025-09-14 04:44:55 +00:00
Kyle Miller
3e4fa12c72 feat: add unicode(...) parser syntax and pp.unicode option (#10373)
This PR adds a `pp.unicode` option and a `unicode("→", "->")` syntax
description alias for the lower-level `unicodeSymbol "→" "->"` parser.
The syntax is added to the `notation` command as well. When `pp.unicode`
is true (the default) then the first form is used when pretty printing,
and otherwise the second ASCII form is used. A variant, `unicode("→",
"->", preserveForPP)` causes the `->` form to be preferred; delaborators
can insert `→` directly into the syntax, which will be pretty printed
as-is; this allows notations like `fun` to use custom options such as
`pp.unicode.fun` to opt into the unicode form when pretty printing.

Additionally:
- Adds more documentation for the `symbol` and `nonReservedSymbol`
parser descriptions.
- Adds documentation for the
`infix`/`infixr`/`infixl`/`prefix`/`postfix` commands.
- The parenthesizers for symbols are improved to backtrack if the atom
doesn't match.
- Fixes a bug where `&"..."` symbols aren't validated.

This is partial progress for issue #1056. What remains is enabling
`unicode(...)` for mixfix commands and then making use of it for core
notation.
2025-09-14 04:40:03 +00:00
Mac Malone
ed5dc328d9 refactor: import Lake.Util.* from Lake (#10371)
This PR explicitly imports `Lake.Util` submodules in `Lake`, ensuring
Lake utilities are consistently available by default in configuration
files.

It also simplifies the Lake globs for the core build to ensure all Lake
submodules are built (even if they are not imported).
2025-09-13 13:56:54 +00:00
Anne Baanen
2bbf5db04f fix: add infotree context to classical tactic (#10332)
This PR ensures that the infotree recognizes `Classical.propDecidable`
as an instance, when below a `classical` tactic.

The `classical` tactic modifies the environment that the subsequent
sequence of tactics runs in (by making `Classical.propDecidable` an
instance). However, it does not add a corresponding `InfoTree.context`
node, so its effects are not visible when we want to replay a tactic
sequence (for example when running a tactic in the tactic analysis
framework). We should add a call to `Lean.Elab.withSafeInfoContext` to
remedy this issue.

There are two potential places to add this class: in the meta-level
`Lean.Elab.Tactic.classical` wrapper, or the tactic-level
`evalClassical` tactic elaborator. I chose the latter since meta-level
does not have access to info tree operations (unless we add many
parameters to `Lean.Elab.Tactic.classical`: `[MonadNameGenerator m]
[MonadOptions m] [MonadMCtx m] [MonadResolveName m] [MonadFileMap m]`).

A testcase that uses the tactic analysis framework is available here:
https://github.com/leanprover-community/mathlib4/pull/29501
2025-09-12 16:30:44 +00:00
Sebastian Ullrich
116b708269 chore: CI: ensure cache reuse in update-stage0 (#10359) 2025-09-12 14:56:32 +00:00
Lean stage0 autoupdater
4b6eab762f chore: update stage0 2025-09-12 13:30:23 +00:00
Sebastian Ullrich
9d6f391414 fix: missing docs linter under the module system (#10361) 2025-09-12 12:41:06 +00:00
Sebastian Ullrich
245ede65b5 feat: meta initialize (#10360)
This PR adds syntax for defining compile-time initializers under the
module system, with other initializers to be restricted from running at
compile time in a follow-up PR.
2025-09-12 12:39:06 +00:00
Lean stage0 autoupdater
2422b9db87 chore: update stage0 2025-09-12 11:43:21 +00:00
Sebastian Ullrich
3f9f8f094d chore: split Std.Do.SPred.Notation in preparation for meta semantics restrictions (#10358) 2025-09-12 11:09:26 +00:00
Joachim Breitner
cf18337157 perf: use per-constructor noConfusion in mkNoConfusion (#10318)
This PR uses the per-constructor `noConfusion` principles (from #10315)
in the `mkNoConfusion` app builder, if possible. This means they are
used by `injection`, `grind`, `simp` and other places. This brings
notable performance improvements when dealing with inductives with a
large number of constructors.
2025-09-12 08:42:24 +00:00
Joachim Breitner
3cf7fdcbe0 feat: per-constructor noConfusion constructions (#10315)
This PR adds `T.ctor.noConfusion` declarations, which are
specializations of `T.noConfusion` to equalities between `T.ctor`. The
point is to avoid reducing the `T.noConfusionType` construction every
time we use `injection` or a similar tactic.

```lean
Vec.cons.noConfusion.{u_1, u} {α : Type u} (P : Sort u_1) {n : Nat}
  (x : α) (xs : Vec α n) (x' : α) (xs' : Vec α n)
  (h : Vec.cons x xs = Vec.cons x' xs')
  (k : n = n → x = x' → xs ≍ xs' → P) : P
```

The constructions are not as powerful as `T.noConfusion` when the
indices of the inductive type are not just constructor parameters (or
constructor applications of these parameters), so the full
`T.noConfusion` construction is still needed as a fallback.

It may seem costly to generate these eagerly, but given that we eagerly
generate injectivity theorems already, and we will use them there, it
seems reasonable for now.

To further reduce the cost, we only generate them for constructors with
fields (for others, the `T.noConfusion` theorem doesn't provide any
information), and we use `macro_inline` to prevent the compiler from
creating code for these, given that the compiler has special support for
`T.noConfusion` that we want it to use).

An earlier version of this PR also removed trivial equations and
un-HEq-ed others, leading to
```
 (k : x = x' → xs = xs' → P) 
```
in the example above. I backed out of that change, as it makes it harder
for tactics like `injectivity` to know how often to `intro`, so better
to keep things uniform.
2025-09-12 08:00:12 +00:00
Paul Reichert
caa0eacea8 feat: ranges in UInt* (#10303)
This PR adds range support to`BitVec` and the `UInt*` types. This means
that it is now possible to write, for example, `for i in (1 : UInt8)...5
do`, in order to loop over the values 1, 2, 3 and 4 of type `UInt8`.
2025-09-12 07:52:45 +00:00
David Thrane Christiansen
b8e584a054 fix: restore monad-polymorphism to some docstring functions (#10357)
This PR makes the Markdown docstring functions monad-polymorphic again,
and improves documentation for the internal docstring API.
2025-09-12 07:41:47 +00:00
Paul Reichert
ae682ed225 feat: more iterator/range lemmas about toList and toArray (#10244)
This PR adds more lemmas about the `toList` and `toArray` functions on
ranges and iterators. It also renames `Array.mem_toArray` into
`List.mem_toArray`.
2025-09-12 07:14:28 +00:00
Cameron Zwarich
b64111d5a8 fix: convert .proj on builtin types to use projection functions (#10355)
This PR changes `toLCNF` to convert `.proj` for builtin types to use
projection functions instead.

Fixes #10078.
2025-09-12 00:19:45 +00:00
Kim Morrison
72cc6c85eb chore: correct order of implicit arguments for Injective/Surjective API (#10354) 2025-09-11 23:30:19 +00:00
Sofia Rodrigues
a966ce64ca feat: add useful functions in Parsec, add error variant and Std.Data.ByteSlice (#9599)
This PR adds the type `Std.Internal.Parsec.Error`, which contains the
constructors `.eof` (useful for checking if parsing failed due to not
having enough input and then retrying when more input arrives that is
useful in the HTTP server) and `.other`, which describes other errors.
It also adds documentation to many functions, along with some new
functions to the `ByteArray` Parsec, such as `peekWhen?`, `octDigit`,
`takeWhile`, `takeUntil`, `skipWhile`, and `skipUntil`.
2025-09-11 14:53:41 +00:00
Lean stage0 autoupdater
5c88a2bf56 chore: update stage0 2025-09-11 13:47:30 +00:00
Sebastian Ullrich
73c85b177e refactor: split Init.Meta in preparation for meta semantics restrictions (#10343) 2025-09-11 13:01:03 +00:00
Kim Morrison
5c06c79c15 chore: fix remainining discrepancies for change in grind pattern heuristics (#10347)
This PR is followup to the change in grind pattern heuristics from
#10342, typically resolving the discrepancy by writing out an explicit
`grind_pattern` for the intended pattern. The new behaviour is more
aggressive, because it selects smaller patterns.
2025-09-11 12:48:52 +00:00
Lean stage0 autoupdater
c8117a34c1 chore: update stage0 2025-09-11 12:27:01 +00:00
Sebastian Ullrich
a5f5d793d7 perf: implement jumping to native [export] decls in the interpreter (#10345)
This PR allows the interpreter to jump to native code of `[export]`
declarations, which can increase performance as well as the
effectiveness of `interpreter.prefer_native=true` during bootstrapping.
2025-09-11 11:41:16 +00:00
David Thrane Christiansen
61c46fd5f8 fix: mark doc parser tests as eol=lf (#10344)
This PR sets the eol Git attribute on docstring parser tests. This is to
stop them from failing on Windows due to line ending translation.
2025-09-11 11:19:01 +00:00
Joachim Breitner
e7d1cdd36a refactor: reimplement mkNoConfusionType in Lean (#10334)
This PR reimplements `mkNoConfusionType` in lean, thus removing the
remaining C code related to this construction.

Also uses the ctor elimination principles only when there are more than
three ctors.
2025-09-11 07:56:59 +00:00
Kim Morrison
dfcb5bb3a8 chore: remove a bad grind algebra instance (#10324)
This PR disables an unused instance that causes expensive typeclass
searches.
2025-09-11 06:44:47 +00:00
Kim Morrison
01ed345643 chore: more review of @[grind] annotations (#10340)
This PR completes the review of `@[grind]` annotations without a sigil
(e.g. `=` or `←`), replacing most of them with more specific annotations
or patterns.

---------

Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
2025-09-11 06:09:52 +00:00
Lean stage0 autoupdater
176fb1cf0e chore: update stage0 2025-09-11 06:13:42 +00:00
Leonardo de Moura
6b387da032 feat: new E-matching pattern inference for grind (#10342)
This PR implements a new E-matching pattern inference procedure that is
faithful to the behavior documented in the reference manual regarding
minimal indexable subexpressions. The old inference procedure was
failing to enforce this condition. For example, the manual documents
`[grind ->]` as follows

`[@grind →]` selects a multi-pattern from the hypotheses of the theorem.
In other words, `grind` will use the theorem for forwards reasoning.

To generate a pattern, it traverses the hypotheses of the theorem from
left to right. Each time it encounters a **minimal indexable
subexpression** which covers an argument which was not previously
covered, it adds that subexpression as a pattern, until all arguments
have been covered.

That said, the new procedure is currently disabled, and the following
option must be used to enable it.
```
set_option backward.grind.inferPattern false
```
Users can inspect differences between the old a new procedures using the
option
```
set_option backward.grind.checkInferPatternDiscrepancy true 
```
Example:
```lean
/--
warning: found discrepancy between old and new `grind` pattern inference procedures, old:
  [@List.length #2 (@toList _ #1 #0)]
new:
  [@toList #2 #1 #0]
use `set_option backward.grind.inferPattern true` to force old procedure
-/
#guard_msgs in
set_option backward.grind.checkInferPatternDiscrepancy true in
@[grind] theorem Vector.length_toList' (xs : Vector α n) : xs.toList.length = n := by sorry
```
2025-09-11 05:27:11 +00:00
Kim Morrison
c3667e2861 feat: upstream Function.Injective/Surjective (#10341)
This PR moves the definitions and basic facts about `Function.Injective`
and `Function.Surjective` up from Mathlib. We can do a better job of
arguing via injectivity in `grind` if these are available.
2025-09-11 04:04:46 +00:00
Leonardo de Moura
33266b23cd chore: use [grind =] (#10337) 2025-09-11 03:21:37 +00:00
Leonardo de Moura
a4a2bfa426 fix: minor issues in grind (#10339)
This PR fixes a few minor issues and applies a few cleanups.
2025-09-11 02:54:36 +00:00
Kim Morrison
b7520e7232 chore: cleanup grind annotations in List (#10338)
This PR updates `@[grind]` annotations which should be `@[grind =]`, for
robustness (and, presumably, in some fraction of cases the existing
heuristic for `@[grind]` is already too liberal).
2025-09-11 02:36:18 +00:00
Leonardo de Moura
0b84c3912e fix: over applied Grind.nestedProof marker (#10335)
This PR fixes the nested proof term detection in `grind`. It must check
whether the gadget `Grind.nestedProof` is over-applied.

closes #10327
2025-09-10 16:48:36 +00:00
Joachim Breitner
e96467f500 refactor: introduce SameCtorUtils (#10316)
This PR shares common functionality relate to equalities between same
constructors, and when these are type-correct. In particular it uses the
more complete logic from `mkInjectivityThm` also in other places, such
as `CasesOnSameCtor` and the deriving code for `BEq`, `DecidableEq`,
`Ord`, for more consistency and better error messages.
2025-09-10 14:32:58 +00:00
Sebastian Ullrich
bdab63048a doc: testing Lean while avoiding rebuilds for downstream projects (#10328) 2025-09-10 13:53:34 +00:00
Joachim Breitner
30a041902b refactor: implement mkNoConfusionImp in Lean (#10331)
This PR implements `mkNoConfusionImp` in Lean rather than in C. This
reduces our reliance on C, and may bring performance benefits from not
reducing `noConfusionType` during elaboration time (it still gets
reduced by the kernel when type-checking).
2025-09-10 13:51:23 +00:00
Eric Wieser
fbcad8f593 feat: allow separate handlers for literals and interpolations in expandInterpolatedStr (#6763)
This PR makes it possible to write custom interpolation notation which
treats interpolated `String`s specially.

Sometimes it is desirable for `let w := "world"; foo!"hello {w}"` and
`foo!"hello world"` to mean different things; for instance, if debugging
and wanting to show all interpolands with `repr`. The current approach
forces `hello` to also be rendered with `repr`, which is not desirable.

This doesn't modify any existing formatters.

Requested in [#lean4 > ✔ dbg_trace should use &#96;Repr&#96; instance @
💬](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/.E2.9C.94.20dbg_trace.20should.20use.20.60Repr.60.20instance/near/495082575)

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-09-10 13:22:17 +00:00
Sebastian Ullrich
0a6bd5c0c6 chore: make Environment.evalConst [noinline] 2025-09-10 12:56:42 +02:00
Sebastian Ullrich
de2e935f30 fix: run @[init] declarations in declaration order (#10217)
This PR ensures `@[init]` declarations such as from `initialize` are run
in the order they were declared on import.

Fixes #10175
2025-09-10 09:52:10 +00:00
Sebastian Ullrich
57bce526f9 fix: further exporting control (#10261)
More proof generation nested in general metaprograms, uncovered by Shake
2025-09-10 09:14:11 +00:00
Sebastian Ullrich
b136906939 perf: do not publicly export docstrings (#10305)
This PR ensures changes to docstrings do not trigger downstream rebuilds
under the module system.
2025-09-10 09:10:04 +00:00
Lean stage0 autoupdater
f4c7a0d25c chore: update stage0 2025-09-10 07:49:18 +00:00
David Thrane Christiansen
3e2124bb48 feat: docstrings with Verso syntax (#10307)
This PR upstreams the Verso parser and adds preliminary support for
Verso in docstrings. This will allow the compiler to check examples and
cross-references in documentation.

After a `stage0` update, a follow-up PR will add the appropriate
attributes that allow the feature to be used. The parser tests from
Verso also remain to be upstreamed, and user-facing documentation will
be added once the feature has been used on more internals.
2025-09-10 07:03:57 +00:00
Leonardo de Moura
fc6a6cc4e2 fix: unnecessary NatModules in grind linarith (#10326)
This PR fixes a performance issue in `grind linarith`. It was creating
unnecessary `NatModule`/`IntModule` structures for commutative rings
without an order. This kind of type should be handled by `grind ring`
only.
2025-09-10 03:51:51 +00:00
Kim Morrison
bb61a2d481 chore: add grind test for numeral normalization (#10292) 2025-09-10 03:19:49 +00:00
Leonardo de Moura
2d8de4235d feat: model-based theory combination for ToInt types (#10325)
This PR implements model-based theory combination for types `A` which
implement the `ToInt` interface. Examples:
```lean
example {C : Type} (h : Fin 4 → C) (x : Fin 4)
    : 3 ≤ x → x ≤ 3 → h x = h (-1) := by
  grind

example {C : Type} (h : UInt8 → C) (x y z w : UInt8)
    : y + 1 + w ≤ x + w → x + w ≤ z → z ≤ y + w + 1 → h (x + w) = h (y + w + 1) := by
  grind

example {C : Type} (h : Fin 8 → C) (x y w r : Fin 8)
    : y + 1 + w ≤ r → r ≤ y + w + x → x = 1 → h r = h (y + w + 1) := by
  grind
```
2025-09-10 03:12:11 +00:00
Kim Morrison
a0ecff4610 chore: remove over-eager grind lemma eq_empty_of_append_eq_empty (#10162)
This PR removes `grind →` annotations that fire too often, unhelpfully.
It would be nice for `grind` to instantiate these lemmas, but only if
they already see `xs ++ ys` and `#[]` in the same equivalence class, not
just as soon as it sees `xs ++ ys`.

In the meantime, let's see what is using these.
2025-09-10 02:35:54 +00:00
Kim Morrison
923c3d10a2 feat: cutsat and grobner frontends for grind (#10322)
This PR introduces limited functionality frontends `cutsat` and
`grobner` for `grind`. We disable theorem instantiation (and case
splitting for `grobner`), and turn off all other solvers. Both still
allow `grind` configuration options, so for example one can use `cutsat
+ring` (or `grobner +cutsat`) to solve problems that require both.

For `cutsat`, it is helpful to instantiate a limited set of theorems
(e.g. `Nat.max_def`). Currently this isn't supported, but we intend to
add this later.
2025-09-10 02:26:52 +00:00
Leonardo de Moura
ac4c752608 fix: OfNat.ofNat grind canonicalizer (#10323)
This PR fixes the `grind` canonicalizer for `OfNat.ofNat` applications.
Example:
```lean
example {C : Type} (h : Fin 2 → C) :
    -- `0` in the first `OfNat.ofNat` is not a raw literal
    h (@OfNat.ofNat (Fin (1 + 1)) 0 Fin.instOfNat) = h 0 := by
  grind
```
2025-09-10 00:21:04 +00:00
Leonardo de Moura
4d2576362b fix: use local metavar ids in grind (#10321)
This PR ensures that the auxiliary temporary metavariable IDs created by
the E-matching module used in `grind` are not affected by what has been
executed before invoking `grind`. The goal is to increase `grind`’s
robustness.

For example, in the E-matching module we use `Expr.quickLt` to sort
candidates. `Expr.quickLt` depends on the `Expr` hash code, which in
turn depends on metavariable IDs. Thus, before this change, the initial
next metavariable ID at the time of `grind` invocation could affect the
order in which instances were generated, and consequently the `grind`
search.
2025-09-09 22:22:52 +00:00
Leonardo de Moura
f6a2c6d07c fix: bug at assignUnassignedLevelMVars in grind (#10320) 2025-09-09 21:45:06 +00:00
Kyle Miller
1a203c7fe5 feat: intermediate tactic info on simpa (#10309)
This PR modifies the `simpa` tactic so that in `simpa ... using e` there
is tactic info on the range `simpa ... using` that shows the simplified
goal.
2025-09-09 20:24:27 +00:00
Rob23oba
e75e6fbe9e chore: don't include redundant empty strings in string interpolation (#10269)
This PR changes the string interpolation procedure to omit redundant
empty parts. For example `s!"{1}{2}"` previously elaborated to `toString
"" ++ toString 1 ++ toString "" ++ toString 2 ++ toString ""` and now
elaborates to `toString 1 ++ toString 2`.
2025-09-09 14:27:26 +00:00
Copilot
d98b626633 doc: improve docstrings for simp!, simp_all!, dsimp! and autoUnfold (#9991)
- [x] Updated docstrings for `simp!`, `simp_all!`, `dsimp!` to use
user-friendly language
- [x] Updated docstrings for `autoUnfold` fields to use user-friendly
language
- [x] Fixed broken test by updating expected output for simp! hover
documentation
- [x] Replaced technical terms with clear language: "will unfold
applications of functions defined by pattern matching, when one of the
patterns applies"

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: nomeata <148037+nomeata@users.noreply.github.com>
2025-09-09 13:34:16 +00:00
Paul Reichert
fd0177afe3 feat: add missing lemmas about insertMany and get? for container types (#10247)
This PR adds missing the lemmas `ofList_eq_insertMany_empty`,
`get?_eq_some_iff`, `getElem?_eq_some_iff` and `getKey?_eq_some_iff` to
all container types.
2025-09-09 13:27:43 +00:00
dependabot[bot]
757426b099 chore: CI: bump actions/checkout from 4 to 5 (#10219)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to
5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
<li>Prepare v5.0.0 release by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2238">actions/checkout#2238</a></li>
</ul>
<h2>⚠️ Minimum Compatible Runner Version</h2>
<p><strong>v2.327.1</strong><br />
<a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Release
Notes</a></p>
<p>Make sure your runner is updated to this version or newer to use this
release.</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4...v5.0.0">https://github.com/actions/checkout/compare/v4...v5.0.0</a></p>
<h2>v4.3.0</h2>
<h2>What's Changed</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
<li>Prepare release v4.3.0 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2237">actions/checkout#2237</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/motss"><code>@​motss</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li><a href="https://github.com/mouismail"><code>@​mouismail</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li><a href="https://github.com/benwells"><code>@​benwells</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li><a href="https://github.com/nebuk89"><code>@​nebuk89</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li><a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4...v4.3.0">https://github.com/actions/checkout/compare/v4...v4.3.0</a></p>
<h2>v4.2.2</h2>
<h2>What's Changed</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4.2.1...v4.2.2">https://github.com/actions/checkout/compare/v4.2.1...v4.2.2</a></p>
<h2>v4.2.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Jcambass"><code>@​Jcambass</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/1919">actions/checkout#1919</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4.2.0...v4.2.1">https://github.com/actions/checkout/compare/v4.2.0...v4.2.1</a></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>V5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>V4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>v4.2.0</h2>
<ul>
<li>Add Ref and Commit outputs by <a
href="https://github.com/lucacome"><code>@​lucacome</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
<li>Dependency updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>- <a
href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>,
<a
href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li>
</ul>
<h2>v4.1.7</h2>
<ul>
<li>Bump the minor-npm-dependencies group across 1 directory with 4
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li>
<li>Bump actions/checkout from 3 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li>
<li>Check out other refs/* by commit by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li>
<li>Pin actions/checkout's own workflows to a known, good, stable
version. by <a href="https://github.com/jww3"><code>@​jww3</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1776">actions/checkout#1776</a></li>
</ul>
<h2>v4.1.6</h2>
<ul>
<li>Check platform to set archive extension appropriately by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1732">actions/checkout#1732</a></li>
</ul>
<h2>v4.1.5</h2>
<ul>
<li>Update NPM dependencies by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1703">actions/checkout#1703</a></li>
<li>Bump github/codeql-action from 2 to 3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1694">actions/checkout#1694</a></li>
<li>Bump actions/setup-node from 1 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1696">actions/checkout#1696</a></li>
<li>Bump actions/upload-artifact from 2 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1695">actions/checkout#1695</a></li>
<li>README: Suggest <code>user.email</code> to be
<code>41898282+github-actions[bot]@users.noreply.github.com</code> by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1707">actions/checkout#1707</a></li>
</ul>
<h2>v4.1.4</h2>
<ul>
<li>Disable <code>extensions.worktreeConfig</code> when disabling
<code>sparse-checkout</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1692">actions/checkout#1692</a></li>
<li>Add dependabot config by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1688">actions/checkout#1688</a></li>
<li>Bump the minor-actions-dependencies group with 2 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1693">actions/checkout#1693</a></li>
<li>Bump word-wrap from 1.2.3 to 1.2.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1643">actions/checkout#1643</a></li>
</ul>
<h2>v4.1.3</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="08c6903cd8"><code>08c6903</code></a>
Prepare v5.0.0 release (<a
href="https://redirect.github.com/actions/checkout/issues/2238">#2238</a>)</li>
<li><a
href="9f265659d3"><code>9f26565</code></a>
Update actions checkout to use node 24 (<a
href="https://redirect.github.com/actions/checkout/issues/2226">#2226</a>)</li>
<li>See full diff in <a
href="https://github.com/actions/checkout/compare/v4...v5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4&new-version=5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 11:53:35 +00:00
dependabot[bot]
b81ea5ee9c chore: CI: bump actions/download-artifact from 4 to 5 (#10220)
Bumps
[actions/download-artifact](https://github.com/actions/download-artifact)
from 4 to 5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/download-artifact/releases">actions/download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/407">actions/download-artifact#407</a></li>
<li>BREAKING fix: inconsistent path behavior for single artifact
downloads by ID by <a
href="https://github.com/GrantBirki"><code>@​GrantBirki</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/416">actions/download-artifact#416</a></li>
</ul>
<h2>v5.0.0</h2>
<h3>🚨 Breaking Change</h3>
<p>This release fixes an inconsistency in path behavior for single
artifact downloads by ID. <strong>If you're downloading single artifacts
by ID, the output path may change.</strong></p>
<h4>What Changed</h4>
<p>Previously, <strong>single artifact downloads</strong> behaved
differently depending on how you specified the artifact:</p>
<ul>
<li><strong>By name</strong>: <code>name: my-artifact</code> → extracted
to <code>path/</code> (direct)</li>
<li><strong>By ID</strong>: <code>artifact-ids: 12345</code> → extracted
to <code>path/my-artifact/</code> (nested)</li>
</ul>
<p>Now both methods are consistent:</p>
<ul>
<li><strong>By name</strong>: <code>name: my-artifact</code> → extracted
to <code>path/</code> (unchanged)</li>
<li><strong>By ID</strong>: <code>artifact-ids: 12345</code> → extracted
to <code>path/</code> (fixed - now direct)</li>
</ul>
<h4>Migration Guide</h4>
<h5> No Action Needed If:</h5>
<ul>
<li>You download artifacts by <strong>name</strong></li>
<li>You download <strong>multiple</strong> artifacts by ID</li>
<li>You already use <code>merge-multiple: true</code> as a
workaround</li>
</ul>
<h5>⚠️ Action Required If:</h5>
<p>You download <strong>single artifacts by ID</strong> and your
workflows expect the nested directory structure.</p>
<p><strong>Before v5 (nested structure):</strong></p>
<pre lang="yaml"><code>- uses: actions/download-artifact@v4
  with:
    artifact-ids: 12345
    path: dist
# Files were in: dist/my-artifact/
</code></pre>
<blockquote>
<p>Where <code>my-artifact</code> is the name of the artifact you
previously uploaded</p>
</blockquote>
<p><strong>To maintain old behavior (if needed):</strong></p>
<pre lang="yaml"><code>&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="634f93cb29"><code>634f93c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/416">#416</a>
from actions/single-artifact-id-download-path</li>
<li><a
href="b19ff43027"><code>b19ff43</code></a>
refactor: resolve download path correctly in artifact download tests
(mainly ...</li>
<li><a
href="e262cbee4a"><code>e262cbe</code></a>
bundle dist</li>
<li><a
href="bff23f9308"><code>bff23f9</code></a>
update docs</li>
<li><a
href="fff8c148a8"><code>fff8c14</code></a>
fix download path logic when downloading a single artifact by id</li>
<li><a
href="448e3f862a"><code>448e3f8</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/407">#407</a>
from actions/nebuk89-patch-1</li>
<li><a
href="47225c44b3"><code>47225c4</code></a>
Update README.md</li>
<li>See full diff in <a
href="https://github.com/actions/download-artifact/compare/v4...v5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=4&new-version=5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 11:53:09 +00:00
Leonardo de Moura
c75d37f76b fix: no model-based theory combination on instances (#10314)
This PR skips model based theory combination on instances.
2025-09-09 03:30:29 +00:00
Leonardo de Moura
dd87739fc2 feat: grind normalizers for natCast and intCast (#10313)
This PR adds missing `grind` normalization rules for `natCast` and
`intCast` Examples:
```
open Lean.Grind
variable (R : Type) (a b : R)

section CommSemiring
variable [CommSemiring R]

example (m n : Nat) : (m + n) • a = m • a + n • a := by grind
example (m n : Nat) : (m * n) • a = m • (n • a) := by grind

end CommSemiring

section CommRing
variable [CommRing R]

example (m n : Nat) : (m + n) • a = m • a + n • a := by grind
example (m n : Nat) : (m * n) • a = m • (n • a) := by grind
example (m n : Int) : (m * n) • (a * b) = (m • a) * (n • b) := by grind

end CommRing
```
2025-09-09 01:32:09 +00:00
Lean stage0 autoupdater
01e6928da0 chore: update stage0 2025-09-09 01:05:26 +00:00
Leonardo de Moura
e36d1925f1 refactor: grind cutsat as solver extension (#10312)
This PR uses the new solver extension framework to implement `grind
cutsat`. All satellite solvers have been migrated to the new framework.
2025-09-09 00:23:12 +00:00
Kim Morrison
f9b2e550bb feat: grind annotations for basic monad transformers (#10227)
This PR adds `@[grind]` annotations (nearly all `@[grind =]` annotations
parallel to existing `@[simp]`s) for `ReaderT`, `StateT`, `ExceptT`.
2025-09-08 23:51:55 +00:00
Leonardo de Moura
ed99ad63f3 refactor: grind offset as solver extension (#10311)
This PR uses the new solver extension framework to implement `grind
offset`.
2025-09-08 19:53:54 +00:00
Leonardo de Moura
eb337b820f refactor: grind linarith as solver extension (#10310)
This PR uses the new solver extension framework to implement `grind
linarith`.
2025-09-08 18:34:25 +00:00
Lean stage0 autoupdater
1dc72b1880 chore: update stage0 2025-09-08 19:04:07 +00:00
Cameron Zwarich
e86ab1b1db fix: make IO.RealWorld opaque (#9631)
This PR makes `IO.RealWorld` opaque. It also adds a new compiler -only
`lcRealWorld` constant to represent this type within the compiler. By
default, an opaque type definition is treated like `lcAny`, whereas we
want a more efficient representation. At the moment, this isn't a big
difference, but in the future we would like to completely erase
`IO.RealWorld` at runtime.
2025-09-08 18:12:19 +00:00
Leonardo de Moura
c34ea82bc2 refactor: grind ring as solver extension (#10308)
This PR uses the new solver extension framework to implement `grind
ring`.
2025-09-08 15:40:55 +00:00
Joachim Breitner
79051fb5c0 feat: simpler off-diagonal noConfusion construction using ctorIdx (#10300)
This PR offers an alternative `noConfusion` construction for the
off-diagonal use (i.e. for different constructors), based on comparing
the `.ctorIdx`. This should lead to faster type checking, as the kernel
only has to reduce `.ctorIdx` twice, instead of the complicate
`noConfusionType` construction.
2025-09-08 14:34:26 +00:00
Kyle Miller
81fe3b6d05 feat: pretty print sorry in "declaration uses 'sorry'" (#10034)
This PR changes the "declaration uses 'sorry'" error to pretty print an
actual `sorry` expression in the message. The effect is that the `sorry`
is hoverable and, if it's labeled, you can "go to definition" to see
where it came from.

The implementation prefers reporting synthetic sorries. These can appear
even if there are no error messages if a declaration refers to a
declaration that has elaboration errors. Users should focus on
elaboration errors before worrying about user-written `sorry`s.

In the future we could have some more precise logic for sorry reporting.
All the sorries in a declaration should be considered to be reported,
and we should not re-report sorries in later declarations. Some
elaborators use `warn.sorry` to avoid re-reporting sorries in auxiliary
declarations.
2025-09-08 12:14:42 +00:00
Lean stage0 autoupdater
05d6b8648c chore: update stage0 2025-09-08 10:52:50 +00:00
Wojciech Różowski
5c03ab9630 fix: unfolding order on predicates (#10245)
This PR changes the implementation of a function `unfoldPredRel` used in
(co)inductive predicate machinery, that unfolds pointwise order on
predicates to quantifications and implications. Previous implementation
relied on `withDeclsDND` that could not deal with types which depend on
each other. This caused the following example to fail:

```lean4
inductive infSeq_functor1.{u} {α : Type u} (r : α → α → Prop) (call : {α : Type u} → (r : α → α → Prop) → α → Prop) : α → Prop where
  | step : r a b → infSeq_functor1 r call b → infSeq_functor1 r call a

def infSeq1 (r : α → α → Prop) : α → Prop := infSeq_functor1 r (infSeq1)
  coinductive_fixpoint monotonicity by sorry

#check infSeq1.coinduct
```
Closes #10234.
2025-09-08 10:07:15 +00:00
Joachim Breitner
3e24d5dee8 fix: expose ctorIdx and per-constructor elims (#10301)
This PR exposes ctorIdx and per-constructor eliminators. Fixes #10299.
2025-09-08 10:04:19 +00:00
Cameron Zwarich
4a73532fbe chore: remove unnecessary parens (#10298) 2025-09-08 05:52:45 +00:00
Cameron Zwarich
f6cf54fb2f chore: remove lean/run/lcnf1.lean test (#10297)
This test involves re-running the compiler on decls that have already
been compiled, which can cause all sorts of issues. I just hit these
issues on a PR, so it's time to retire this test like others that hit
the same issues.
2025-09-08 05:51:40 +00:00
Leonardo de Moura
058f6008c0 fix: bug at Poly.combine_mul_k (#10296)
This PR fixes a bug in an auxiliary function used to construct proof
terms in `grind cutsat`.
2025-09-08 02:17:11 +00:00
Lean stage0 autoupdater
ab30577acb chore: update stage0 2025-09-08 01:54:53 +00:00
Leonardo de Moura
be1e090833 feat: grind solver extensions (part 2) (#10294)
This PR completes the `grind` solver extension design and ports the
`grind ac` solver to the new framework. Future PRs will document the API
and port the remaining solvers. An additional benefit of the new design
is faster build times.
2025-09-08 01:11:05 +00:00
Cameron Zwarich
6a8d7cc17c chore: remove instWPMonad instance and test that relies upon it (#10293)
The proof of the instWPMonad instance relies on the equality of any two
terms of type `IO.RealWorld`, which is only a side effect of the current
transparent definition. Ignoring the questions around the utility of
proving things about programs in `IO`, the semantic validity of this
instance in the intended model of the IO monad is also unclear.

I tried a few things to axiomatize this instance so it could be put into
the test file to preserve the one test section that relies on it, but I
was unsuccessful; everything I attempted caused errors.
2025-09-07 23:42:52 +00:00
Lean stage0 autoupdater
13795fb3ad chore: update stage0 2025-09-07 18:40:52 +00:00
Leonardo de Moura
612c7588d0 feat: grind solver extensions (#10290)
This PR adds infrastructure for registering new `grind` solvers. `grind`
already includes many solvers, and this PR is the first step toward
modularizing the design and supporting user-defined solvers.
2025-09-07 17:45:50 +00:00
Lean stage0 autoupdater
d70b619500 chore: update stage0 2025-09-07 17:55:11 +00:00
Markus Himmel
9402c307fe chore: reorganize Init imports around strings (#10289)
This PR reorganizes the import hierarchy so that
`Init.Data.String.Basic` can import `Init.Data.UInt.Bitwise` and
`Init.Data.Array.Lemmas`.
2025-09-07 17:09:14 +00:00
Lean stage0 autoupdater
1ab115648d chore: update stage0 2025-09-07 13:40:08 +00:00
Markus Himmel
aa0a31ae7d chore: prepare for untangling strings (#10288)
This PR prepares for a future reorganization of the import hierarchy so
that `Init.Data.String.Basic` can import `Init.Data.UInt.Bitwise` and
`Init.Data.Array.Lemmas`.
2025-09-07 12:58:23 +00:00
Markus Himmel
19bd0254c3 chore: move String.utf8EncodeChar to the prelude (#10264)
This PR moves `String.utf8EncodeChar` to the prelude to prepare for the
imminent redefinition of `String`.

The definition in the prelude uses modulo and division operations on
natural numbers. In `String.Extra`, a `csimp` lemma is provided, showing
that the new definition is equal to the previous one (which is now
called `utf8EncodeCharFast`) which uses bitwise operations on `UInt8`.
2025-09-07 12:42:53 +00:00
Marc Huisinga
0b3550f284 fix: textedit completions (#10286)
This PR fixes `textEdit`-based completions after they were accidentally
broken by the new serialization procedure in #10249.
2025-09-07 09:44:16 +00:00
Leonardo de Moura
5463e10ce4 test: grind ac diagnostics (#10284) 2025-09-07 02:15:56 +00:00
Leonardo de Moura
8fd8821b61 feat: grind ac module diagnostics (#10283)
This PR implements diagnostic information for the `grind ac` module. It
now displays the basis, normalized disequalities, and additional
properties detected for each associative operator.
2025-09-07 01:43:38 +00:00
Leonardo de Moura
975b6e758f feat: improve grind linarith counterexamples for NatModule (#10282)
This PR improves the counterexamples produced by `grind linarith` for
`NatModule`s. `grind` now hides occurrences of the auxiliary function
`Grind.IntModule.OfNatModule.toQ`.
2025-09-07 01:04:01 +00:00
Leonardo de Moura
a31eb94e5a feat: normalize NatModule equations (#10281)
This PR implements `NatModule` normalization when the `AddRightCancel`
instance is not available. Note that in this case, the embedding into
`IntModule` is not injective. Therefore, we use a custom normalizer,
similar to the `CommSemiring` normalizer used in the `grind ring`
module. Example:

```lean
open Lean Grind
example [NatModule α] (a b c : α)
    : 2•a + 2•(b + 2•c) + 3•a = 4•a + c + 2•b + 3•c + a := by
  grind
```
2025-09-07 00:20:10 +00:00
Leonardo de Moura
652868c308 feat: NatModule equation normalization theorem (#10280)
This PR adds the auxiliary theorem `Lean.Grind.Linarith.eq_normN` for
normalizing `NatModule` equations when the instance `AddRightCancel` is
not available.
2025-09-06 23:32:26 +00:00
Mac Malone
0d28e450c2 refactor: lake: mv verLit into the DSL namespace (#10276)
This PR moves the `verLit` syntax into the `Lake.DSL` namespace to be
consistent with other code found in `Lake.DSL`.
2025-09-06 21:14:15 +00:00
Joachim Breitner
a872cec0a7 refactor: use match decEq, not if h : in deriving DecidableEq (#10274)
This PR changes the implementation of the linear `DecidableEq`
implementation to use `match decEq` rather than `if h : ` to compare the
constructor tags. Otherwise, the “smart unfolding” machinery will not
let `rfl` decide that different constructors are different.
2025-09-06 21:00:34 +00:00
Leonardo de Moura
2ff41f43be feat: NatModule inequalities and equalities in grind linarith (#10278)
This PR adds support for `NatModule` equalities and inequalities in
`grind linarith`. Examples:
```lean
open Lean Grind Std

example [NatModule α] [LE α] [LT α] 
  [LawfulOrderLT α] [IsLinearOrder α] [OrderedAdd α] 
  (x y : α) : x ≤ y → 2 • x + y ≤ 3 • y := by
  grind

example [NatModule α] [AddRightCancel α] [LE α] [LT α] 
    [LawfulOrderLT α] [IsLinearOrder α] [OrderedAdd α] 
    (a b c d : α) : a ≤ b → a ≥ c + d → d ≤ 0 → d ≥ 0 → b = c → a = b := by
  grind
```
2025-09-06 20:52:09 +00:00
Leonardo de Moura
52a9fe3b67 feat: missing NatModule instances (#10277)
This PR adds the missing instances `IsPartialOrder`, `IsLinearPreorder`
and `IsLinearOrder` for `OfNatModule.Q α`.
2025-09-06 18:58:02 +00:00
Joachim Breitner
316ff35afd feat: deriving instances: use accessible names (#10271)
This PR changes the naming of the internal functions in deriving
instances like BEq to use accessible names. This is necessary to
reasonably easily prove things about these functions. For example after
`deriving BEq` for a type `T`, the implementation of `instBEqT` is in
`instBEqT.beq`.
2025-09-06 18:12:20 +00:00
Mac Malone
aaa0cf3cf6 refactor: lake: rm public syntax workarounds (#10275) 2025-09-06 17:33:36 +00:00
Joachim Breitner
8b09366c78 fix: casesOnSameCtor: export if not private (#10273)
This PR tries to do the right thing about the visibility of the
same-ctor-match-construct.
2025-09-06 16:32:10 +00:00
Sebastian Ullrich
5f75c55191 fix: do not apply private instances in public scope (#10260) 2025-09-06 15:34:12 +00:00
Sebastian Ullrich
752b53e936 feat: maxErrors option (#10262)
This PR adds a new option `maxErrors` that limits the number of errors
printed from a single `lean` run, defaulting to 100. Processing is
aborted when the limit is reached, but this is tracked only on a
per-command level.

Smaller values can be useful when making changes that break a lot of
files and would otherwise scroll the actual root failures out of the
terminal view.
2025-09-06 14:52:49 +00:00
Eric Wieser
3f671cca92 doc: add docstrings for tracing functions (#10169) 2025-09-06 09:29:24 +00:00
Leonardo de Moura
8735447d44 feat: infrastructure for NatModule in grind linarith (#10267)
This PR implements the infrastructure for supporting `NatModule` in
`grind linarith` and uses it to handle disequalities. Another PR will
add support for equalities and inequalities. Example:
```lean
open Lean Grind
variable (M : Type) [NatModule M] [AddRightCancel M]

example (x y : M) : 2 • x + 3 • y + x = 3 • (x + y) := by
  grind
```
2025-09-06 01:16:03 +00:00
Leonardo de Moura
1861cc6bbc fix: panic in grind ring (#10265)
This PR fixes a panic in `grind ring` exposed by #10242. `grind ring`
should not assume that all normalizations have been applied, because
some subterms cannot be rewritten by `simp` due to typing constraints.
Moreover, `grind` uses `preprocessLight` in a few places, and it skips
the simplifier/normalizer.

Closes #10242
2025-09-05 16:16:25 +00:00
Sebastian Ullrich
974c649e2e fix: meta structure/inductive should create meta ctor (#10263) 2025-09-05 14:00:55 +00:00
Paul Reichert
184f716da1 refactor: improve names in the range API (#10059)
This PR improves the names of definitions and lemmas in the polymorphic
range API. It also introduces a recommended spelling. For example, a
left-closed, right-open range is spelled `Rco` in analogy with Mathlib's
`Ico` intervals.
2025-09-05 13:10:05 +00:00
Lean stage0 autoupdater
3f7f1c87f6 chore: update stage0 2025-09-05 11:21:02 +00:00
Marc Huisinga
7ba0ae1f72 feat: improve auto-completion performance (#10249)
This PR speeds up auto-completion by a factor of ~3.5x through various
performance improvements in the language server. On one machine, with
`import Mathlib`, completing `i` used to take 3200ms and now instead
yields a result in 920ms.

Specifically, the following improvements are made:
- The watchdog process no longer de-serializes and re-serializes most
messages from the file worker before passing them on to the user - a
fast partial de-serialization procedure is now used to determine whether
the message needs to be de-serialized in full or not.
- `escapePart` is optimized to perform better on ASCII strings that do
not need escaping.
- `Json.compress` is optimized to allocate fewer objects.
- A faster JSON compression specifically for completion responses is
implemented that skips allocating `Json` altogether.
- The JSON compression has been moved to the task where we convert a
request response to `Json` so that converting to a string won't block
the output task of the FileWorker and so the `Json` value is not marked
as multi-threaded when we compress is, which drastically increases the
cost of reference-counting.
- The JSON representation of the `data?` field of each completion item
is optimized.
- Both the completion kind and the set of completion tags for each
imported completion item is now cached.
- The filtering of duplicate completion items is optimized.

Other adjustments:
- `LT UInt8` and `LE UInt8` are moved to Prelude so that they can be
used in `Init.Meta` for the name part escaping fast path.
- `Array.usize` is exposed since it was marked as `@[simp]`.
2025-09-05 08:55:49 +00:00
Cameron Zwarich
9923a8d9f8 chore: remove special case for extern constructors (#10257)
This is subsumed by the fix in #10256.
2025-09-05 06:08:45 +00:00
Cameron Zwarich
de38a16fa9 fix: use IR decls in toIR for applications without mono decls (#10256)
This PR corrects a mistake in `toIR` where it could over-apply a
function that has an IR decl but no mono decl.

Fixes #10181.
2025-09-05 05:32:19 +00:00
Cameron Zwarich
c0238e396c refactor: inline tryIrDecl? into its only caller (#10255)
This helper function was actually incorrectly named anyways.
2025-09-05 04:41:34 +00:00
Cameron Zwarich
c7cc398935 refactor: create a mkApplication helper for toIR (#10254) 2025-09-05 01:42:36 +00:00
Mac Malone
849bb770fd refactor: lake: split PackageConfig from Config.Package (#10253)
This PR moves the `PackageConfig` definition from `Lake.Config.Package`
into its own module. This enables a significant reduction in the `meta
import` tree of the `Lake.CLI.Translate` modules.
2025-09-04 23:15:37 +00:00
Leonardo de Moura
6cefbc4bb0 chore: fix typo (#10251) 2025-09-04 16:05:00 +00:00
Paul Reichert
9b6a4a7588 fix: solve two problems with LinearOrderPackage factories (#10250)
This PR fixes a bug in the `LinearOrderPackage.ofOrd` factory. If there
is a `LawfulEqOrd` instance available, it should automatically use it
instead of requiring the user to provide the `eq_of_compare` argument to
the factory. The PR also solves a hygiene-related problem making the
factories fail when `Std` is not open.
2025-09-04 15:27:09 +00:00
Sebastian Ullrich
47787dc1cb perf: rebuild leak on private match (#10246)
This PR prevents downstream rebuilds on changes to private `match`es
under the module system
2025-09-04 12:51:42 +00:00
Lean stage0 autoupdater
25ab3dd93d chore: update stage0 2025-09-04 08:22:20 +00:00
Kim Morrison
bbd45b13f4 chore: move omega internals to a namespace (#10243)
This PR moves some internal implementation details of `omega` out of the
`List` namespace. See [#mathlib4 > Naming: ne_zero vs nonzero @
💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Naming.3A.20ne_zero.20vs.20nonzero/near/537424328).
2025-09-04 06:32:02 +00:00
Kim Morrison
85f168bbd0 chore: add test cases for grind on Fin lemmas (#10241)
This PR adds some test cases for `grind` working with `Fin`. There are
many still failing tests in `tests/lean/grind/grind_fin.lean` which I'm
intending to triage and work on.
2025-09-04 04:28:29 +00:00
Marcus Rossel
89aed0931e feat: improve error message when passing local hypotheses to grind (#8891)
This PR improves the error message produced when passing (automatically
redundant) local hypotheses to `grind`.
2025-09-04 03:00:21 +00:00
Sebastian Ullrich
92d24e1c40 fix: Environment.realizeConst to replay realization map (#10238)
This PR fixes an issue with retrieving realized declarations after use
of Aesop uncovered by #10229
2025-09-03 22:16:40 +00:00
Leonardo de Moura
c15ee8a9f0 fix: universe polymorphic E-matching (#10239)
This PR fixes the E-matching procedure for theorems that contain
universe parameters not referenced by any regular parameter. This kind
of theorem seldom happens in practice, but we do have instances in the
standard library. Example:
```
@[simp, grind =] theorem Std.Do.SPred.down_pure {φ : Prop} : (⌜φ⌝ : SPred []).down = φ := rfl
```

closes #10233
2025-09-03 22:14:58 +00:00
Leonardo de Moura
320b02108b fix: grind canonicalizer (#10237)
This PR fixes a missing case in the `grind` canonicalizer. Some types
may include terms or propositions that are internalized later in the
`grind` state.

closes #10232
2025-09-03 18:08:48 +00:00
Rob23oba
80df86dfdd feat: add more MonoBind instances for monad transformers (#10230)
This PR adds `MonoBind` for more monad transformers. This allows using
`partial_fixpoint` for more complicated monads based on `Option` and
`EIO`. Example:
```lean-4
abbrev M := ReaderT String (StateT String.Pos Option)

def parseAll (x : M α) : M (List α) := do
  if (← read).atEnd (← get) then
    return []
  let val ← x
  let list ← parseAll x
  return val :: list
partial_fixpoint
```
2025-09-03 17:15:41 +00:00
Paul Reichert
fef390df08 perf: improve iterator/range benchmarks, use shortcut instances for Int ranges (#10197)
This PR is the result of analyzing the elaborator performance regression
introduced by #10005. It makes the `workspaceSymboldNewRanges` and
`iterators` benchmarks less noisy. It also replaces some range-related
instances for `Nat` with shortcuts to the general-purpose instances.
This is a trade-off between the ergonomics and the synthesis cost of
having general-purpose instances.
2025-09-03 15:47:52 +00:00
Sebastian Ullrich
37be918c50 perf: do not export EqnInfo for non-exposed defs (#10229) 2025-09-03 10:03:52 +00:00
Sebastian Ullrich
2efbe4ac36 feat: support visibility modifiers on syntax abbrevs (#10228)
Closes #10068
2025-09-03 07:53:29 +00:00
Eric Wieser
6d68aab56a feat: generalize universes in monadic operators for collections (#10224)
This PR generalizes the monadic operations for `HashMap`, `TreeMap`, and
`HashSet` to work for `m : Type u → Type v`.

This upstreams [a workaround from
Aesop](66a992130e/Aesop/Util/Basic.lean (L57-L66)),
and seems to continue a pattern already established in other files, such
as:
```lean
Array.forM.{u, v, w} {α : Type u} {m : Type v → Type w} [Monad m] (f : α → m PUnit) (as : Array α) (start : Nat := 0)
  (stop : Nat := as.size) : m PUnit
```
2025-09-03 07:24:14 +00:00
Joachim Breitner
ccb8568756 feat: linear-size DecidableEq instance (#10152)
This PR introduces an alternative construction for `DecidableEq`
instances that avoids the quadratic overhead of the default
construction.

The usual construction uses a `match` statement that looks at each pair
of constructors, and thus is necessarily quadratic in size. For
inductive data type with dozens of constructors or more, this quickly
becomes slow to process.

The new construction first compares the constructor tags (using the
`.ctorIdx` introduced in #9951), and handles the case of a differing
constructor tag quickly. If the constructor tags match, it uses the
per-constructor-eliminators (#9952) to create a linear-size instance. It
does so by creating a custom “matcher” for a parallel match on the data
types and the `h : x1.ctorIdx = x2.ctorIdx` assumption; this behaves
(and delaborates) like a normal `match` statement, but is implemented in
a bespoke way. This same-constructor-matcher will be useful for
implementing other instances as well.

The new construction produces less efficient code at the moment, so we
use it only for inductive types with 10 or more constructors by default.
The option `deriving.decEq.linear_construction_threshold` can be used to
adjust the threshold; set it to 0 to always use the new construction.
2025-09-03 06:31:49 +00:00
Leonardo de Moura
a4f6f391fe feat: equality propagation from AC module to grind core (#10223)
This PR implements equality propagation from the new AC module into the
`grind` core. Examples:

```lean
example {α β : Sort u} (f : α → β) (op : α → α → α) [Std.Associative op] [Std.Commutative op] 
    (a b c d : α) : op a (op b b) = op d c → f (op (op b a) (op b c)) = f (op c (op d c)) := by
  grind only

example (a b c : Nat) : min a (max b (max c 0)) = min (max c b) a := by
  grind -cutsat only

example {α β : Sort u} (bar : α → β) (op : α → α → α) [Std.Associative op] [Std.IdempotentOp op]
    (a b c d e f x y w : α) :
    op d (op x c) = op a b →
    op e (op f (op y w)) = op (op d a) (op b c) →
    bar (op d (op x c)) = bar (op e (op f (op y w))) := by
  grind only
```
2025-09-02 23:02:25 +00:00
Leonardo de Moura
dac61c406f feat: extra critical pairs for associative + idempotent operators in grind ac (#10221)
This PR adds the extra critical pairs to ensure the `grind ac` procedure
is complete when the operator is associative and idempotent, but not
commutative. Example:
```lean
example {α : Sort u} (op : α → α → α) [Std.Associative op] [Std.IdempotentOp op] (a b c d e f x y w : α)
    : op d (op x c) = op a b →
      op e (op f (op y w)) = op a (op b c) →
      op d (op x c) = op e (op f (op y w)) := by
  grind only

example {α : Sort u} (op : α → α → α) [Std.Associative op] [Std.IdempotentOp op] (a b c d e f x y w : α)
    : op a (op d x) = op b c →
      op e (op f (op y w)) = op a (op b c) →
      op a (op d x) = op e (op f (op y w)) := by
  grind only
```
2025-09-02 15:52:56 +00:00
Henrik Böving
db35f98b26 fix: make csimp equivalence criteria more strict (#10214)
This PR fixes #10213.
2025-09-02 14:36:08 +00:00
Leonardo de Moura
e6f50b0181 perf: EqCnstr.superposeWith (#10218)
This PR adds a small optimization for `EqCnstr.superposeWith`
It also adds a new test unrelated to the optimization.
2025-09-02 13:50:47 +00:00
Dax Fohl
2877196656 doc: fix broken "quickstart" and "supported editors" link (#8785)
The "supported editors" link in
https://github.com/leanprover/lean4/blob/master/doc/dev/index.md is
broken, as `setup.md` no longer exists in the repo. This PR changes the
link to point to the live Lean docs setup page at
https://docs.lean-lang.org/lean4/doc/setup.html#editing.

A similar fix for quickstart is included.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-09-02 12:45:04 +00:00
Aaron Liu
f748d1c4ef doc: fix typo in docstring for fieldIdxKind (#8814)
This PR fixes a typo in the docstring for `Lean.fieldIdxKind`, which was
missing a backtick.
2025-09-02 12:30:07 +00:00
Eric Wieser
848832dd61 chore: demote a panic to an exception in saveModuleData (#9127)
This PR makes `saveModuleData` throw an IO.Error instead of panicking,
if given something that cannot be serialized. This doesn't really matter
for saving modules, but is handy when writing tools to save auxiliary
date in olean files via Batteries' `pickle`.

The caller of this C++ function already is guarded in a `try`/`catch`
that promotes from a `lean::exception` to an `IO.userError`.

A simple test of this in the web editor is
```
import Batteries

#eval pickle "/tmp/foo.txt" fun x : Nat => x
```
which crashes before this change.

---------

Co-authored-by: Laurent Sartran <lsartran@google.com>
2025-09-02 12:25:45 +00:00
Henrik Böving
c5f2c192d6 fix: Selectable.one does not panic on empty array (#10216)
This PR fixes #10193.
2025-09-02 11:55:36 +00:00
Sebastian Ullrich
96c42b95fa chore: CI: reintroduce lost CTEST_OPTIONS (#10211) 2025-09-02 09:26:29 +00:00
Leonardo de Moura
d826474b14 feat: extra critical pairs for AC + idempotent operators in grind ac (#10208)
This PR adds the extra critical pairs to ensure the `grind ac` procedure
is complete when the operator is AC and idempotent. Example:
```lean
example {α : Sort u} (op : α → α → α) [Std.Associative op] [Std.Commutative op] [Std.IdempotentOp op] 
      (a b c d : α) : op a (op b b) = op d c → op (op b a) (op b c) = op c (op d c)  := by
  grind only
```
2025-09-02 04:24:22 +00:00
Kim Morrison
8d9d23b5bb feat: (approximate) inverses of dyadic rationals (#10194)
This PR adds the inverse of a dyadic rational, at a given precision, and
characterising lemmas. Also cleans up various parts of the `Int.DivMod`
and `Rat` APIs, and proves some characterising lemmas about
`Rat.toDyadic`.

---------

Co-authored-by: Rob23oba <152706811+Rob23oba@users.noreply.github.com>
2025-09-02 03:43:53 +00:00
Leonardo de Moura
c83237baf7 chore: cleanup superposeAC? (#10207)
This PR ensures `superposeAC?` and `superpose?` have similar signatures.
2025-09-02 01:55:20 +00:00
Leonardo de Moura
11f618ac49 feat: critical pairs (non commutative case) for grind ac (#10206)
This PR adds superposition for associative (but non-commutative)
operators in `grind ac`. Examples:
```lean
example {α} (op : α → α → α) [Std.Associative op] (a b c d : α)
   : op a b = c →
     op b a = d →
     op (op c a) (op b c) = op (op a d) (op d b) := by
  grind

example {α} (a b c d : List α)
   : a ++ b = c →
     b ++ a = d →
     c ++ a ++ b ++ c = a ++ d ++ d ++ b := by
  grind only
```
2025-09-02 00:58:49 +00:00
Leonardo de Moura
708f715efb feat: critical pairs for grind ac (#10205)
This PR adds superposition for associative and commutative operators in
`grind ac`. Examples:

```lean
example (a b c d e f g h : Nat) :
    max a b = max c d → max b e = max d f → max b g = max d h →
    max (max f d) (max c g) = max (max e (max d (max b (max c e)))) h := by
  grind -cutsat only

example {α} (op : α → α → α) [Std.Associative op] [Std.Commutative op] (a b c d : α)
    : op a b = op b c → op c c = op d c →
      op (op d a) (op b d) = op (op a a) (op b d) := by
  grind only
```
2025-09-01 23:17:09 +00:00
Joachim Breitner
b0506ee835 chore: remove bootstrap tricks from #9951 (#10203)
This PR removes bootstrap tricks from #9951.
2025-09-01 13:30:42 +00:00
Joachim Breitner
f1737737f0 perf: use matcher as splitter (#10184)
This PR avoids constructing the splitter if the matcher itself has the
right type. This happens whenever there are no overlaps.
2025-09-01 11:29:43 +00:00
Joachim Breitner
f3b1f054ef perf: prove match equations by rfl if possible (#10183)
This PR lets match equations be proved by `rfl` if possible, instead of
explicitly unfolding the LHS first. May lead to smaller proofs.
2025-09-01 11:19:55 +00:00
Joachim Breitner
94ea5fb3fd test: add test for #10195 (#10200)
This PR adds a test for #10195
2025-09-01 10:14:54 +00:00
Rob23oba
5b9567b144 fix: complete overhaul of structural recursion on inductives predicates (#9995)
This PR almost completely rewrites the inductive predicate recursion
algorithm; in particular `IndPredBelow` to function more consistently.
Historically, the `brecOn` generation through `IndPredBelow` has been
very error-prone -- this should be fixed now since the new algorithm is
very direct and doesn't rely on tactics or meta-variables at all.
Additionally, the new structural recursion procedure for inductive
predicates shares more code with regular structural recursion and thus
allows for mutual and nested recursion in the same way it was possible
with regular structural recursion. For example, the following works now:
```lean-4
mutual

inductive Even : Nat → Prop where
  | zero : Even 0
  | succ (h : Odd n) : Even n.succ

inductive Odd : Nat → Prop where
  | succ (h : Even n) : Odd n.succ

end

mutual

theorem Even.exists (h : Even n) : ∃ a, n = 2 * a :=
  match h with
  | .zero => ⟨0, rfl⟩
  | .succ h =>
    have ⟨a, ha⟩ := h.exists
    ⟨a + 1, congrArg Nat.succ ha⟩
termination_by structural h

theorem Odd.exists (h : Odd n) : ∃ a, n = 2 * a + 1 :=
  match h with
  | .succ h =>
    have ⟨a, ha⟩ := h.exists
    ⟨a, congrArg Nat.succ ha⟩
termination_by structural h

end
```

Closes #1672
Closes #10004
2025-09-01 08:17:58 +00:00
Leonardo de Moura
c4e5f57512 feat: proof terms for grind ac (#10189)
This PR implements the proof terms for the new `grind ac` module.
Examples:
```lean
example {α : Sort u} (op : α → α → α) [Std.Associative op] (a b c d : α)
    : op a (op b b) = op c d → op c (op d c) = op (op a b) (op b c) := by
  grind only

example {α : Sort u} (op : α → α → α) [Std.Associative op] [Std.Commutative op] (a b c d : α)
    : op a (op b b) = op d c → op (op b a) (op b c) = op c (op d c)  := by
  grind only

example {α : Sort u} (op : α → α → α) [Std.Associative op] [Std.Commutative op]
    (one : α) [Std.LawfulIdentity op one] (a b c d : α)
    : op a (op (op b one) b) = op d c → op (op b a) (op (op b one) c) = op (op c one) (op d c)  := by
  grind only
```

The `grind ac` module is not complete yet, we still need to implement
critical pair computation and fix the support for idempotent operators.
2025-08-31 04:10:10 +00:00
Leonardo de Moura
f376fd87d0 feat: AC disequality simplification (#10186)
This PR adds supports for simplifying disequalities in the `grind ac`
module.
2025-08-30 20:42:21 +00:00
Leonardo de Moura
8e7e55f2d5 doc: grind attribute modifiers (#10185)
This PR documents all `grind` attribute modifiers (e.g., `=`, `usr`,
`ext`, etc).
2025-08-30 16:12:50 +00:00
Kim Morrison
8789e5621b feat: missing Nat.fold(Rev)_add lemmas (#10182)
This PR adds lemmas about `Nat.fold` and `Nat.foldRev` on sums, to match
the existing theorems about `dfold` and `dfoldRev`.
2025-08-30 08:54:12 +00:00
Leonardo de Moura
fbf096510d chore: minimize number of public imports in grind (#10180) 2025-08-30 03:38:47 +00:00
Leonardo de Moura
18cc1cec80 fix: grind instance normalization (#10179)
This PR fixes `grind` instance normalization procedure.
Some modules in grind use builtin instances defined directly in core
(e.g., `cutsat`), while others synthesize them using `synthInstance`
(e.g., `ring`). This inconsistency is problematic, as it may introduce
mismatches and result in two different representations for the same
term. This PR fixes the issue.
2025-08-30 02:24:26 +00:00
Leonardo de Moura
404b00a584 fix: grind preprocessor (#10177)
This PR fixes a bug in the `grind` preprocessor exposed by #10160.

Closes #10160
2025-08-29 23:37:52 +00:00
Leonardo de Moura
50ddf85b07 feat: check grind ac invariants (#10176)
This PR adds code for checking invariants in the `grind ac` module, and
fixes the bugs exposed by them.
2025-08-29 22:36:39 +00:00
Sofia Rodrigues
9107d27368 fix: remove extend from async and await (#10173)
This PR removes the `extends Monad` from `MonadAwait` and `MonadAsync`
to avoid underdetermined instances.

The issue was discussed here: [#lean4 > Is
Std.Internal.IO.Async.MonadAsync.toMonad a bad
instance?](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Is.20Std.2EInternal.2EIO.2EAsync.2EMonadAsync.2EtoMonad.20a.20bad.20instance.3F)
2025-08-29 15:33:57 +00:00
Wojciech Rozowski
d51a5b920d feat: change delimiting of local attributes in implicit sections (#9968)
This PR modifies macros, which implement non-atomic definitions and
```$cmd1 in $cmd2``` syntax. These macros involve implicit scopes,
introduced through ```section``` and ```namespace``` commands. Since
sections or namespaces are designed to delimit local attributes, this
has led to unintuitive behaviour when applying local attributes to
definitions appearing in the above-mentioned contexts. This has been
causing the following examples to fail:
```lean4
axiom A : Prop

namespace ex1
open Nat in
@[local simp] axiom a : A ↔ True
example : A := by simp
end ex1

namespace ex2
@[local simp] axiom Foo.a : A ↔ True
example : A := by simp
end ex2
```
This PR adds an internal-only piece of syntax,
```InternalSyntax.end_local_scope```, that influences the
```ScopedEnvExtension.addLocalEntry``` used in implementing local
attributes, to avoid delimiting local entries in the current scope. This
command is used in the above-mentioned macros.

Closes [#9445](https://github.com/leanprover/lean4/issues/9445).

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2025-08-28 15:48:42 +00:00
Wojciech Rozowski
eb013fb90d fix: construction of CompleteLattice instance for eta-reduced definitions (#10144)
This PR changes the construction of a `CompleteLattice` instance on
predicates (maps intro `Prop`) inside of
`coinductive_fixpoint`/`inductive_fixpoint` machinery.

Consider a following endomap on predicates of the type ` α → Prop`:
```lean4
def DefFunctor (r : α → α → Prop) (infSeq : α → Prop) : α → Prop :=
   λ x : α => ∃ y, r x y ∧ infSeq y
```
The following eta-reduced expression failed to elaborate:
```lean4
def def1 (r : α → α → Prop) : α → Prop := DefFunctor r (def1 r)
  coinductive_fixpoint monotonicity sorry
```

At the same time, eta-expanded variant would elaborate correctly:
```lean4
def def2 (r : α → α → Prop) : α → Prop := fun x => DefFunctor r (def2 r) x
  coinductive_fixpoint monotonicity sorry
```

This PR fixes the above issue, by changing the way how `CompleteLattice`
instance on the space of predicates is constructed, to allow for the
eta-reduced case, as outlined above.
2025-08-28 12:27:53 +00:00
Kim Morrison
4c44fdb95f chore: remove grind annotations of List/Array/Vector.zip_map_left/right (#10163)
This PR removes some (hopefully) unnecessary `grind` annotations that
cause instantiation explosions.
2025-08-28 10:38:50 +00:00
Sebastian Ullrich
d63d1188cc chore: fix stdlib size benchmarks 2025-08-28 12:07:27 +02:00
Lean stage0 autoupdater
a31d686ed1 chore: update stage0 2025-08-28 09:45:24 +00:00
Kim Morrison
a62dabeb56 feat: nodup_keys theorems for maps (#10159)
This PR adds `nodup_keys` lemmas as corollaries of existing
`distinct_keys` to all `Map` variants.
2025-08-28 06:00:28 +00:00
Kim Morrison
d2eb1bc9f5 chore: review of failing grind tests (#10166)
This PR reviews the expected-to-fail-right-now tests for `grind`, moving
some (now passing) tests to the main test suite, updating some tests,
and adding some tests about normalisation of exponents.
2025-08-28 05:24:31 +00:00
Leonardo de Moura
38608a672e feat: simplify equations in grind AC module (#10165)
This PR adds support for equality simplification helper functions to the
`grind` AC module.
2025-08-28 03:54:09 +00:00
Leonardo de Moura
86425f655a feat: helper AC.Seq functions (#10164)
This PR adds helper functions for the `AC.Seq` type.
2025-08-28 02:16:52 +00:00
Sebastian Ullrich
9757a7be53 perf: do not export opaque bodies (#10119)
In particular, do not export `partial` bodies
2025-08-27 20:59:59 +00:00
Marc Huisinga
3ce69e4edb feat: re-enable Suggestion.messageData? (#10157)
Re-enables `Suggestion.messageData?` after it was deprecated in #9966
since it is needed for the workaround described in #10150. We will
hopefully be able to clean up with API once #10150 is properly fixed.
2025-08-27 16:23:02 +00:00
Leonardo de Moura
2dda33ddb2 chore: remove workaround (#10156) 2025-08-27 15:18:17 +00:00
Sebastian Ullrich
655a39ceb8 chore: improve error message on trying to access an identifier imported privately from the public scope (#10153) 2025-08-27 13:43:56 +00:00
Sebastian Ullrich
8d26a9e8b5 chore: revert public deriving workarounds (#10155) 2025-08-27 13:15:18 +00:00
Joachim Breitner
72e8970848 chore: benchmarks for deriving DecidableEq on large inductives (#10149)
This PR adds benchmarks for deriving `DecidableEq` on inductives with
many constructors. (Although at the moment, many is “many” as we timeout
for more than 30 or 40 constructors.)
2025-08-27 12:05:04 +00:00
Sebastian Ullrich
697ea0bc01 fix: Unicode path support for Lean Windows executables (#10133)
This PR fixes compatibility of Lean-generated executables with Unicode
file system paths on Windows

Fixes #2554
2025-08-27 11:28:55 +00:00
Sebastian Ullrich
4d5fb31dfb fix: where finally should enter the private scope (#10151)
This PR ensures `where finally` tactics can access private data under
the module system even when the corresponding holes are in the public
scope as long as all of them are of proposition types.
2025-08-27 11:27:40 +00:00
Sebastian Ullrich
43dc9f45d1 chore: CI: disable broken test on macOS x64 2025-08-27 13:14:32 +02:00
Lean stage0 autoupdater
dc1ddda473 chore: update stage0 2025-08-27 10:47:56 +00:00
Joachim Breitner
b5555052bd feat: T.ctor.elim single-constructor cases function (#9952)
This PR adds “non-branching case statements”: For each inductive
constructor `T.con` this adds a function `T.con.with` that is similar
`T.casesOn`, but has only one arm (the one for `con`), and an additional
`t.toCtorIdx = 12` assumption.

For example:
```lean
inductive Vec (α : Type) : Nat → Type where
  | nil : Vec α 0
  | cons {n} : α → Vec α n → Vec α (n + 1)

/--
info: @[reducible] protected def Vec.cons.elim.{u} : {α : Type} →
  {motive : (a : Nat) → Vec α a → Sort u} →
    {a : Nat} →
      (t : Vec α a) →
        t.ctorIdx = 1 → ({n : Nat} → (a : α) → (a_1 : Vec α n) → motive (n + 1) (Vec.cons a a_1)) → motive a t
-/
#guard_msgs in
#print sig Vec.cons.elim
```

This is a building block for non-quadratic implementations of `BEq` and
`DecidableEq` etc.

Builds on top of #9951.

The compiled code for a these functions could presumably, without
branching on the inductive value, directly access the fields. Achieving
this optimization (and achieving it without a quadratic compilation
cost) is not in scope for this PR.
2025-08-27 09:40:31 +00:00
Lean stage0 autoupdater
e4ca32174c chore: update stage0 2025-08-27 09:58:40 +00:00
Sebastian Ullrich
d06fff0f13 chore: CI: use restored ccache cache in update-stage0 2025-08-27 11:44:46 +02:00
Sebastian Ullrich
e74e9694fe feat: revamp and unify visibility/exposure handling in deriving handlers (#10148)
Visibility is now handled implicitly for all deriving handlers by
adjusting section visibility according to the presence of private types
while removing exposition on presence of private constructors can be
opted in on a per-handler level via the new combinator
`withoutExposeFromCtors`.

Fixes #10062 #10063 #10064 #10065
2025-08-27 09:10:24 +00:00
thorimur
5bb7818355 feat: allow position reporting in #guard_msgs (#10125)
This PR allows `#guard_msgs` to report the relative positions of logged
messages with the config option `(positions := true)`.

Closes #8265
2025-08-27 06:47:34 +00:00
Kyle Miller
5bc42bf5ca fix: pretty print dot notation for private definitions on public types (#10122)
This PR adds support for pretty printing using generalized field
notation (dot notation) for private definitions on public types. It also
modifies dot notation elaboration to resolve names after removing the
private prefix, which enables using dot notation for private definitions
on private imported types.

It won't pretty print with dot notation for definitions on inaccessible
private types from other modules.

Closes #7297
2025-08-27 03:30:52 +00:00
Leonardo de Moura
aaec0f584c feat: ac normalization in grind (#10146)
This PR implements the basic infrastructure for the new procedure
handling AC operators in grind. It already supports normalizing
disequalities. Future PRs will add support for simplification using
equalities, and computing critical pairs. Examples:
```lean
example {α : Sort u} (op : α → α → α) [Std.Associative op] (a b c : α)
    : op a (op b c) = op (op a b) c := by
  grind only

example {α : Sort u} (op : α → α → α) (u : α) [Std.Associative op] [Std.LawfulIdentity op u] (a b c : α)
    : op a (op b c) = op (op a b) (op c u) := by
  grind only

example {α : Type u} (op : α → α → α) (u : α) [Std.Associative op] [Std.Commutative op] 
    [Std.IdempotentOp op] [Std.LawfulIdentity op u] (a b c : α)
    : op (op a a) (op b c) = op (op (op b a) (op (op u b) b)) c := by
  grind only

example {α} (as bs cs : List α) : as ++ (bs ++ cs) = ((as ++ []) ++ bs) ++ (cs ++ []) := by
  grind only

example (a b c : Nat) : max a (max b c) = max (max b 0) (max a c) ∧ min a b = min b a := by
  grind only [cases Or]
```
2025-08-27 03:28:30 +00:00
Mac Malone
db3fb47109 refactor: port more of shell.cpp to Lean (#10086)
This PR ports more of the post-initialization C++ shell code to Lean.

All that remains is the initialization of the profiler and task manager.
As initialization tasks rather than main shell code, they were left in
C++ (where the rest of the initialization code currently is).

The `max_memory` and `timeout` Lean options used by the the `--memory`
and `--timeout` command-line options are now properly registered. The
server defaults for max memory and max heartbeats (timeout) were removed
as they were not actually used (because the `server` option that was
checked was neither set nor exists).

This PR also makes better use of the module system in `Shell.lean` and
fixes a minor bug in a previous port where the file name check was
dependent on building the `.ilean` rather than the `.c` file (as was
originally the case).

Fixes #9879.
2025-08-26 20:02:42 +00:00
Joachim Breitner
c83674bdff chore: revert use of macro_inline for ctorIdx (#10141)
This PR reverts the `macro_inline` part of #10135.
2025-08-26 18:07:49 +00:00
Leonardo de Moura
2652cc18b8 chore: error messages consistency (#10143)
This PR standardizes error messages by quoting names with backticks. The
changes were automated, so some cases may still be missing.
2025-08-26 17:55:43 +00:00
Lean stage0 autoupdater
62e00fb5a0 chore: update stage0 2025-08-26 17:42:03 +00:00
Marc Huisinga
2324c0939d chore: add private getUtf8Byte' to Init.Meta (#10140)
This PR adds a private `Lean.Name.getUtf8Byte'` to `Init.Meta` for a
future PR that optimizes `Lean.Name.escapePart`.
`Lean.Name.getUtf8Byte'` should be replaced with `String.getUtf8Byte`
once the string refactor is through.
2025-08-26 16:54:02 +00:00
Sebastian Ullrich
425bebe99e chore: further split libleanshared on Windows to avoid symbol limit (#10136)
Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
2025-08-26 16:01:57 +00:00
Lean stage0 autoupdater
a0613f4d12 chore: update stage0 2025-08-26 16:01:23 +00:00
Sebastian Ullrich
298bd10f54 perf: do not cause compiler.small to export IR bodies unless the Expr body is already being exported (#10002) 2025-08-26 15:12:08 +00:00
Sebastian Ullrich
6810d31602 chore: CI: cache again on failure (#10137) 2025-08-26 14:47:05 +00:00
Luisa Cicolini
3e11f27ff4 feat: add fast circuit for unsigned multiplication overflow detection fastUmulOverflow_eq and surrounding definitions (#7858)
This PR implements the fast circuit for overflow detection in unsigned
multiplication used by Bitwuzla and proposed in:
https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=987767

The theorem is based on three definitions: 
* `uppcRec`: the unsigned parallel prefix circuit for the bits until a
certain `i`
* `aandRec`: the conjunction between the parallel prefix circuit at of
the first operand until a certain `i` and the `i`-th bit in the second
operand
* `resRec`: the preliminary overflow flag computed with these two
definitions
To establish the correspondence between these definitiions and their
meaning in `Nat`, we rely on `clz` and `clzAuxRec` definitions.
Therefore, this PR contains the `clz`- and `clzAuxRec`-related
infrastructure that was necessary to get the proofs through.

An additional change this PR contains is the moving of `### Count
leading zeros` section in `BitVec.Lemmas` downwards. In fact, some of
the proofs I wrote required introducing `Bitvec.toNat_lt_iff` and
`BitVec.le_toNat_iff` which I believe should live in the `Inequalities`
section. Therefore, to put these in the appropriate section, I decided
to move the whole `clz` section downwards (while it's small and
relatively self contained. Specifically, the theorems I moved are:
`clzAuxRec_zero`, `clzAuxRec_succ`, `clzAuxRec_eq_clzAuxRec_of_le`,
`clzAuxRec_eq_clzAuxRec_of_getLsbD_false`.
 
The fast circuit is not yet the default one in the bitblaster, as it's
performance is not yet competitive due to some missing rewrites that
bitwuzla supports but are not in Lean yet.
 
co-authored-by: @bollu

---------

Co-authored-by: Tobias Grosser <tobias@grosser.es>
2025-08-26 13:21:23 +00:00
Kim Morrison
a78a34bbd7 chore: replace Lean.Grind internal preorder classes with the classes from Std (#10129)
This PR replaces the interim order typeclasses used by `Grind` with the
new publicly available classes in `Std`.
2025-08-26 13:18:22 +00:00
Joachim Breitner
0803f1e77e perf: ctorIdx for single-constructor inductives: no casesOn, macro_inline (#10135)
This PR lets the `ctorIdx` definition for single constructor inductives
avoid the pointless `.casesOn`, and uses `macro_inline` to avoid
compiling the function and wasting symbols.
2025-08-26 13:00:10 +00:00
Kim Morrison
9e47edd0df feat: lemmas about rounding dyadics (#10138)
This PR adds lemmas about the `Dyadic.roundUp` and `Dyadic.roundDown`
operations.
2025-08-26 12:31:40 +00:00
Kim Morrison
0f1174d097 chore: use SMul rather than HMul in grind algebra typeclasses (#10095)
This PR modifies the `grind` algebra typeclasses to use `SMul x y`
instead of `HMul x y y`.
2025-08-26 12:23:37 +00:00
Marc Huisinga
f180eee7bf feat: use widget message for "try this" (#9966)
This PR adjusts the "try this" widget to be rendered as a widget message
under 'Messages', not a separate widget under a 'Suggestions' section.
The main benefit of this is that the message of the widget is not
duplicated between 'Messages' and 'Suggestions'.

Since widget message suggestions were already implemented by @jrr6 for
the new hint infrastructure, this PR replaces the old "try this"
implementation with the new hint infrastructure. In doing so, the
`style?` field of suggestions is deprecated, since the hint
infrastructure highlights hints using diff colors, and `style?` also
never saw much use downstream. Additionally, since the message and the
suggestion are now the same component, the `messageData?` field of
suggestions is deprecated as well. Notably, the "Try this:" message
string now also contains a newline and indentation to separate the
suggestion from the rest of the message more clearly and the `postInfo?`
field of the suggestion is now part of the message.

Finally, this PR changes the diff colors used by the hint infrastructure
to be more color-blindness-friendly (insertions are now blue, not green,
and text that remains unchanged is now using the editor foreground color
instead of blue).

### Breaking changes
Tests that use `#guard_msgs` to test the "Try this:" message may need to
be adjusted for the new formatting of the message.
2025-08-26 12:15:32 +00:00
Sebastian Ullrich
6a3fc281ad chore: CI: use Namespace.so checkout action for Linux Lake (#10103) 2025-08-26 09:19:58 +00:00
Lean stage0 autoupdater
06e9f4735a chore: update stage0 2025-08-26 09:46:07 +00:00
Joachim Breitner
0f5f2df11f fix: FunInd: handle let-vars-in-match-better (#10134)
This PR makes the generation of functional induction principles more
robust when the user `let`-binds a variable that is then `match`'ed on.
Fixes #10132.
2025-08-26 08:56:00 +00:00
Joachim Breitner
aa0cf78d93 chore: create .toCtorIdx alias only for enumeration types (#10130)
This PR creates the deprecated `.toCtorIdx` alias only for enumeration
types, which are the types that used to have this function. No need
generating an alias for types that never had it. Should reduce the
number of symbols in the standard library.
2025-08-26 08:33:37 +00:00
Sebastian Ullrich
4f94972ff1 chore: avoid panic in addDocString on partial elaboration (#10131) 2025-08-26 08:16:27 +00:00
Joachim Breitner
37dd26966b fix: rcases: avoid inflating case names with single constructor names (#9918)
This PR prevents `rcases` and `obtain` from creating absurdly long case
tag names when taking single constructor types (like `Exists`) apart.
Fixes #6550

The change does not affect `cases` and `induction`, it seems (where the
user might be surprised to not address the single goal with a name),
because I make the change in Lean/`Meta/Tactic/Induction.lean`, not
`Lean/Elab/Tactic/Induction.lean`. Yes, that's confusing.
2025-08-26 07:56:32 +00:00
Leonardo de Moura
1feac1ae92 chore: simplify grind import graph (#10128) 2025-08-26 06:34:44 +00:00
Leonardo de Moura
3ff195f7b2 refactor: grind build times (#10127) 2025-08-26 06:01:50 +00:00
Leonardo de Moura
5478dcf373 refactor: grind build times (#10126) 2025-08-26 04:06:37 +00:00
Kim Morrison
ad3e975178 feat: dyadic rationals (#9993)
This PR defines the dyadic rationals, showing they are an ordered ring
embedding into the rationals. We will use this for future interval
arithmetic tactics.

Many thanks to @Rob23oba, who did most of the implementation work here.

---------

Co-authored-by: Rob23oba <robin.arnez@web.de>
2025-08-26 03:49:39 +00:00
Leonardo de Moura
cd9865b26b refactor: grind build times (#10124) 2025-08-26 01:05:18 +00:00
Leonardo de Moura
8c4db341dd chore: use ofConstName in error messages (#10121) 2025-08-25 23:20:36 +00:00
Kim Morrison
a6a02fe6b9 chore: reduce Int imports on the critical path (#10123)
This PR shortens the rebuild critical path at
https://speed.lean-lang.org/lean4-out/cbf3814a565f7188f830f365453fb0bdd66d6175/
2025-08-25 23:07:02 +00:00
Kyle Miller
741347281c fix: dot notation for recursive invocation of private definitions (#10120)
This PR fixes an issue where private definitions recursively invoked
using generalized field notation (dot notation) would give an "invalid
field" errors. It also fixes an issue where "invalid field notation"
errors would pretty print the name of the declaration with a `_private`
prefix.

Closes #10044
2025-08-25 22:55:08 +00:00
Kim Morrison
a06e6e7f4d chore: make UInt.Lemmas a private import of String.Extra (#10115)
This PR makes the `Init.Data.UInt.Lemmas` import into
`Init.Data.String.Extra` private; previously this import was on the
rebuild critical path.
2025-08-25 16:46:22 +00:00
Lean stage0 autoupdater
505d5c6013 chore: update stage0 2025-08-25 17:01:52 +00:00
Joachim Breitner
13e8cb5a3a perf: reorder DiscrTree.Key constructors (#10110)
this PR reorders the `DiscrTree.Key` constructors to match the order
given in the manually written `DiscrTree.Key.ctorIdx`. This allows us to
use the auto-generated one, and moreover lets this code benefit from
special compiler support for `.ctorIdx`, once that lands.
2025-08-25 16:13:43 +00:00
Marc Huisinga
2107f45991 chore: revert #10111 (#10118)
Identical to #10052. #10116 fixed the underlying cause of test
flakiness, so this PR should hopefully be good-to-go now.
2025-08-25 15:45:03 +00:00
Marc Huisinga
a72f9429ea test: sort messages (#10116)
This PR normalizes the published diagnostics in the test runner so that
messages published out of order (due to parallelism) cannot cause test
failures. Clients can handle out-of-order messages just fine.
2025-08-25 15:08:11 +00:00
Sebastian Ullrich
321af0e02b fix: public structures with private field types under the module system (#10109)
Fixes #10099
2025-08-25 14:48:23 +00:00
Joachim Breitner
1718ca21cd feat: deprecate .toCtorIdx for .ctorIdx (#10113)
This PR deprecates `.toCtorIdx` for the more naturally named `.ctorIdx`
(and updates the standard library).
2025-08-25 14:32:05 +00:00
Sebastian Ullrich
f4ce319f1b chore: minimize Lean.Expr import (#10112) 2025-08-25 13:35:21 +00:00
Marc Huisinga
340c3da6ae chore: revert #10052 (#10111)
Potential suspect for flaky test failure.
2025-08-25 11:29:21 +00:00
Lean stage0 autoupdater
afbf52896f chore: update stage0 2025-08-25 11:31:26 +00:00
Joachim Breitner
afcf52e623 feat: .ctorIdx for all inductives (#9951)
This PR generates `.ctorIdx` functions for all inductive types, not just
enumeration types. This can be a building block for other constructions
(`BEq`, `noConfusion`) that are size-efficient even for large
inductives.

It also renames it from `.toCtorIdx` to `.ctorIdx`, which is the more
idiomatic naming.
The old name exists as an alias, with a deprecation attribute to be
added after the next
stage0 update.

These functions can arguably compiled down to a rather efficient tag
lookup, rather than a `case` statement. This is future work (but
hopefully near future).

For a fair number of basic types the compiler is not able to compile a
function using `casesOn` until further definitions have been defined.
This therefore (ab)uses the `genInjectivity` flag and
`gen_injective_theorems%` command to also control the generation of this
construct.

For (slightly) more efficient kernel reduction one could use `.rec`
rather than `.casesOn`. I did not do that yet, also because it
complicates compilation.
2025-08-25 10:47:06 +00:00
Sebastian Ullrich
3c40ea2733 chore: revert automatically exposing derived instances (#10101)
Heed surrounding `@[expose]` instead
2025-08-25 08:55:10 +00:00
Marc Huisinga
c95100e8fd fix: de-prioritize PartialTermInfo in hover info selection (#10047)
This PR ensures that hovering over `match` displays the type of the
match.
2025-08-25 08:47:14 +00:00
Marc Huisinga
be4651a772 fix: don't block fileworker with lake setup-file (#10052)
This PR fixes a bug that caused the Lean server process tree to survive
the closing of VS Code.

The cause of this issue was that the file worker main task was blocked
on waiting for the result of `lake setup-file` because the blocking call
was lifted outside of the dedicated server task that was supposed to
contain it by the compiler.
2025-08-25 08:47:01 +00:00
Rob23oba
797985e319 feat: upstream several Rat lemmas from mathlib (#10077)
This PR upstreams lemmas about `Rat` from `Mathlib.Data.Rat.Defs` and
`Mathlib.Algebra.Order.Ring.Unbundled.Rat`, specifically enough to get
`Lean.Grind.Field Rat` and `Lean.Grind.OrderedRing Rat`. In addition to
the lemmas, instances for `Inv Rat`, `Pow Rat Nat` and `Pow Rat Int`
have been upstreamed.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2025-08-25 06:02:27 +00:00
Kim Morrison
c9f08de7b3 feat: Lean.Grind.AddCommGroup instance for Rat (#10107)
This PR adds the `Lean.Grind.AddCommGroup` instance for `Rat`.
2025-08-25 05:15:26 +00:00
Leonardo de Moura
9be2eab93d feat: associative operator detection in grind (#10105)
This PR adds support for detecting associative operators in `grind`. The
new AC module also detects whether the operator is commutative,
idempotent, and whether it has a neutral element. The information is
cached.
2025-08-25 03:07:16 +00:00
Leonardo de Moura
cc5ff2afb1 test: grind cutsat (#10106) 2025-08-25 03:04:32 +00:00
Kim Morrison
5651192fa2 chore: fix error in Grind/Arith/Linear/StructId (#10096)
I'm unsure how this was ever working. Is this dead code?
2025-08-25 01:09:23 +00:00
Sebastian Ullrich
5ccea92a09 chore: revert "chore: CI: use Namespace.so checkout action for Linux Lake" (#10102)
Reverts leanprover/lean4#10100 pending a fix for running it on master
2025-08-24 15:58:25 +00:00
Sebastian Ullrich
3fc3f5d240 chore: CI: use Namespace.so checkout action for Linux Lake (#10100)
~1min ~> ~10s
2025-08-24 15:24:50 +00:00
Lean stage0 autoupdater
dca16fb58c chore: update stage0 2025-08-24 15:22:55 +00:00
Sebastian Ullrich
20d66250df feat: optional @[expose] specifier on deriving classes (#10060)
This PR allows for more fine-grained control over what derived instances
have exposed definitions under the module system: handlers should not
expose their implementation unless either the deriving item or a
surrounding section is marked with `@[expose]`. Built-in handlers to be
updated after a stage 0 update.
2025-08-24 14:42:18 +00:00
Kim Morrison
47632f27f6 chore: protect some theorems in the Rat namespace (#10097) 2025-08-24 10:51:47 +00:00
Leonardo de Moura
dfdd682c01 feat: AC theorems for grind (#10093)
This PR adds background theorems for a new solver to be implemented in
`grind` that will support associative and commutative operators.
2025-08-24 05:02:37 +00:00
Cameron Zwarich
8e828216e5 perf: inline dependent instances into specialized decls (#10080) 2025-08-24 00:12:27 +00:00
Lean stage0 autoupdater
92037b5b1b chore: update stage0 2025-08-23 23:33:05 +00:00
Mac Malone
a93e315e72 fix: include all of Lake.Util in core build (#10090)
This PR adds the modules in `Lake.Util` to core's Lake configuration to
ensure all utilities are built. With the module system port, they were
no longer all transitively imported.

Specifically, `Lake.Util.Lock` is unused because Lake does not currently
use a lock file for the build.
2025-08-23 22:55:39 +00:00
Mac Malone
902484988e fix: include Lake.Load in core build (#10087)
This PR adds `Lake.Load` to core's Lake configuration to ensure it is
built. With the module system port, it was no longer transitively
imported.
2025-08-23 21:52:15 +00:00
David Thrane Christiansen
c9727c2d19 feat: add a stop position field to the parser (#10043)
This PR allows Lean's parser to run with a final position prior to the
end of the string, so it can be invoked on a sub-region of the input.

This has applications in Verso proper, which parses Lean syntax in
contexts such as code blocks and docstrings, and it is a prerequisite to
parsing the contents of Lean docstrings.
2025-08-23 18:29:51 +00:00
Kyle Miller
0d9b7fb6b8 feat: adds rawIdent parser alias (#10085)
This PR adds a parser alias for the `rawIdent` parser, so that it can be
used in `syntax` declarations in `Init`.
2025-08-23 17:24:33 +00:00
Kyle Miller
db43de7b9d feat: add enter [in patt] syntax (#10081)
This PR adds `enter [in patt]` syntax. The implementation will come in a
followup PR, and it will stand for `pattern patt`.
2025-08-23 17:16:53 +00:00
Sebastian Ullrich
17f76f3bd7 chore: CI: recover dropped install suffixes (#10076) 2025-08-23 15:15:26 +00:00
Kim Morrison
6f69715f0a feat: replace Std.Internal.Rat (#9979)
This PR replaces `Std.Internal.Rat` with the new public `Rat` upstreamed
from Batteries.

The time library was depending on some defeqs which are no longer true,
so I have inserted some casts.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
Co-authored-by: Sofia Rodrigues <sofia@algebraic.dev>
2025-08-23 12:07:01 +00:00
Kim Morrison
2b34d5b899 feat: more Int lemmas in preparation for dyadics (#10075)
This PR contains lemmas about `Int` (minor amendments for BitVec and
Nat) that are being used in preparing the dyadics. This is all work of
@Rob23oba, which I'm pulling out of #9993 early to keep that one
manageable.
2025-08-23 04:59:59 +00:00
Cameron Zwarich
0881a8872b chore: use dotted constructor names (#10074) 2025-08-23 04:52:19 +00:00
Cameron Zwarich
91a2de1e1e chore: use forallTelescope rather than forallTelescopeReducing (#10073) 2025-08-23 04:07:23 +00:00
Cameron Zwarich
4a7def9e5f chore: use Expr.fvarId! and FVarId.getType (#10072) 2025-08-23 04:04:57 +00:00
Cameron Zwarich
dc5766d27a fix: eliminate infinite loop in toLCNF's expandNoConfusionMajor (#10070)
This PR fixes the compilation of `noConfusion` by repairing an oversight
made when porting this code from the old compiler. The old compiler only
repeatedly expanded the major for each non-`Prop` field of the inductive
under consideration, mirroring the construction of `noConfusion` itself,
whereas the new compiler erroneously counted all fields.

Fixes #9971.
2025-08-23 02:18:51 +00:00
Leonardo de Moura
a63d483258 feat: pow support in grind cutsat (#10071)
This PR improves support for `a^n` in `grind cutsat`. For example, if
`cutsat` discovers that `a` and `b` are equal to numerals, it now
propagates the equality. This PR is similar to #9996, but `a^b`.
Example:

```lean
example (n : Nat) : n = 2 → 2 ^ (n+1) = 8 := by
  grind
```

With #10022, it also improves the support for `BitVec n` when `n` is not
numeral. Example:

```lean
example {n m : Nat} (x : BitVec n)
    : 2 ≤ n → n ≤ m → m = 2 → x = 0 ∨ x = 1 ∨ x = 2 ∨ x = 3 := by
  grind
```
2025-08-23 01:55:05 +00:00
Mac Malone
1f9bba9d39 refactor: lake: use module (#9749)
This PR refactors the Lake codebase to use the new module system
throughout. Every module in `Lake` is now a `module`.

As this was already a large-scale refactor, a general cleanup of the
code has also been bundled in.

This PR also uses workarounds for currently outstanding module system
issues: #10061, #10062, #10063, #10064, #10065, #10067, and #10068.

**Breaking change:** Since the module system encourages a
`private`-by-default design, the Lake API has switched from its previous
`public`-by-default approach. As such, many definitions that were
previously public are now private. The newly private definitions are not
expected to have had significant user use, Nonetheless, important use
cases could be missed. If a key API is now inaccessible but seems like
it should be public, users are encouraged to report this as an issue on
GitHub.
2025-08-22 23:02:33 +00:00
Leonardo de Moura
5daf65ec56 feat: add helper theorems for NatModule (#10069)
This PR adds helper theorems to support `NatModule` in `grind linarith`.
2025-08-22 20:36:05 +00:00
Paul Reichert
9d4665a0bf perf: quick fix for range elaboration performance (#10066)
This PR reverts parts of #10005 that surprisingly turned out to cause a
performance regression in the benchmarks. The slowdown seems to be
related to elaboration, not inefficiencies in the generated code. This
is just a quick fix. I will take a closer look in a week.
2025-08-22 20:30:13 +00:00
Lean stage0 autoupdater
6df94385c5 chore: update stage0 2025-08-22 17:52:06 +00:00
David Thrane Christiansen
82932ec86a feat: add stop position to parser (#10057)
This PR adds a stop position field to parser input contexts, allowing
the parser to be instructed to stop parsing prior to the end of a file.

This is step 1, prior to a stage0 update, to make run-time data
structures sufficiently compatible to avoid segfaults. After the update,
the actual code to stop parsing can be merged.
2025-08-22 17:04:04 +00:00
Lean stage0 autoupdater
3d7d35b588 chore: update stage0 2025-08-22 16:03:06 +00:00
Sebastian Ullrich
fb23d7b45d chore: make parseQuotWithCurrentStage do what it says under prefer_native (#10058)
Switch on the interpreter when entering quotations under this option
2025-08-22 15:14:43 +00:00
Paul Reichert
f12177d01e feat: introduce Int range notation (#10045)
This PR implements the necessary typeclasses so that range notation
works for integers. For example, `((-2)...3).toList = [-2, -1, 0, 1, 2]
: List Int`.
2025-08-22 14:41:39 +00:00
Sebastian Ullrich
68654c231b doc: fix examples link 2025-08-22 16:28:01 +02:00
Lean stage0 autoupdater
2adc21f28b chore: update stage0 2025-08-22 14:07:57 +00:00
Sebastian Ullrich
0528696bbe fix: deriving DecidableEq under the module system (#10030)
Fixes #9839
2025-08-22 13:18:31 +00:00
Sebastian Ullrich
51bba5338a perf: make macro scope numbering less dependent on surrounding context (#10027)
This PR changes macro scope numbering from per-module to per-command,
ensuring that unrelated changes to other commands do not affect macro
scopes generated by a command, which improves `prefer_native` hit rates
on bootstrapping as well as avoids further rebuilds under the module
system.

In detail, instead of always using the current module name as a macro
scope prefix, each command now introduces a new macro scope prefix
(called "context") of the shape `<main module>._hygCtx_<uniq>` where
`uniq` is a `UInt32` derived from the command but automatically
incremented in case of conflicts (which must be local to the current
module). In the current implementation, `uniq` is the hash of the
declaration name, if any, or else the hash of the full command's syntax.
Thus, it is always independent of syntactic changes to other commands
(except in case of hash conflicts, which should only happen in practice
for syntactically identical commands) and, in the case of declarations,
also independent of syntactic changes to any private parts of the
declaration.
2025-08-22 13:16:02 +00:00
Sebastian Ullrich
561a4510b3 fix: auto params on private structure fields (#10053) 2025-08-22 12:49:37 +00:00
Sebastian Ullrich
0e8838df3b chore: avoid confusing public import all combination (#10051) 2025-08-22 12:04:42 +00:00
Kim Morrison
385daa99a8 chore: cleanup in Data/Rat (#10050)
This PR fixes some naming issues in Data/Rat/Lemmas, and upstreams the
eliminator `numDenCasesOn` and its relatives.
2025-08-22 12:00:19 +00:00
Kim Morrison
7595bc0791 feat: theorems about Nat/Int/Rat needed for dyadics (#10049)
This PR adds some background material needed for introducing the dyadic
rationals in #9993.
2025-08-22 11:45:16 +00:00
Rob23oba
9c6b698227 perf: fast version of Nat.log2 (#10046)
This PR replaces the implementation of `Nat.log2` with a version that
reduces faster.
The new version can handle:
```lean-4
example : Nat.log2 (1 <<< 500) = 500 := rfl
```
2025-08-22 11:32:00 +00:00
Henrik Böving
962ba9649c perf: try to reduce amount of code generated by HashMaps (#9941)
Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-08-22 11:24:11 +00:00
Sebastian Ullrich
8c8a6021af perf: use constant macro scope in elabArrow (#10048)
Shrinks .olean size by avoiding variation in this very frequent but
mostly unused name
2025-08-22 11:16:05 +00:00
Lean stage0 autoupdater
584ed5f33e chore: update stage0 2025-08-22 08:30:43 +00:00
Mac Malone
1523ed1cdb chore: allow module in LakeMain (#10039)
This PR enables core's `LakeMain` to be a `module` when core is built
without `USE_LAKE`.

This was a problem when porting Lake to the module system (#9749).
2025-08-22 07:45:42 +00:00
Jason Yuen
facc356a0a chore: fix spelling errors (#10042)
Typos were found with
```
pip install codespell --upgrade
codespell --summary --ignore-words-list enew,forin,fro,happend,hge,ihs,iterm,spred --skip stage0 --check-filenames
codespell --summary --ignore-words-list enew,forin,fro,happend,hge,ihs,iterm,spred --skip stage0 --check-filenames --regex '[A-Z][a-z]*'
codespell --summary --ignore-words-list enew,forin,fro,happend,hge,ihs,iterm,spred --skip stage0 --check-filenames --regex "\b[a-z']*"
```
2025-08-22 07:23:12 +00:00
Paul Reichert
c4b3f303bb feat: more convenient creation of polymorphic range instances (#10005)
This PR shortens the work necessary to make a type compatible with the
polymorphic range notation. In the concrete case of `Nat`, it reduces
the required lines of code from 150 to 70.
2025-08-22 07:08:33 +00:00
Paul Reichert
1448493489 feat: improvements to Min/Max-related classes (#10024)
This PR adds useful declarations to the `LawfulOrderMin/Max` and
`LawfulOrderLeftLeaningMin/Max` API. In particular, it introduces
`.leftLeaningOfLE` factories for `Min` and `Max`. It also renames
`LawfulOrderMin/Max.of_le` to .of_le_min_iff` and `.of_max_le_iff` and
introduces a second variant with different arguments.
2025-08-22 07:08:00 +00:00
Cameron Zwarich
f7a251b75f chore: set experimental.module=true when running grind benchmarks (#10041) 2025-08-22 03:15:36 +00:00
Cameron Zwarich
5aa706435a fix: incorporate info from _redArg decls for noncomputable check (#10040)
This PR changes the `toMono` pass to replace decls with their `_redArg`
equivalent, which has the consequence of not considering arguments
deemed useless by the `reduceArity` pass for the purposes of the
`noncomputable` check.
2025-08-22 01:02:40 +00:00
Leonardo de Moura
a581433d8b fix: grind error messages (#10038)
This PR ensures `grind` error messages use `{.ofConstName declName}`
when referencing declaration names.
2025-08-21 23:28:26 +00:00
Leonardo de Moura
6683d1eb91 chore: add module keyword to grind tests (#10036)
This PR also fixes missing `@[expose]` in grind support definitions.
2025-08-21 22:02:08 +00:00
Cameron Zwarich
504d71f268 chore: remove unnecessary code handling cases of an erased value (#10035)
This is now all handled in `toLCNF`.
2025-08-21 21:55:10 +00:00
Cameron Zwarich
ca4322ff09 fix: support casesOn for inductive predicates with computations on fields (#10023)
This PR adds support for correctly handling computations on fields in
`casesOn` for inductive predicates that support large elimination. In
any such predicate, the only relevant fields allowed are those that are
also used as an index, in which case we can find the supplied index and
use that term instead.
2025-08-21 18:55:34 +00:00
Cameron Zwarich
d32f04ba21 refactor: split out an isInductivePredicateVal function (#10033)
This is just like `isInductivePredicate?`, but on an existing
`InductiveVal` rather than one that is looked up by name.
2025-08-21 18:05:14 +00:00
Leonardo de Moura
0db795a1dc feat: improve grind cutsat support for Fin n when n is not a numeral (#10022)
This PR improves support for `Fin n` in `grind cutsat` when `n` is not a
numeral. For example, the following goals can now be solved
automatically:

```lean
example (p d : Nat) (n : Fin (p + 1)) 
    : 2 ≤ p → p ≤ d + 1 → d = 1 → n = 0 ∨ n = 1 ∨ n = 2 := by
  grind

example (s : Nat) (i j : Fin (s + 1)) (hn : i ≠ j) (hl : ¬i < j) : j < i := by
  grind

example {n : Nat} (j : Fin (n + 1)) : j ≤ j := by
  grind

example {n : Nat} (x y : Fin ((n + 1) + 1)) (h₂ : ¬x = y) (h : ¬x < y) : y < x := by
  grind
```
2025-08-21 17:25:52 +00:00
Mac Malone
d9a73dd1e3 feat: @[expose] on Lean.ParserState.setPos (#10019)
This PR adds `@[expose]` to `Lean.ParserState.setPos`. This makes it
possible to prove in-boundedness for a state produced by `setPos` for
functions like `next'` and `get'` without needing to `import all`.

This came up while porting Lake to the module system (#9749).
2025-08-21 17:24:10 +00:00
Joachim Breitner
e9f6033467 chore: benchmark for deriving BEq on large inductive (#10028) 2025-08-21 15:50:12 +00:00
Cameron Zwarich
0c9bb4b861 fix: lower overapplied constructors to unreachable (#10032)
This PR changes the handling of overapplied constructors when lowering
LCNF to IR from a (slightly implicit) assertion failure to producing
`unreachable`. Transformations on inlined unreachable code can produce
constructor applications with additional arguments.

In the old compiler, these additional arguments were silently ignored,
but it seems more sensible to replace them with `unreachable`, just in
case they arise due to a compiler error.

Fixes #9937.
2025-08-21 15:05:09 +00:00
Sebastian Ullrich
9b4911f8f6 chore: CI: fix Linux Lake on PR half-merge (#10029) 2025-08-21 13:25:53 +00:00
Sebastian Ullrich
f678b40660 chore: make USE_LAKE the default (#10016) 2025-08-21 11:43:25 +00:00
Joachim Breitner
890722f571 refactor: factor out mkNatLookupTable (#10006)
This PR shares the meta code that creates a binary decision tree on
Nats.
2025-08-21 10:45:21 +00:00
Marc Huisinga
ef1ca99bff chore: simplify require config in lakefile.toml schema (#10001)
This PR simplifies the `require` config of the lakefile.toml schema in
order to present simpler completions for dependency configuration.
2025-08-21 08:30:42 +00:00
Mac Malone
26fdc1e19a feat: deriving BEq, Hashable for Lean.Import (#10018)
This PR derives `BEq` and `Hashable` for `Lean.Import`. Lake already did
this later, but it now done when defining `Import`.

Doing this in Lake became problematic when porting it to the module
system (#9749).
2025-08-21 07:53:30 +00:00
Mac Malone
0b0d183c1d feat: @[expose] on Name.append & friends (#10015)
This PR exposes the bodies of `Name.append`, `Name.appendCore`, and
`Name.hasMacroScopes`. This enables proof by reflection of the
concatenation of name literals when using the module system.

```lean
example : `foo ++ `bar = `foo.bar := rfl
```

This is necessary for Lake as part of the port to using `module`
(#9749).
2025-08-21 07:52:59 +00:00
Kim Morrison
21f5263f2f feat: minor quality of life improvements in script/AnalyzeGrindAnnotations (#10021)
This PR make some minor changes to the grind annotation analysis script,
including sorting results and handling errors. Still need to add an
external UI.
2025-08-21 04:12:21 +00:00
Lean stage0 autoupdater
02edc0bd92 chore: update stage0 2025-08-21 03:44:22 +00:00
Leonardo de Moura
45affb5e09 fix: missing nonlinear / and % in grind cutsat (#10020)
This PR fixes a missing case for PR #10010.
2025-08-21 02:59:52 +00:00
Mac Malone
6a7111ed0e fix: lake: no LEAN_GITHASH for bootstrap (#10012)
This PR changes Lake to not set `LEAN_GITHASH` when in core (i.e.
`bootstrap = true`). This avoids Lake rebuilding modules when the Lake
watchdog is on one build of Lean/Lake and the command line is on a
different one.
2025-08-21 02:44:36 +00:00
Mac Malone
6b4c356c5b chore: lake: fix tests/module (#10013)
This PR fixes an existing breakage in the Lake's module test caused by
Lean's automatic inlining.
2025-08-21 01:28:06 +00:00
Kim Morrison
e3947cbe20 chore: remove bad Option grind annotation (#10000)
This PR removes a `grind` annotation that fired on all `Option.map`s,
causing an avalanche of instantiations.
2025-08-21 01:08:31 +00:00
Cameron Zwarich
d6a43a660f perf: disable reuse when a value's last use is an owned argument (#10017)
The current reuse analysis is greedy in that every function attempts to
reuse a value. However, this means that if the last use is an owned
argument, it will be `inc`'d prior to this last use, in order to prevent
reuse from happening in the callee. In many cases, it makes more sense
to give the callee the chance to reuse it instead. The benchmark results
indicate that this is a much better default.
2025-08-21 00:41:56 +00:00
thorimur
b2330fee2b chore: miscellaneous documentation typos (#10009)
This PR fixes several typos in documentation.
2025-08-20 21:39:03 +00:00
Leonardo de Moura
105879669e chore: remove unnecessary hypothesis in ToInt helper theorems (#10014) 2025-08-20 20:13:15 +00:00
Sebastian Ullrich
679df58329 chore: revert "chore: make USE_LAKE the default" (#10011)
Reverts leanprover/lean4#10003, which broke the merge queue's breakage
check
2025-08-20 19:52:57 +00:00
Leonardo de Moura
d604c16c0e feat: nonlinear / and % support in grind cutsat (#10010)
This PR improves support for nonlinear `/` and `%` in `grind cutsat`.
For example, given `a / b`, if `cutsat` discovers that `b = 2`, it now
propagates that `a / b = b / 2`. This PR is similar to #9996, but for
`/` and `%`. Example:

```lean
example (a b c d : Nat)
    : b > 1 → d = 1 → b ≤ d + 1 → a % b = 1 → a = 2 * c → False := by
  grind
```
2025-08-20 19:31:31 +00:00
Sebastian Ullrich
44891fe0c0 chore: make USE_LAKE the default (#10003) 2025-08-20 19:24:10 +00:00
Kyle Miller
ee699518fa fix: have #eval save the info context (#10008)
This PR fixes a bug in `#eval` where clicking on the evaluated
expression could show errors in the Infoview. This was caused by `#eval`
not saving the temporary environment that is used when elaborating the
expression.
2025-08-20 17:49:09 +00:00
Joachim Breitner
1b213835e6 fix: #print attributes in the right order (#10007)
This PR lets #print print `private` before `protected`, matching the
syntax.
2025-08-20 15:34:55 +00:00
Paul Reichert
22becc78f7 feat: better get-elem tactic for ranges (#9987)
This PR improves the tactic for proving that elements of a `Nat`-based
`PRange` are in-bounds by relying on the `omega` tactic.
2025-08-20 13:42:41 +00:00
Paul Reichert
e083771b81 feat: package factories for order typeclasses based on Ord (#9916)
This PR provides factories that derive order typeclasses in bulk, given
an `Ord` instance. If present, existing instances are preferred over
those derived from `Ord`. It is possible to specify any instance
manually if desired.
2025-08-20 11:14:07 +00:00
Kim Morrison
1a31aa3d2b chore: fewer Nat.bitwise grind attributes for distributivity (#9999)
This PR reduces the number of `Nat.Bitwise` grind annotations we have
the deal with distributivity. The new smaller set encourages `grind` to
rewrite into DNF. The old behaviour just resulted in saturating up to
the instantiation limits.
2025-08-20 05:38:05 +00:00
Leonardo de Moura
86dc07c20d feat: nonlinear monomials in grind cutsat (#9996)
This PR improves support for nonlinear monomials in `grind cutsat`. For
example, given a monomial `a * b`, if `cutsat` discovers that `a = 2`,
it now propagates that `a * b = 2 * b`.
Recall that nonlinear monomials like `a * b` are treated as variables in
`cutsat`, a procedure designed for linear integer arithmetic.

Example:
```lean
example (a : Nat) (ha : a < 8) (b c : Nat) : 2 ≤ b → c = 1 → b ≤ c + 1 → a * b < 8 * b := by
  grind

example (x y z w : Int) : z * x * y = 4 → x = z + w → z = 1 → w = 2 → False := by
  grind
```
2025-08-20 03:16:53 +00:00
Sebastian Ullrich
48365b6052 chore: update stage0 2025-08-19 14:49:12 -07:00
Sebastian Ullrich
d4a5a2c632 fix: local syntax should create private definitions 2025-08-19 14:49:12 -07:00
Sebastian Ullrich
8d34dfe914 chore: CI: make cached Lake primary job (#9401) 2025-08-19 20:43:00 +00:00
Mac Malone
a1cf67edc3 feat: parser alias for visibility (#9974)
This PR registers a parser alias for `Lean.Parser.Command.visibility`.
This avoids having to import `Lean.Parser.Command` in simple command
macros that use visibilities.
2025-08-19 15:20:32 +00:00
Sebastian Ullrich
d0167f7002 chore: show origin module for inaccessible private decls (#9964) 2025-08-19 15:12:09 +00:00
Sebastian Graf
90ef90b462 feat: change extended syntax for mvcgen invariants ... with ... (#9989)
This PR changes the new extended syntax for `mvcgen` to `mvcgen
invariants ... with ...`.
2025-08-19 14:51:19 +00:00
Marc Huisinga
cab46ea3d1 fix: leanOptions in lakefile.toml schema (#9988)
This PR fixes a bug in the `lakefile.toml` schema where it would issue
an invalid validation for multi-layer `leanOptions` .
2025-08-19 14:43:01 +00:00
Paul Reichert
24cafcd65d feat: package factories for order typeclasses (#9797)
This PR provides the means to quickly provide all the order instances
associated with some high-level order structure (preorder, partial
order, linear preorder, linear order). This can be done via the factory
functions `PreorderPackage.ofLE`, `PartialOrderPackage.ofLE`,
`LinearPreorderPackage.ofLE` and `LinearOrderPackage.ofLE`.
2025-08-19 13:43:29 +00:00
nnarek
b75fbe7a40 doc: documentation of p,+ macro should mention that it maps to sepBy1, not sepBy (#9876)
This PR fixes doc issue of p,+ macro,which maps to sepBy1(p, ",") while
doc says that it maps to sepBy(p, ",").

Closes https://github.com/leanprover/lean4/issues/9873
2025-08-19 11:54:47 +00:00
Sebastian Ullrich
cd729660ed chore: allow quoting private names from inside public scope (#9985) 2025-08-19 09:07:48 +00:00
Paul Reichert
f81236185c feat: integrate high-level order typeclasses with BEq and Ord (#9908)
This PR makes `IsPreorder`, `IsPartialOrder`, `IsLinearPreorder` and
`IsLinearOrder` extend `BEq` and `Ord` as appropriate, adds the
`LawfulOrderBEq` and `LawfulOrderOrd` typeclasses relating `BEq` and
`Ord` to `LE`, and adds many lemmas and instances.

Note: This PR contains a refactoring where `Init.Data.Ord` is moved to
`Init.Data.Ord.Basic`. If I added `Init.Data.Ord` simply importing all
submodules, git would not be able to determine that `Init.Data.Ord` was
renamed to `Init.Data.Ord.Basic`. This could lead to unnecessary merge
conflicts in the future. Hence, I chose the name `Init.Data.OrdRoot`
instead of `Init.Data.Ord` temporarily. After this PR, I will rename
this module back to `Init.Data.Ord` in a separate PR.

(This is a copy of #9430: I will not touch that PR because it currently
allows to debug a CI problem and pushing commits might break the
reproducibility.)
2025-08-19 07:54:53 +00:00
Kyle Miller
7fa1a8b114 chore: eliminate uses of intros x y z (#9983)
This PR eliminates uses of `intros x y z` (with arguments) and updates
the `intros` docstring to suggest that `intro x y z` should be used
instead. The `intros` tactic is historical, and can be traced all the
way back to Lean 2, when `intro` could only introduce a single
hypothesis. Since 2020, the `intro` tactic has superceded it. The
`intros` tactic (without arguments) is currently still useful.
2025-08-19 06:09:13 +00:00
Cameron Zwarich
8536fe5aa9 refactor: split handling of normal fvars and join points in toIR (#9981)
This makes the representation of lowered fvar values the IR `Arg` type.
2025-08-19 03:44:15 +00:00
Leonardo de Moura
6b24eb474f fix: variable reordering in grind cutsat (#9980)
This PR fixes a bug in the dynamic variable reordering function used in
`grind cutsat`.

Closes #9948
2025-08-19 02:19:50 +00:00
Kim Morrison
de493d761d feat: upstream definition of Rat from Batteries (#9957)
This PR upstreams the definition of Rat from Batteries, for use in our
planned interval arithmetic tactic.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-08-19 01:58:24 +00:00
Cameron Zwarich
b68f3455d3 refactor: use a separate getter for fvar values in toIR (#9978) 2025-08-19 01:28:15 +00:00
Anne Baanen
f88d35f6c9 chore: add fixed grind tests for Nat and Int ring structure (#9615)
This PR adds two test cases extracted from Mathlib, that `grind` cannot
solve but `omega` can. Originally the multiplication instance came from
`Nat.instSemiring` and `Int.instSemiring`, in minimizing I found that
`Distrib` is already enough.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2025-08-19 01:12:44 +00:00
Cameron Zwarich
89752e2242 fix: support compiling casesOn recursors of subsingleton predicates (#9977)
This PR adds support for compilation of `casesOn` recursors of
subsingleton predicates.

Fixes #9963.
2025-08-19 00:23:24 +00:00
Cameron Zwarich
b8fa6f17ee fix: make lcAny-producing arrow types lower to tobj rather than obj (#9972)
This PR fixes an issue when running Mathlib's `FintypeCat` as code,
where an erased type former is passed to a polymorphic function. We were
lowering the arrow type to`object`, which conflicts with the runtime
representation of an erased value as a tagged scalar.
2025-08-18 22:18:26 +00:00
Henrik Böving
2d4bcf202f chore: even more independent benchmarks (#9970) 2025-08-18 18:36:33 +00:00
Sebastian Graf
1b0d83e7fc fix: remove local Triple notation from SpecLemmas.lean to fix stage2 (#9967)
This PR removes local `Triple` notation from SpecLemmas.lean to work
around a bug that breaks the stage2 build.
2025-08-18 16:41:26 +00:00
Wojciech Rozowski
2d52d44710 feat: fixpoint_induct and partial_correctness lemmas for mutual blocks come in conjunction and projected variants (#9651)
This PR modifies the generation of induction and partial correctness
lemmas for `mutual` blocks defined via `partial_fixpoint`. Additionally,
the generation of lattice-theoretic induction principles of functions
via `mutual` blocks is modified for consistency with `partial_fixpoint`.

The lemmas now come in two variants:
1. A conjunction variant that combines conclusions for all elements of
the mutual block. This is generated only for the first function inside
of the mutual block.
2. Projected variants for each function separately

## Example 1
```lean4
axiom A : Type
axiom B : Type

axiom A.toB : A → B
axiom B.toA : B → A

mutual
noncomputable def f : A := g.toA
partial_fixpoint
noncomputable def g : B := f.toB
partial_fixpoint
end
```

Generated `fixpoint_induct` lemmas:
```lean4
f.fixpoint_induct (motive_1 : A → Prop) (motive_2 : B → Prop) (adm_1 : admissible motive_1)
  (adm_2 : admissible motive_2) (h_1 : ∀ (g : B), motive_2 g → motive_1 g.toA)
  (h_2 : ∀ (f : A), motive_1 f → motive_2 f.toB) : motive_1 f

g.fixpoint_induct (motive_1 : A → Prop) (motive_2 : B → Prop) (adm_1 : admissible motive_1)
  (adm_2 : admissible motive_2) (h_1 : ∀ (g : B), motive_2 g → motive_1 g.toA)
  (h_2 : ∀ (f : A), motive_1 f → motive_2 f.toB) : motive_2 g
```

Mutual (conjunction) variant:
```lean4
f.mutual_fixpoint_induct (motive_1 : A → Prop) (motive_2 : B → Prop) (adm_1 : admissible motive_1) (adm_2 : admissible motive_2)
  (h_1 : ∀ (g : B), motive_2 g → motive_1 g.toA) (h_2 : ∀ (f : A), motive_1 f → motive_2 f.toB) :
  motive_1 f ∧ motive_2 g
```

## Example 2 
```lean4
mutual
  def f (n : Nat) : Option Nat :=
    g (n + 1)
  partial_fixpoint

  def g (n : Nat) : Option Nat :=
    if n = 0 then .none else f (n + 1)
  partial_fixpoint
end
```
Generated `partial_correctness` lemmas (in a projected variant):
```lean4
f.partial_correctness (motive_1 motive_2 : Nat → Nat → Prop)
  (h_1 :
    ∀ (g : Nat → Option Nat),
      (∀ (n r : Nat), g n = some r → motive_2 n r) → ∀ (n r : Nat), g (n + 1) = some r → motive_1 n r)
  (h_2 :
    ∀ (f : Nat → Option Nat),
      (∀ (n r : Nat), f n = some r → motive_1 n r) →
        ∀ (n r : Nat), (if n = 0 then none else f (n + 1)) = some r → motive_2 n r)
  (n r✝ : Nat) : f n = some r✝ → motive_1 n r✝

g.partial_correctness (motive_1 motive_2 : Nat → Nat → Prop)
  (h_1 :
    ∀ (g : Nat → Option Nat),
      (∀ (n r : Nat), g n = some r → motive_2 n r) → ∀ (n r : Nat), g (n + 1) = some r → motive_1 n r)
  (h_2 :
    ∀ (f : Nat → Option Nat),
      (∀ (n r : Nat), f n = some r → motive_1 n r) →
        ∀ (n r : Nat), (if n = 0 then none else f (n + 1)) = some r → motive_2 n r)
  (n r✝ : Nat) : g n = some r✝ → motive_2 n r✝
```

Mutual (conjunction) variant:
```
f.mutual_partial_correctness (motive_1 motive_2 : Nat → Nat → Prop)
  (h_1 :
    ∀ (g : Nat → Option Nat),
      (∀ (n r : Nat), g n = some r → motive_2 n r) → ∀ (n r : Nat), g (n + 1) = some r → motive_1 n r)
  (h_2 :
    ∀ (f : Nat → Option Nat),
      (∀ (n r : Nat), f n = some r → motive_1 n r) →
        ∀ (n r : Nat), (if n = 0 then none else f (n + 1)) = some r → motive_2 n r) :
  (∀ (n r : Nat), f n = some r → motive_1 n r) ∧ ∀ (n r : Nat), g n = some r → motive_2 n r
```
2025-08-18 15:26:30 +00:00
Kyle Miller
af5322c7ef feat: tactic info per intro hypothesis, rfl pattern (#9942)
This PR modifies `intro` to create tactic info localized to each
hypothesis, making it possible to see how `intro` works
variable-by-variable. Additionally:
- The tactic supports `intro rfl` to introduce an equality and
immediately substitute it, like `rintro rfl` (recall: the `rfl` pattern
is like doing `intro h; subst h`). The `rintro` tactic can also now
support `HEq` in `rfl` patterns if `eq_of_heq` applies.
- In `intro (h : t)`, elaboration of `t` is interleaved with unification
with the type of `h`, which prevents default instances from causing
unification to fail.
- Tactics that change types of hypotheses (including `intro (h : t)`,
`delta`, `dsimp`) now update the local instance cache.

In `intro x y z`, tactic info ranges are `intro x`, `y`, and `z`. The
reason for including `intro` with `x` is to make sure the info range is
"monotonic" while adding the first argument to `intro`.
2025-08-18 13:55:06 +00:00
Kyle Miller
3af9cc3f6f doc: extend docstrings for let/have tactics (#9956)
This PR adds additional information to the `let` and `have` tactic
docstrings about opaqueness, when to use each, and associated tactics.
2025-08-18 13:48:08 +00:00
Rob23oba
688b930bad feat: tree map lemmas for filter, map, filterMap (#9632)
This PR adds lemmas for the `TreeMap` operations `filter`, `map` and
`filterMap`. These lemmas existed already for hash maps and are simply
ported over from there.
2025-08-18 12:13:52 +00:00
Tom Levy
04f9baf4d3 fix: remove dependency on LawfulBEq from List.lookup lemmas (#9949)
This PR allows most of the `List.lookup` lemmas to be used when
`LawfulBEq α` is not available.

`LawfulBEq` is very strong. Most of the lemmas don't actually require it
-- some only require `ReflBEq`, and only `List.lookup_eq_some_iff`
actually requires `LawfulBEq`.
2025-08-18 10:16:30 +00:00
Johannes Tantow
19301f83eb feat: verify toArray for hash maps (#9685)
This PR verifies `toArray` and related functions for hashmaps.
2025-08-18 09:39:44 +00:00
Markus Himmel
2e6c1a74e5 chore: move String.Pos operations out of Prelude (#9845)
This PR moves arithmetic of `String.Pos` out of the prelude.

Other `String` declarations are part of the prelude because they are
generated by macros, but this does not seem to be the case for these.
2025-08-18 09:23:02 +00:00
Henrik Böving
e4be2b2cad chore: make perf tests more independent of external factors (#9960) 2025-08-18 08:45:23 +00:00
Henrik Böving
48a8dd4a56 fix: print mathlib toolchain URL properly (#9962)
This PR makes lake print the error message it intended for when fetching
the mathlib toolchain
fails.
2025-08-18 08:11:50 +00:00
Sebastian Ullrich
a805e7e12c chore: avoid turning accesses to private decs from public signatures into auto implicits (#9961) 2025-08-18 08:01:12 +00:00
Jason Yuen
3c702f38ee chore: add a missing backtick (#9959)
This PR adds a backtick and fixes the docs for `section`.
2025-08-18 07:48:05 +00:00
Lean stage0 autoupdater
fe90da5a8d chore: update stage0 2025-08-18 05:25:50 +00:00
Kyle Miller
fd926cc44e feat: clean up type annotations when elaborating declaration bodies (#9674)
This PR cleans up `optParam`/`autoParam`/etc. annotations before
elaborating definition bodies, theorem bodies, `fun` bodies, and `let`
function bodies. Both `variable`s and binders in declaration headers are
supported.

There are no changes to `inductive`/`structure`/`axiom`/etc. processing,
just `def`/`theorem`/`example`/`instance`.
2025-08-18 04:43:20 +00:00
Leonardo de Moura
f5bab3c8ba feat: grind cutsat equations in solved form (#9958)
This PR ensures that equations in the `grind cutsat` module are
maintained in solved form. That is, given an equation `a*x + p = 0` used
to eliminate `x`, the linear polynomial `p` must not contain other
eliminated variables. Before this PR, equations were maintained in
triangular form. We are going to use the solved form to linearize
nonlinear terms.
2025-08-18 01:34:37 +00:00
Leonardo de Moura
973885d087 chore: remove NullCert leftovers (#9955) 2025-08-18 00:07:23 +00:00
Lean stage0 autoupdater
1aa59f5579 chore: update stage0 2025-08-17 23:48:38 +00:00
Leonardo de Moura
a4496a4a6b chore: remove grind +ringNull option (#9954)
This PR removes the option `grind +ringNull`. It provided an alternative
proof term construction for the `grind ring` module, but it was less
effective than the default proof construction mode and had effectively
become dead code.
This PR also optimizes semiring normalization proof terms using the
infrastructure added in #9946.
**Remark:** After updating stage0, we can remove several background
theorems from the `Init/Grind` folder.
2025-08-17 23:04:59 +00:00
Lean stage0 autoupdater
84fecdc042 chore: update stage0 2025-08-17 16:58:21 +00:00
Sebastian Ullrich
81a4b0ca99 chore: fix failing mk*Sorry in bootstrapping contexts (#9950) 2025-08-17 16:14:53 +00:00
Leonardo de Moura
6f7dba167a feat: trim grind linarith proof context (#9947)
This PR optimizes the proof terms produced by `grind linarith`. It is
similar to #9945, but for the `linarith` module in `grind`.
It removes unused entries from the context objects when generating the
final proof, significantly reducing the amount of junk in the resulting
terms.
2025-08-17 05:32:40 +00:00
Leonardo de Moura
0cc0de9e51 feat: trim grind ring proof context (#9946)
This PR optimizes the proof terms produced by `grind ring`. It is
similar to #9945, but for the ring module in `grind`.
It removes unused entries from the context objects when generating the
final proof, significantly reducing the amount of junk in the resulting
terms. Example:
```lean
/--
trace: [grind.debug.proof] fun h h_1 h_2 h_3 =>
      Classical.byContradiction fun h_4 =>
        let ctx := RArray.branch 1 (RArray.leaf x) (RArray.leaf x⁻¹);
        let e_1 := (Expr.var 0).mul (Expr.var 1);
        let e_2 := Expr.num 0;
        let e_3 := Expr.num 1;
        let e_4 := (Expr.var 0).pow 2;
        let m_1 := Mon.mult (Power.mk 1 1) Mon.unit;
        let m_2 := Mon.mult (Power.mk 0 1) Mon.unit;
        let p_1 := Poly.num (-1);
        let p_2 := Poly.add (-1) (Mon.mult (Power.mk 0 1) Mon.unit) (Poly.num 0);
        let p_3 := Poly.add 1 (Mon.mult (Power.mk 0 2) Mon.unit) (Poly.num 0);
        let p_4 := Poly.add 1 (Mon.mult (Power.mk 0 1) (Mon.mult (Power.mk 1 1) Mon.unit)) (Poly.num (-1));
        let p_5 := Poly.add 1 (Mon.mult (Power.mk 0 1) Mon.unit) (Poly.num 0);
        one_eq_zero_unsat ctx p_1 (eagerReduce (Eq.refl true))
          (Stepwise.simp ctx 1 p_4 (-1) m_1 p_5 p_1 (eagerReduce (Eq.refl true))
            (Stepwise.core ctx e_1 e_3 p_4 (eagerReduce (Eq.refl true)) (diseq0_to_eq x h_4))
            (Stepwise.mul ctx p_2 (-1) p_5 (eagerReduce (Eq.refl true))
              (Stepwise.superpose ctx 1 m_2 p_4 (-1) m_1 p_3 p_2 (eagerReduce (Eq.refl true))
                (Stepwise.core ctx e_1 e_3 p_4 (eagerReduce (Eq.refl true)) (diseq0_to_eq x h_4))
                (Stepwise.core ctx e_4 e_2 p_3 (eagerReduce (Eq.refl true)) h))))
-/
#guard_msgs in -- Context should contains only `x` and its inverse.
set_option trace.grind.debug.proof true in
set_option pp.structureInstances false in
open Lean Grind CommRing in
example [Field α] (x y z w : α) :
   x^2 = 0 → y^2 = 0 → z^3 = 0 → w^2 = 0 → x = 0 := by
  grind
```
2025-08-17 04:44:47 +00:00
Leonardo de Moura
010468699f feat: trim grind cutsat proof context (#9945)
This PR optimizes the proof terms produced by `grind cutsat`. It removes
unused entries from the context objects when generating the final proof,
significantly reducing the amount of junk in the resulting terms.
Example:
```lean
/--
trace: [grind.debug.proof] fun h h_1 h_2 h_3 h_4 h_5 h_6 h_7 h_8 =>
      let ctx := RArray.leaf (f 2);
      let p_1 := Poly.add 1 0 (Poly.num 0);
      let p_2 := Poly.add (-1) 0 (Poly.num 1);
      let p_3 := Poly.num 1;
      le_unsat ctx p_3 (eagerReduce (Eq.refl true)) (le_combine ctx p_2 p_1 p_3 (eagerReduce (Eq.refl true)) h_8 h_1)
-/
#guard_msgs in -- Context should contain only `f 2`
open Lean Int Linear in
set_option trace.grind.debug.proof true in
example (f : Nat → Int) :
    f 1 <= 0 → f 2 <= 0 → f 3 <= 0 → f 4 <= 0 → f 5 <= 0 → 
    f 6 <= 0 → f 7 <= 0 → f 8 <= 0 → -1 * f 2 + 1 <= 0 → False := by
  grind
```
2025-08-17 02:53:19 +00:00
Sebastian Ullrich
4a6004b8fa perf: use Lean.realizeValue in getFunInfo (#9810) 2025-08-16 15:02:29 +00:00
Sebastian Graf
c6df4a4a89 fix: delegate to exact in mvcgen using invariants to avoid MVar mishaps (#9939)
This PR expands `mvcgen using invariants | $n => $t` to `mvcgen; case
inv<$n> => exact $t` to avoid MVar instantiation mishaps observable in
the test case for #9581.

Closes #9581.
2025-08-16 09:40:42 +00:00
Sebastian Graf
ee4cbbeb14 fix: remove duplicate mpure_intro tactic definition (#9938)
This PR removes a duplicate `mpure_intro` tactic definition.
2025-08-16 09:19:07 +00:00
Cameron Zwarich
0e968f010a chore: fix indentation (#9936) 2025-08-16 05:30:36 +00:00
Lean stage0 autoupdater
b0d42e6ac9 chore: update stage0 2025-08-16 02:17:49 +00:00
Sebastian Graf
df898a5c87 chore: make test mvcgenUsingWith deterministic (#9933) 2025-08-15 17:57:55 +00:00
Sebastian Graf
bdc9124228 feat: implement Std.Do.Triple.mp (#9931)
This PR implements `Std.Do.Triple.mp`, enabling users to compose two
specifications for the same program.
2025-08-15 17:44:15 +00:00
Leonardo de Moura
aad98fe749 fix: revert Nat.sub embedding into Int (#9930)
This PR reverts the way `grind cutsat` embeds `Nat.sub` into `Int`. It
fixes a regression reported by David Renshaw on Zulip.


https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/v4.2E23.2E0/near/534646557
2025-08-15 16:06:31 +00:00
Sebastian Ullrich
506d16a603 chore: complete riscv_ast benchmark (#9928) 2025-08-15 14:39:25 +00:00
Sebastian Graf
9e1d97c261 feat: extended using invariants and with syntax for mvcgen (#9927)
This PR implements extended `induction`-inspired syntax for `mvcgen`,
allowing optional `using invariants` and `with` sections.

```lean
  mvcgen
  using invariants
  | 1 => Invariant.withEarlyReturn
      (onReturn := fun ret seen => ⌜ret = false ∧ ¬l.Nodup⌝)
      (onContinue := fun traversalState seen =>
        ⌜(∀ x, x ∈ seen ↔ x ∈ traversalState.prefix) ∧ traversalState.prefix.Nodup⌝)
  with mleave -- mleave is a no-op here, but we are just testing the grammar
  | vc1 => grind
  | vc2 => grind
  | vc3 => grind
  | vc4 => grind
  | vc5 => grind
```
2025-08-15 12:25:01 +00:00
Lean stage0 autoupdater
4c562fc1a3 chore: update stage0 2025-08-15 12:21:02 +00:00
Sebastian Ullrich
415a58f9fb chore: warn on [expose] on private definition (#9917) 2025-08-15 11:31:33 +00:00
Sebastian Graf
85ba133df0 fix: better ProofMode/Delab (#9926)
This PR guards the `Std.Tactic.Do.MGoalEntails` delaborator by a check
ensuring that there are at least 3 arguments present, preventing
potential panics.
2025-08-15 08:36:34 +00:00
Kim Morrison
3ee8d35031 chore: begin dev cycle for v4.24.0 (#9925) 2025-08-15 08:02:04 +00:00
Sebastian Graf
45fbe4a73d fix: documentated examples for PostCond, move around tests (#9924)
This PR fixes examples in the documentation for `PostCond`.
2025-08-15 07:59:33 +00:00
Sofia Rodrigues
287b173844 fix: background function and forIn (#9560)
This PR fixes the `forIn` function, that previously caused the resulting
Promise to be dropped without a value when an exception was thrown
inside of it. It also corrects the parameter order of the `background`
function.
2025-08-15 02:39:57 +00:00
Cameron Zwarich
05c1ba291d fix: erase dependencies on let-bound fvars in internalizeCode (#9922)
This PR changes `internalizeCode` to replace all substitutions with
non-param-bound fvars in `Expr`s (which are all types) with `lcAny`,
preserving the invariant that there are no such dependencies. The
violation of this invariant across files caused test failures in a
pending PR, but it is difficult to write a direct test for it. In the
future, we should probably change the LCNF checker to detect this.

This change also speeds up some compilation-heavy benchmarks much more
than I would've expected, which is a pleasant surprise. This indicates
we might get more speedups from reducing the amount of type information
we preserve in LCNF.
2025-08-15 01:52:47 +00:00
Sebastian Ullrich
15a065d14d fix: panic in delabPRange (#9920)
This PR fixes a panic in the delaborator for `Std.PRange`. It also
modifies the delaborators for both `Std.Range` and `Std.PRange` to not
use `let_expr`, which cleans up annotations and metadata, since
delaborators must follow the structures of expressions. It adds support
for `pp.notation` and `pp.explicit` options. It also adds tests for
these delaborators.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
Co-authored-by: Kyle Miller <kmill31415@gmail.com>
2025-08-15 01:50:23 +00:00
Kim Morrison
35a753dc98 fix: panic in ProofMode/Delab (#9923)
This PR adds a guard for a delaborator that is causing panics in
doc-gen4. This is a band-aid solution for now, and @sgraf812 will take a
look when they're back from leave.
2025-08-15 01:01:12 +00:00
Leonardo de Moura
06d05d1f46 feat: missing grind annotations (#9921)
This PR marks `List.drop_length` and `List.take_length` with `[grind
=]`.
2025-08-14 22:47:42 +00:00
Leonardo de Moura
fe7e0859d5 fix: div/norm normalization assumptions in grind (#9919)
This PR ensures `grind cutsat` does not rely on div/mod terms to have
been normalized. The `grind` preprocessor has normalizers for them, but
sometimes they cannot be applied because of type dependencies.

Closes #9907
2025-08-14 22:28:25 +00:00
Lean stage0 autoupdater
76971a88ff chore: update stage0 2025-08-14 16:21:50 +00:00
Sebastian Ullrich
ddfeca1b1b fix: do not allow access to private primitives in public scope (#9890)
This PR addresses a missing check in the module system where private
names that remain in the public environment map for technical reasons
(e.g. inductive constructors generated by the kernel and relied on by
the code generator) accidentally were accessible in the public scope.
2025-08-14 15:34:54 +00:00
Sebastian Ullrich
0ab29c7420 fix: do not show progress bar for checking/compiling helper decls (#9786)
This PR ensures we only show progress bars for computations directly
relevant to users

---------

Co-authored-by: Marc Huisinga <mhuisi@protonmail.com>
2025-08-14 14:46:38 +00:00
Sebastian Ullrich
1ba1424ac3 perf: local metaExt (#9822) 2025-08-14 14:26:12 +00:00
Kim Morrison
c8dae31ba5 feat: review of grind annotations for Option (#9863)
This PR reviews `grind` annotations for `Option`, preferring to use
`@[grind =]` instead of `@[grind]` (and fixing a few problems revealed
by this), and making sure `@[grind =]` theorems are "fully applied".
2025-08-14 11:08:05 +00:00
Lean stage0 autoupdater
49cd03bc29 chore: update stage0 2025-08-14 10:47:52 +00:00
Sebastian Ullrich
6e1451dbd8 fix: duplicate private instance name avoidance under the module system (#9914) 2025-08-14 10:03:41 +00:00
Joachim Breitner
6b3aed29b9 feat: unused simp argument linter to explain false positives around (#9912)
This PR lets the unused simp argument linter explain that the given hint
of removing `←` arguments may be too strong, and that replacing them
with `-` arguments can be needed. Fixes #9909.
2025-08-14 09:54:21 +00:00
Sebastian Graf
34fe6b460c chore: fix docs of mspec (#9913)
Just docs.
2025-08-14 09:49:11 +00:00
Joachim Breitner
62f9de5edf fix: fun_induction to instantiateMVars (#9877)
This PR makes `fun_induction foo` instantiate the MVars in the goal
before searching for suitable applications of foo. Fixes #9844.
2025-08-14 09:42:26 +00:00
Sebastian Graf
0c39a50337 feat: Rename Std.List.Zipper to List.Cursor (#9911)
This PR renames `Std.List.Zipper` to `List.Cursor`, with slight changes
to the implementation (no `reverse`) and use in loop specification
lemmas.
2025-08-14 09:17:54 +00:00
Sebastian Ullrich
535435955b chore: remove broken Nix build (#9910) 2025-08-14 08:31:39 +00:00
Marc Huisinga
93e35dc3da feat: add lakefile.toml json schema (#9871)
This PR adds a JSON schema for `lakefile.toml`. Importantly, this schema
is *not* intended for validating `lakefile.toml`, but is instead
optimized for auto-completion and hovers using the [Even Better
TOML](https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml)
VS Code extension.

Once merged, I will attempt to contribute a link to this schema to the
[JSON Schema store](https://github.com/SchemaStore/schemastore). When
that is done, we can integrate the Lean 4 VS Code extension with Even
Better TOML, providing us with language server support in
`lakefile.toml`.

The schema contributed by this PR has the following known deficiencies:
- Superfluous properties do not produce an error.
- The structure of complicated structures (e.g. path or version
patterns) is deliberately not accurately reflected in the schema. Even
Better TOML doesn't seem to handle these structures well in
auto-completion.
- Due to the lack of an accurate declarative spec of the lakefile.toml
format and several deviations from the format to provide better
auto-completions, this schema will have to be kept in sync manually with
the code in Lake, at least for now.
2025-08-14 07:24:40 +00:00
Leonardo de Moura
05e8c856fa fix: reset decision stack in grind linarith (#9904)
This PR ensures the decision stack is reset after an assignment is found
in `grind linarith`.

Closes #9897
2025-08-14 02:53:01 +00:00
Leonardo de Moura
2e991d3b10 fix: panic at invalid pattern in grind (#9902)
This PR fixes a panic when an invalid pattern is provided to `grind`.

closes #9899
2025-08-14 02:25:37 +00:00
Kim Morrison
f60f946e11 chore: missing doc-strings for grind typeclasses (#9900)
This PR adds some missing doc-strings for grind typeclasses.
2025-08-14 02:15:13 +00:00
Leonardo de Moura
253c10c398 fix: normalize Nat.cast and Int.cast of numerals in grind (#9901)
This PR ensures that `Nat.cast` and `Int.cast` of numerals are
normalized by `grind`.
It also adds a `simp` flag for controlling how bitvector literals are
represented. By default, the bitvector simprocs use `BitVec.ofNat`. This
representation is problematic for the `grind ring` and `grind cutsat`
modules. The new flag allows the use of `OfNat.ofNat` and `Neg.neg` to
represent literals, consistent with how they are represented for other
commutative rings.

Closes #9321
2025-08-14 02:04:55 +00:00
Leonardo de Moura
f8c743e37d feat: consider all singleton patterns in local forall expressions in grind (#9896)
This PR improves the heuristic used to select patterns for local
`forall` expressions occurring in the goal being solved by `grind`. It
now considers all singleton patterns in addition to the selected
multi-patterns. Example:
```lean
example (p : Nat → Prop) (h₁ : x < n) (h₂ : ¬ p x) : ∃ i, i < n ∧ ¬ p i := by
  grind
```
2025-08-13 18:45:29 +00:00
Sebastian Graf
f80274be6b fix: Rename M.by_wp lemmas according to naming convention (#9894)
This PR renames `M.by_wp` lemmas to `M.of_wp_*`.
2025-08-13 16:56:07 +00:00
Sebastian Graf
d93cdde938 feat: Aggressively eta expand before applying a spec in mvcgen (#9888)
This PR makes `mvcgen` aggressively eta-expand before trying to apply a
spec. This ensures that `mspec` will be able to frame hypotheses
involving uninstantiated loop invariants in goals for the inductive step
of a loop instead of losing them in a destructive world update.
2025-08-13 15:53:48 +00:00
Sebastian Ullrich
640337e0a0 chore: error on [macro_inline] without [expose] (#9891) 2025-08-13 10:57:48 +00:00
Sebastian Graf
55f9dfad7d feat: More grind annotations for List.range' (#9766)
This PR moves `List.range'_elim` to `List.eq_of_range'_eq_append_cons`
and adds a couple of `grind` annotations for `List.range'`. This will
make it more convenient to work with proof obligations produced by
`mvcgen`.
2025-08-13 09:27:48 +00:00
Sebastian Graf
b9a8dd8f0d feat: simp and grind rules for ExceptConds (#9889)
This PR adds `simp` and `grind` rules for
`ExceptCond.{const,true,false}`.
2025-08-13 08:11:22 +00:00
Sebastian Graf
f973e855e0 feat: Make mrefine reduce applications of SPred.and (#9887)
This PR makes `mrefine` reduce applications of `SPred.and`.
2025-08-13 07:50:17 +00:00
Kim Morrison
93e0ebf25c feat: make Lean.Grind.Preorder a mixin (#9885)
This PR is initially motivated by noticing `Lean.Grind.Preorder.toLE`
appearing in long Mathlib typeclass searches; this change will prevent
these searches. These changes are also helpful preparation for
potentially dropping the custom `Lean.Grind.*` typeclasses, and unifying
with the new typeclasses introduced in #9729.
2025-08-13 05:02:39 +00:00
Leonardo de Moura
21fa5d10f4 chore: move tests that are working (#9884) 2025-08-13 00:46:54 +00:00
Leonardo de Moura
0046b8b4bb feat: warning based on patterns for grind (#9883)
This PR refines the warning message for redundant `grind` arguments. It
is not based on the actual inferred pattern instead provided kind.
2025-08-13 00:42:09 +00:00
Cameron Zwarich
639baaaa03 refactor: adopt do notation (#9882) 2025-08-12 22:12:59 +00:00
Cameron Zwarich
6f7ca5e5d3 refactor: take more advantage of anonymous constructors (#9881) 2025-08-12 21:19:40 +00:00
Lean stage0 autoupdater
5210cdf43f chore: update stage0 2025-08-12 21:07:52 +00:00
Leonardo de Moura
072e3e89e3 fix: local forall activation in grind (#9880)
This PR ensures a local forall is activated at most once per pattern in
`grind`.
2025-08-12 19:49:05 +00:00
Leonardo de Moura
6e18afac8c feat: kernel hint for proof-by-reflection (#9865)
This PR adds improved support for proof-by-reflection to the kernel type
checker. It addresses the performance issue exposed by #9854. With this
PR, whenever the kernel type-checks an argument of the form `eagerReduce
_`, it enters "eager-reduction" mode. In this mode, the kernel is more
eager to reduce terms. The new `eagerReduce _` hint is often used to
wrap `Eq.refl true`. The new hint should not negatively impact any
existing Lean package.

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2025-08-12 19:24:47 +00:00
Sebastian Ullrich
a9145d3312 fix: do not block in snapshot reporter when creating ilean update (#9784)
This PR ensures the editor progress bar better reflects the actual
progress of parallel elaboration.
2025-08-12 16:08:59 +00:00
Leonardo de Moura
5801dff9ea chore: Eq.refl (#9878) 2025-08-12 15:34:29 +00:00
Leonardo de Moura
54dce214d1 fix: nondeterminism in grind ring (#9867)
This PR fixes a nondeterministic behavior in `grind ring`.

Closes #9825
2025-08-12 15:27:39 +00:00
Sebastian Graf
e5bb854748 feat: Add delaborator for Std.PRange notation (#9850)
This PR add a delaborator for `Std.PRange` notation.
2025-08-12 08:51:27 +00:00
Cameron Zwarich
e9df183e87 perf: avoid ref count increments for borrowed array accesses (#9866) 2025-08-12 05:27:35 +00:00
Lean stage0 autoupdater
954957c456 chore: update stage0 2025-08-12 05:06:58 +00:00
Cameron Zwarich
dfc8e38a21 feat: add array access functions that return a borrowed result (#9864)
This PR adds new variants of `Array.getInternal` and
`Array.get!Internal` that return their argument borrowed, i.e. without a
reference count increment. These are intended for use by the compiler in
cases where it can determine that the array will continue to hold a
valid reference to the element for the returned value's lifetime.

In the future, this will likely be replaced by a return value borrow
annotation, in which case the special variant of the functions could be
removed, with the compiler inserting an extra `inc` in the non-borrow
cases.
2025-08-12 04:25:14 +00:00
Cameron Zwarich
bf348ae60f refactor: use more helper functions (#9862) 2025-08-11 23:56:50 +00:00
Leonardo de Moura
4df4968538 fix: grind theorem activation (#9860)
This PR fixes E-matching theorem activation in `grind`.

Fixes #9856
2025-08-11 22:59:35 +00:00
Cameron Zwarich
ca05569cd5 refactor: rename VarProjInfo to DerivedValInfo (#9859)
We want to use this for non-projections in the near future.
2025-08-11 22:02:28 +00:00
Leonardo de Moura
a157abbbc9 fix: E-matching patterns containing ground universe polymorphic patterns in grind (#9857)
This PR ensures `grind` can E-match patterns containing universe
polymorphic ground sub-patterns. For example, given
```
set_option pp.universes true in
attribute [grind?] Id.run_pure
```
the pattern
```
Id.run_pure.{u_1}: [@Id.run.{u_1} #1 (@pure.{u_1, u_1} `[Id.{u_1}] `[Applicative.toPure.{u_1, u_1}] _ #0)]
```
contains two nested universe polymorphic ground patterns
- `Id.{u_1}`
- `Applicative.toPure.{u_1, u_1}`

This kind of pattern is not common, but it occurs in core.
2025-08-11 21:12:57 +00:00
Leonardo de Moura
5abf4bb651 fix: additional numeral normalization in grind (#9853)
This PR adds `Nat` and `Int` numeral normalizers in `grind`.

closes #9828
2025-08-11 19:13:17 +00:00
Leonardo de Moura
7ea711e043 fix: remove inShareCommon filter used in grind (#9852)
This PR removes the `inShareCommon` quick filter used in `grind`
preprocessing steps. `shareCommon` is no longer used only for fully
preprocessed terms.

closes #9830
2025-08-11 18:24:13 +00:00
Sebastian Graf
b853166575 feat: Deterministic case labels in mvcgen (#9843)
This PR makes `mvcgen` produce deterministic case labels for the
generated VCs. Invariants will be named `inv<n>` and every other VC will
be named `vc<n>.*`, where the `*` part serves as a loose indication of
provenance.
2025-08-11 14:57:59 +00:00
Paul Reichert
0725349bbd feat: high-level order typeclasses (#9729)
This PR introduces a canonical way to endow a type with an order
structure. The basic operations (`LE`, `LT`, `Min`, `Max`, and in later
PRs `BEq`, `Ord`, ...) and any higher-level property (a preorder, a
partial order, a linear order etc.) are then put in relation to `LE` as
necessary. The PR provides `IsLinearOrder` instances for many core types
and updates the signatures of some lemmas.

**BREAKING CHANGES:**

* The requirements of the `lt_of_le_of_lt`/`le_trans` lemmas for
`Vector`, `List` and `Array` are simplified. They now require an
`IsLinearOrder` instance. The new requirements are logically equivalent
to the old ones, but the `IsLinearOrder` instance is not automatically
inferred from the smaller typeclasses.
* Hypotheses of type `Std.Total (¬ · < · : α → α → Prop)` are replaced
with the equivalent class `Std.Asymm (· < · : α → α → Prop)`. Breakage
should be limited because there is now an instance that derives the
latter from the former.
* In `Init.Data.List.MinMax`, multiple theorem signatures are modified,
replacing explicit parameters for antisymmetry, totality, `min_ex_or`
etc. with corresponding instance parameters.
2025-08-11 14:55:17 +00:00
Sebastian Graf
264e451d3c feat: Add @[spec] lemmas for forIn at Std.PRange (#9848)
This PR adds `@[spec]` lemmas for `forIn` and `forIn'` at `Std.PRange`.
2025-08-11 14:34:34 +00:00
Cameron Zwarich
5b5bb5174b fix: check for recursive decls before instance proj inlining (#9847)
This PR adds a check for reursive decls in this bespoke inlining path,
which fixes a regression from the old compiler.

Fixes #9624.
2025-08-11 13:50:26 +00:00
Sofia Rodrigues
14120a519c fix: replace 'D' with 'd' for day representation in long date format (#9799)
This PR fixes the #9410 issue.
2025-08-11 13:17:34 +00:00
Sebastian Graf
2875e8f277 chore: Add Nodup and Fresh tests to doLogicTests.lean (#9837)
Two test cases that will be added to the reference manual
2025-08-11 09:12:38 +00:00
Sebastian Graf
9a0c1ab2d0 feat: Simpler first-order implementation for pure SPreds (#9841)
This PR migrates the ⌜p⌝ notation for embedding pure p : Prop into SPred
σs to expand into a simple, first-order expression SPred.pure p that can
be supported by e-matching in grind.

Doing so deprives ⌜p⌝ notation of its idiom-bracket-like support for
#selector and ‹Nat›ₛ syntax which is thus removed.
2025-08-11 08:32:16 +00:00
Paul Reichert
f15d531acb refactor: reduce omega's dependency on fvar IDs (#9723)
This PR replaces some `HashSet Expr`-typed collections of facts in
`omega`'s implementation with plain lists. This change makes some
`omega` calls faster, some slower, but the advantage is that `omega`'s
performance is more independent the state of the name generator that
produces fvar IDs.

I've created this PR for discussion and am happy to hear opinions on
whether this should be merged or not. A good reason *not* to merge is
that it causes regressions in some places and `grind` is expected to
supersede `omega` either way. A good reason to merge is that `omega` is
used all over the place and its flaky performance increases the noise in
future benchmarks.
2025-08-11 07:17:24 +00:00
Sebastian Graf
e0fcaf5e7d chore: Naming in Invariant.withEarlyReturn (#9835)
Just a small renaming leftover.
2025-08-11 06:43:30 +00:00
Sebastian Graf
1b78d8f0a3 fix: Rewriting in mvcgen when there are excess arguments to wp (#9834)
This PR fixes a bug in `mvcgen` triggered by excess state arguments to
the `wp` application, a situation which arises when working with
`StateT` primitives.
2025-08-11 06:42:08 +00:00
Sebastian Graf
66772d77fc fix: Work around a DefEq bug in mspec involving delayed assignments (#9833)
This PR works around a DefEq bug in `mspec` involving delayed
assignments.
2025-08-11 06:40:19 +00:00
Sebastian Graf
d64637e8c7 fix: Add simp lemmas SPred.entails_<n> to replace SPred.entails_cons (#9832)
This PR adds simp lemmas `SPred.entails_<n>` to replace
`SPred.entails_cons` which was disfunctional as a simp lemma due to
#8074.
2025-08-11 06:38:33 +00:00
Sebastian Graf
02fa9641fd feat: Add delaborator for Std.Range (#9831)
This PR adds a delaborator for `Std.Range` notation.
2025-08-11 06:36:26 +00:00
Cameron Zwarich
4506173a27 fix: support overapplication of Quot.lift in the compiler (#9827)
This PR changes the lowering of `Quot.lcInv` (the compiler-internal form
of `Quot.lift`) in `toMono` to support overapplication.

Fixes #9806.
2025-08-11 01:51:54 +00:00
Kyle Miller
20eea7372f feat: make delta deriving more robust and handle binders (#9800)
This PR improves the delta deriving handler, giving it the ability to
process definitions with binders, as well as the ability to recursively
unfold definitions. Furthermore, delta deriving now tries all explicit
non-out-param arguments to a class, and it can handle "mixin" instance
arguments. The `deriving` syntax has been changed to accept general
terms, which makes it possible to derive specific instances with for
example `deriving OfNat _ 1` or `deriving Module R`. The class is
allowed to be a pi type, to add additional hypotheses; here is a Mathlib
example:
```lean
def Sym (α : Type*) (n : ℕ) :=
  { s : Multiset α // Multiset.card s = n }
deriving [DecidableEq α] → DecidableEq _
```
This underscore stands for where `Sym α n` may be inserted, which is
necessary when `→` is used. The `deriving instance` command can refer to
scoped variables when delta deriving as well. Breaking change: the
derived instance's name uses the `instance` command's name generator,
and the new instance is added to the current namespace.

This closes
[mathlib4#380](https://github.com/leanprover-community/mathlib4/issues/380).
2025-08-10 21:21:54 +00:00
Mac Malone
79f6bb6f54 refactor: lake: reorganize tests/module (#9824)
This PR reorganizes the directory structure of Lake's module test and
renames some of the files to be more descriptive.

Originally, this was meant to be combined with a fix, but that fix
appears to be incorrect, so this is just a refactor.
2025-08-10 19:16:55 +00:00
Kyle Miller
fc076c5acc fix: get DecidableEq deriving handler to work for enumerations in higher universes (#9818)
This PR fixes a bug where the `DecidableEq` deriving handler did not
take universe levels into account for enumerations (inductive types
whose constructors all have no fields). Closes #9541.
2025-08-10 16:29:02 +00:00
Henrik Böving
44d3cfb3dc chore: stabilize benchmark output (#9820) 2025-08-10 10:53:38 +00:00
Sebastian Ullrich
0985326b2e chore: remove unnecessary withoutExporting use (#9821) 2025-08-10 10:20:31 +00:00
Kyle Miller
cbeef963a9 fix: have unsafe term produce an opaqueDecl (#9819)
This PR makes the `unsafe t` term create an auxiliary opaque
declaration, rather than an auxiliary definition with opaque
reducibility hints.
2025-08-10 09:30:55 +00:00
Cameron Zwarich
544f9912b7 chore: add separate profiling entries for base, mono, and IR phases (#9817) 2025-08-10 05:00:49 +00:00
Cameron Zwarich
361ca788a7 refactor: split the LCNF pass list into separate base/mono lists (#9816)
This will make it easier to run the two phases in parallel.
2025-08-10 04:23:19 +00:00
Leonardo de Moura
68a249d23d perf: normalizeLevels in grind (#9814)
This PR skips the `normalizeLevels` preprocessing step in `grind` when
it is not needed.
2025-08-10 00:51:20 +00:00
Leonardo de Moura
95c8f1f866 fix: unfoldReducible in grind (#9813)
This PR fixes an unexpected bound variable panic in `unfoldReducible`
used in `grind`.
2025-08-10 00:02:05 +00:00
Leonardo de Moura
fa17ea2715 chore: include generation in grind.internalize trace message (#9812) 2025-08-09 23:48:43 +00:00
Sebastian Ullrich
c970c74d66 feat: introduce Lean.realizeValue for sharing computation results between compatible environment branches (#9798)
This PR introduces `Lean.realizeValue`, a new metaprogramming API for
parallelism-aware caching of `MetaM` computations
2025-08-09 17:19:29 +00:00
Leonardo de Moura
479da83f57 feat: grind annotation analyzer (#9809)
This PR adds a script for analyzing `grind` E-matching annotations. The
script is useful for detecting matching loops. We plan to add
user-facing commands for running the script in the future.
2025-08-09 17:14:57 +00:00
Yaël Dillies
feca9e8103 fix: allow trailing comma in the arg list of simp?, dsimp?, simpa, etc (#9804)
This PR allows trailing comma in the argument list of `simp?`, `dsimp?`,
`simpa`, etc... Previously, it was only allowed in the non `?` variants
of `simp`, `dsimp`, `simp_all`.

Closes #7383.
2025-08-09 16:37:30 +00:00
Leonardo de Moura
a041ffa702 chore: remove leftover (#9808) 2025-08-09 15:58:50 +00:00
Sebastian Graf
5eafc080e1 feat: Simplify Std.List.Zipper.pref using mleave (#9807)
This PR adds `Std.List.Zipper.pref` to the simp set of `mleave`.
2025-08-09 15:57:47 +00:00
Sebastian Graf
8558b2d278 feat: Improved API for invariants and postconditions (#9805)
This PR improves the API for invariants and postconditions and as such
introduces a few breaking changes to the existing pre-release API around
`Std.Do`. It also adds Markus Himmel's `pairsSumToZero` example as a
test case.
2025-08-09 14:42:37 +00:00
Cameron Zwarich
756f837f82 perf: reduce redundant inc/dec using "implied borrows" from projections and liveness (#9801)
This PR changes the IR RC pass to take "implied borrows" from
projections into account. If a projected value's lifetime is contained
in that of its parent (or any projection ancestor), then it does not
need its reference count incremented (or later decremented).

I believe that this same technique should generalize to both the
reset/reuse and borrow signature inference passes.
2025-08-09 14:13:50 +00:00
Sebastian Ullrich
0b838ff2c9 chore: update stage0 2025-08-09 12:35:07 +02:00
Sebastian Ullrich
ca43608aa0 feat: allow combining private/public and protected 2025-08-09 12:35:07 +02:00
Rob23oba
ad471b46b8 fix: Inhabited instance of StdGen (#9782)
This PR corrects the `Inhabited` instance of `StdGen` to use a valid
initial state for the pseudorandom number generator. Previously, the
`default` generator had the property that `Prod.snd (stdNext default) =
default`, so it would produce only constant sequences.

[Zulip
discussion](https://leanprover.zulipchat.com/#narrow/channel/113489-new-members/topic/inhabited.20instance.20for.20StdGen.20isn't.20very.20random/with/533247146)
2025-08-08 06:23:48 +00:00
Kim Morrison
e6b357e87a chore: @[expose] List.mapIdxM (#9794) 2025-08-08 04:55:50 +00:00
Kim Morrison
b676fb1164 fix: @[expose] String.firstDiffPos and String.extract (#9792)
This PR adds `@[expose]` to two definitions with `where` clauses that
Batteries proves theorems about.
2025-08-08 04:55:45 +00:00
Kim Morrison
ca68b84623 chore: @[expose] List.filterMapTR (#9793)
This PR adds `@[expose]`, as Batteries wants access to the `where`
clause.
2025-08-08 04:55:38 +00:00
Kim Morrison
d6bc78dcb8 feat: split out Expr.getMVarDependencies from MVarId.getMVarDependencies (#9785)
This PR splits out an implementation detail of
MVarId.getMVarDependencies into a top-level function. Aesop was relying
on the function defined in the where clause, which is no longer possible
after #9759.
2025-08-08 00:28:30 +00:00
Cameron Zwarich
2104fd7da9 chore: remove unused default (#9791) 2025-08-07 16:27:23 +00:00
Kyle Miller
c801a9e8cf feat: use the metavariable index when pretty printing (#9778)
This PR modifies the pretty printing of anonymous metavariables to use
the index rather than the internal name. This leads to smaller numerical
suffixes in `?m.123` since the indices are numbered within a given
metavariable context rather than across an entire file, hence each
command gets its own numbering. This does not yet affect pretty printing
of universe level metavariables.

For debugging purposes, metavariables that are not defined now pretty
print as `?_mvar.123` rather than cause pretty printing to fail.
2025-08-07 15:58:51 +00:00
Sebastian Ullrich
c9a6446041 chore: CI: include tests in rebootstrap check (#9788) 2025-08-07 15:37:36 +00:00
Cameron Zwarich
a2f24fac65 chore: use unreachable! for unreachable cases, not silent fallback (#9790) 2025-08-07 15:23:01 +00:00
Cameron Zwarich
eaec888dc3 refactor: add isPossibleRef/isDefiniteRef fields to RC VarInfo (#9789)
These are the only uses of the existing `type` field, so we might as
well compute them up-front and store them.
2025-08-07 14:21:19 +00:00
Sebastian Graf
69d8cca38a feat: Add a simp lemma for PostCond.const (#9787)
This PR adds a simp lemma `PostCond.const_apply`.
2025-08-07 13:15:22 +00:00
Sebastian Graf
04a3968206 chore: Move withFreshUserNames to Lean/Meta/Basic.lean (#9783)
This PR generalizes and moves `withFreshUserNames` to
Lean/Meta/Basic.lean where it can be reused.
2025-08-07 10:27:52 +00:00
Sebastian Graf
ae699a6b13 fix: proper hygiene for goals generated by mvcgen (#9781)
This PR ensures that `mvcgen` is hygienic. The goals it generates should
now introduce all locals inaccessibly.
2025-08-07 09:33:06 +00:00
Kim Morrison
9257ef42ba feat: extend grind category theory tests (#9780)
This PR extends the test suite for `grind` working category theory, to
help debug outstanding problems in Mathlib.
2025-08-07 05:56:42 +00:00
Kim Morrison
63f899a407 chore: cleanup tests/lean/run/grind_cat (#9779)
Just tidying up and organising into sections, in preparation for
extending to capture problems in Mathlib.
2025-08-07 04:20:39 +00:00
Leonardo de Moura
690cf16aa5 fix: merge simplification and unfolding steps in grind (#9776)
This PR combines the simplification and unfold-reducible-constants steps
in `grind` to ensure that no potential normalization steps are missed.

Closes #9610
2025-08-07 04:15:52 +00:00
Cameron Zwarich
aaf831cd93 perf: don't mark params stored in tagged pointers as borrowed (#9775) 2025-08-07 03:49:23 +00:00
Cameron Zwarich
472a0b4954 refactor: invert and rename RC VarInfo.mustBeConsumed to .inheritsBorrowFromParam (#9777) 2025-08-07 02:04:12 +00:00
Cameron Zwarich
c04323a7d5 perf: use a slightly more refined borrowed param test in RC pass (#9774) 2025-08-07 01:08:32 +00:00
Cameron Zwarich
fac4905e89 chore: fix function body indentation (#9773) 2025-08-07 00:44:43 +00:00
Leonardo de Moura
65e55ac094 fix: projection propagation in grind (#9772)
This PR fixes a bug in the projection over constructor propagator used
in `grind`. It may construct type incorrect terms when a equivalence
class contains heterogeneous equalities.

closes #9769
2025-08-06 21:05:45 +00:00
Cameron Zwarich
f23d24ec7c perf: avoid computing liveness twice for cases in RC pass (#9770) 2025-08-06 18:54:58 +00:00
Cameron Zwarich
e332adf3d5 perf: avoid computing liveness twice for join point decls in RC pass (#9768)
We compute the liveness information for the join point body, so the only
thing that updateJPLiveVarMap should be adding is the binding of the
params, which we can easily do ourselves.

If we supported recursive join points, I believe this would actually be
a correctness issue, but as-is it doesn't affect the output.
2025-08-06 17:34:29 +00:00
Leonardo de Moura
13f00ea8ed fix: equality congruence proofs in grind (#9767)
This PR fixes equality congruence proof terms contructed by `grind`.
2025-08-06 16:40:27 +00:00
Lean stage0 autoupdater
a14e542ecb chore: update stage0 2025-08-06 16:54:50 +00:00
Sébastien Boisgérault
6065f08528 doc: fix "the same as the same as" in the description of |> (#9765)
This PR fixes the documentation of the pipe operator |>, which is
currently (emphasis mine):

> Haskell-like pipe operator `|>`. `x |> f` means **the same as the same
as** `f x`,
> and it chains such that `x |> f |> g` is interpreted as `g (f x)`.
2025-08-06 16:11:08 +00:00
Sebastian Ullrich
d455b05619 fix: panic on duplicate private def in public section (#9761) 2025-08-06 16:09:18 +00:00
Sebastian Ullrich
d49b941ea9 feat: default let rec and where decls to private under the module system (#9759)
Re-lands #9666
2025-08-06 15:53:51 +00:00
Sebastian Graf
478be16fc5 feat: Implement mvcgen +jp to prevent exponential VC blowup (#9736)
This PR implements the option `mvcgen +jp` to employ a slightly lossy VC
encoding for join points that prevents exponential VC blowup incurred by
naïve splitting on control flow.

```lean
def ifs_pure (n : Nat) : Id Nat := do
  let mut x := 0
  if n > 0 then x := x + 1 else x := x + 2
  if n > 1 then x := x + 3 else x := x + 4
  if n > 2 then x := x + 1 else x := x + 2
  if n > 3 then x := x + 1 else x := x + 2
  if n > 4 then x := x + 1 else x := x + 2
  if n > 5 then x := x + 1 else x := x + 2
  return x

theorem ifs_pure_triple : ⦃⌜True⌝⦄ ifs_pure n ⦃⇓ r => ⌜r > 0⌝⦄ := by
  unfold ifs_pure
  mvcgen +jp
  /-
  ...
  h✝⁵ : if n > 0 then x✝⁵ = 0 + 1 else x✝⁵ = 0 + 2
  h✝⁴ : if n > 1 then x✝⁴ = x✝⁵ + 3 else x✝⁴ = x✝⁵ + 4
  h✝³ : if n > 2 then x✝³ = x✝⁴ + 1 else x✝³ = x✝⁴ + 2
  h✝² : if n > 3 then x✝² = x✝³ + 1 else x✝² = x✝³ + 2
  h✝¹ : if n > 4 then x✝¹ = x✝² + 1 else x✝¹ = x✝² + 2
  h✝ : if n > 5 then x✝ = x✝¹ + 1 else x✝ = x✝¹ + 2
  ⊢ x✝ > 0
  -/
  grind
```
2025-08-06 15:21:08 +00:00
Sebastian Graf
26c1ddf104 feat: Add grind annotations for key SPred lemmas (#9757)
This PR adds `grind` annotations for key `Std.Do.SPred` lemmas.
2025-08-06 14:36:34 +00:00
Cameron Zwarich
f759d5dbc1 perf: erase all constructor params in the mono phase (#9764) 2025-08-06 14:23:28 +00:00
Paul Reichert
ea09ffc8ce refactor: restore Subarray.foldl and Subarray.forIn signatures (#9762)
This PR does what #9234 regrettably failed to do: actually reintroduce
the signatures of some `Subarray` functions that are now implemented via
slices (see #9017) in order to ensure backward compatibility and
consistency. With this PR, the old interface is restored. As an added
benefit, `Subarray.forIn` is no longer opaque.
2025-08-06 14:15:54 +00:00
Henrik Böving
6d5ce9b87f refactor: implement IO.waitAny using Lean (#9732)
This PR re-implements `IO.waitAny` using Lean instead of C++. This is to
reduce the size and
complexity of `task_manager` in order to ease future refactorings.

There is an import behavioral change of `IO.waitAny` in this PR.
Consider a situation where we have
two promises `p1`, `p2` and call `IO.waitAny [p1.result!, p2.result!]`
and `p1` resolves instantly.
Previously this would just return the result of `p1` and require nothing
else. With the new
implementation if `p2` is released before being resolved this can cause
a panic, even if
`IO.waitAny` has already finished. I argue that this is reasonable
behavior, given that an
invocation of `result!` promises that the promise will eventually be
resolved.
2025-08-06 13:09:15 +00:00
Lean stage0 autoupdater
24d4353ab2 chore: update stage0 2025-08-06 12:37:09 +00:00
Sebastian Ullrich
822f9e0a80 chore: deriving Hashable under the module system (#9760) 2025-08-06 11:55:53 +00:00
Sebastian Ullrich
09600f2ca4 chore: add lakeprof benchmarks (#9709) 2025-08-06 11:25:45 +00:00
Sebastian Ullrich
42e472ff3f refactor: simplify AddConstAsyncResult.commitCheckEnv use (#9715)
Also gets rid of some artifical `blocked (untracked)` time
2025-08-06 11:24:11 +00:00
Sebastian Ullrich
285d271505 doc: more careful Promise.result! docstring (#9734) 2025-08-06 11:23:43 +00:00
Kim Morrison
dcba6dfa7e chore: failing grind test cases for linarith on ordered fields (#9756) 2025-08-06 09:31:09 +00:00
Sebastian Graf
953a1eefbb feat: Implement mrevert ∀ (#9755)
This PR implements a `mrevert ∀n` tactic that "eta-reduces" the stateful
goal and is adjoint to `mintro ∀x1 ... ∀xn`.
2025-08-06 08:53:54 +00:00
Sebastian Graf
d5331d4150 feat: Make mleave apply at * and improve its simp set (#9581) (#9754)
This PR make `mleave` apply `at *` and improve its simp set in order to
discharge some more trivialities (#9581).

It also improves some documentation.
2025-08-06 08:34:45 +00:00
Sebastian Graf
61ea403bfa fix: Make mvcgen mintro let/have bindings (#9474) (#9507)
This PR makes `mvcgen` `mintro` let/have bindings.

Closes #9474.
2025-08-06 07:30:09 +00:00
Parth Shastri
d5e19f9b28 fix: remove accidental instance for lexOrd (#9739)
This PR removes the `instance` attribute from `lexOrd` that was
accidentally applied in `Std.Classes.Ord.Basic`.
2025-08-06 06:16:57 +00:00
Cameron Zwarich
d8c7c9fdb5 refactor: reduce code duplication (#9753) 2025-08-06 05:38:10 +00:00
Kim Morrison
ed1ca47199 chore: add failing grind cutsat tests (#9751)
Further `grind` cutsat failures relative to `omega`, found using Anne's
tactic analysis tool in Mathlib.
2025-08-06 04:15:34 +00:00
Cameron Zwarich
885b8bcc60 chore: inline a function into its only caller (#9750) 2025-08-06 03:47:38 +00:00
Cameron Zwarich
31e05cd2bd chore: fix typos (#9747) 2025-08-06 00:49:49 +00:00
Cameron Zwarich
7fb72a0081 refactor: rename RC VarInfo.consume field to .mustBeConsumed (#9746) 2025-08-06 00:48:10 +00:00
Mac Malone
f3e3ebba81 refactor: move import validation to parser & Lake (#9716)
This PR moves the validation of cross-package `import all` to Lake and
the syntax validation of import keywords (`public`, `meta`, and `all`)
to the two import parsers.

It also fixes the error reporting of the fast import parser
(`Lean.parseImports`) and adds positions to its errors.
2025-08-05 22:36:54 +00:00
Cameron Zwarich
51b780cd9f chore: rewrite LiveVars in a monadic style (#9745) 2025-08-05 21:49:43 +00:00
Cameron Zwarich
25b0c5af34 chore: don't match on Context (#9744) 2025-08-05 21:32:34 +00:00
Sebastian Ullrich
6ab20e7f03 chore: revert "feat: default let rec and where decls to private under the module system" (#9743)
Stage 2 tests broke, to be fixed tomorrow 

Reverts leanprover/lean4#9666
2025-08-05 21:28:08 +00:00
Cameron Zwarich
6846a5179b chore: reduce code duplication (#9742) 2025-08-05 20:42:56 +00:00
Cameron Zwarich
eb5399445a chore: clean up parens (#9740) 2025-08-05 18:21:38 +00:00
Cameron Zwarich
83c08880a6 chore: use dotted constructor names (#9738) 2025-08-05 17:17:06 +00:00
Cameron Zwarich
172a02557e chore: clean up uses of getters (#9737) 2025-08-05 16:48:35 +00:00
Leonardo de Moura
2d3501be61 feat: constant functions in grind (#9735)
This PR extends the propagation rule implemented in #9699 to constant
functions.
2025-08-05 16:19:51 +00:00
Sebastian Ullrich
d07ec9a19f chore: show @[expose] attribute in #print (#9722) 2025-08-05 15:59:49 +00:00
Cameron Zwarich
ed860dfa23 chore: use better struct literal syntax (#9731) 2025-08-05 14:07:39 +00:00
Henrik Böving
09e8079ea3 fix: U/SIntX BEq handling in bv_decide (#9728)
This PR fixes #9724
2025-08-05 11:43:43 +00:00
Sebastian Ullrich
b42a7780e2 feat: default let rec and where decls to private under the module system (#9666)
This PR addresses an outstanding feature in the module system to
automatically mark `let rec` and `where` helper declarations as private
unless they are defined in a public context such as under `@[expose]`.
2025-08-05 11:41:28 +00:00
Henrik Böving
4ee90bd82f fix: tag S/UInt conversions with int_toBitVec (#9721)
This PR tags more `SInt` and `UInt` lemmas with `int_toBitVec` so
`bv_decide`
can handle casts between them and negation.

This is based on a bug report from
https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/open.20scoped.20UInt64.2ECommRing/near/532485974
2025-08-05 08:30:33 +00:00
Cameron Zwarich
12cd4ca742 fix: remove incorrect error in LCNF's check (#9720)
This PR removes an error which implicitly assumes that the sort of type
dependency between erased types present in the test being added can not
occur. It would be difficult to refine the error using only the
information present in LCNF types, and it is of very little ongoing
value (I don't recall it ever finding an actual problem), so it makes
more sense to delete it.

Fixes #9692.
2025-08-05 04:36:57 +00:00
Cameron Zwarich
713a46cd75 chore: adopt <||> to reduce code duplication (#9719) 2025-08-05 04:13:02 +00:00
Cameron Zwarich
f236328bc3 chore: don't check type of erased arguments in FixedParams analysis (#9602) 2025-08-05 02:41:36 +00:00
Kim Morrison
6e06978961 chore: remove >6 month old deprecations (#9640) 2025-08-05 02:29:15 +00:00
Cameron Zwarich
8edcfbe776 fix: correctly handle non-Nat literal types in LCNF elimDeadBranches (#9703)
This PR changes the LCNF `elimDeadBranches` pass so that it considers
all non-`Nat` literal types to be `⊤`. It turns out that fixing this to
correctly handle all of these types with the current abstract value
representation is surprisingly nontrivial, and it's better to just land
the fix first.
2025-08-05 02:14:07 +00:00
Wojciech Nawrocki
1c60173b69 fix: mark __x patterns as impl details in match and intro (#9702)
This PR fixes an issue in the `match` elaborator where pattern variables
like `__x` would not have the kind `implDetail` in the local context.
Now `kindOfBinderName` is `LocalDeclKind.ofBinderName`.

Zulip discussion
[here](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Bad.20interaction.20of.20Qq.20with.20grind).

---------

Co-authored-by: Kyle Miller <kmill31415@gmail.com>
2025-08-04 22:54:39 +00:00
Cameron Zwarich
59579bfc3e refactor: remove goBig case from UnreachableBranches.ofNat (#9717)
This case can't meaningfully contribute to the result, because there are
no uses of `Nat` constructors in the `mono` phase.
2025-08-04 19:47:40 +00:00
Leonardo de Moura
7f22c0883b perf: Expr.toPoly in grind (#9714)
This PR adds a version of `CommRing.Expr.toPoly` optimized for kernel
reduction. We use this function not only to implement `grind ring`, but
also to interface the ring module with `grind cutsat`.
2025-08-04 15:30:10 +00:00
Cameron Zwarich
78b941019b refactor: use a state monad rather than combinators for computing free indices (#9711) 2025-08-04 13:55:41 +00:00
Leonardo de Moura
ae728d84f0 perf: proof terms for grind ring and grind cutsat (#9710)
This PR improves some of the proof terms produced by `grind ring` and
`grind cutsat`.
2025-08-04 12:27:11 +00:00
Markus Himmel
3eab35ef22 chore: minor improvements (#9708)
This PR stylistically improves an internal hash map proof and fixes a
typo in the docsting of `String.join`.
2025-08-04 07:12:05 +00:00
Cameron Zwarich
c260435913 refactor: use a state monad rather than combinators for computing max indices (#9707) 2025-08-04 05:15:22 +00:00
Leonardo de Moura
a5351b5c47 perf: add Poy.combine_mul_k (#9706)
This PR combines `Poly.combine_k` and `Poly.mul_k` steps used in the
`grind cutsat` proof terms.
2025-08-04 03:49:08 +00:00
Kim Morrison
718d8acc76 chore: update release_repos.yml (#9705)
This PR updates `release_repos.yml` to reflect that `import-graph` no
longer depends on `batteries`, and reorders the repositories to better
reflect dependencies.
2025-08-04 02:51:41 +00:00
Leonardo de Moura
e8c3c7b5eb perf: grind cutsat proof terms (#9704)
This PR optimizes the proof terms produced by `grind cutsat`. Additional
performance improvements will be merged later.
2025-08-04 02:35:34 +00:00
Sebastian Graf
8f575bf986 fix: Use non-overloading Std.Do.Triple notation in SpecLemmas.lean (#9701)
This PR switches to a non-verloading local `Std.Do.Triple` notation in
SpecLemmas.lean to work around a stage2 build failure.
2025-08-03 16:00:24 +00:00
Leonardo de Moura
cf48c6004d fix: assertion violations at grind checkInvariants (#9700)
This PR fixes assertion violations when `checkInvariants` is enabled in
`grind`
2025-08-03 12:27:26 +00:00
Leonardo de Moura
d0dc5dfd3d feat: propagation for functions with singleton domain in grind (#9699)
This PR adds propagation rules for functions that take singleton types.
This feature is useful for discharging verification conditions produced
by `mvcgen`. For example:

```lean
example (h : (fun (_ : Unit) => x + 1) = (fun _ => 1 + y)) : x = y := by
  grind
```
2025-08-03 12:00:29 +00:00
Joachim Breitner
af473b085a perf: MatchEqs.simpH: do not use contradiction (#9643)
This removes the early call to `contradiction` from `simpH`, and
replaces it with a quick check if the pattern start with different
constructors.

We already call `simpH` quadratically often (unavoidable), so we want it
to be quick. Most common contradictions are found later on, so maybe we
don't want to the expensive `contradiction` tactic to be run early.

May help with #9598.
2025-08-03 06:41:52 +00:00
Mac Malone
9e778f3a61 feat: lake: improve query formatting (#9698)
This PR adjusts the formatting type classes for `lake query` to no
longer require both a text and JSON form and instead work with any
combination of the two. The classes have also been renamed. In addition,
the query formatting of a text module header has been improved to only
produce valid headers.
2025-08-03 05:51:13 +00:00
Mac Malone
52855ce1c1 fix: lake: module lookup by source w/ multiple . (#9697)
This PR fixes the handling in `lake lean` and `lake setup-file` of a
library source file with multiple dots (e.g., `src/Foo.Bar.lean`).
2025-08-03 05:18:59 +00:00
Lean stage0 autoupdater
22000a703a chore: update stage0 2025-08-03 04:34:00 +00:00
Mac Malone
f6f54955fe fix: lake: thin archives for Windows bootstrap only (#9604)
This PR restricts Lake's production of thin archives to only the Windows
core build (i.e., `bootstrap = true`). The unbundled `ar` usually used
for core builds on macOS does not support `--thin`, so we avoid using it
unless necessary.
2025-08-03 03:54:33 +00:00
Cameron Zwarich
1459d17bfd chore: lift redundant markSimplified (#9691) 2025-08-02 23:21:21 +00:00
Sebastian Ullrich
77646f7149 chore: avoid calling into lake twice from CMake build (#9688)
Keeps the output cleaner and save a little time and potential
re-rebuilds
2025-08-02 20:48:45 +00:00
Sebastian Ullrich
1e83f62d31 perf: clarify and granularize access to async env ext state (#9587)
* Have asynchronous environment extensions specify whether they are
manipulate data for declarations from the "outside"/main branch (e.g.
attributes) or from the "inside"/async branch (e.g. data collected from
body elaboration) in order to avoid unnecessary waiting.
* Merge `findStateAsync?` into `getState` via a new, optional
`asyncDecl` parameter.
* Make `mayContainAsync` check an automatic part of `modifyState`.
2025-08-02 17:01:08 +00:00
Joachim Breitner
df9ca20339 perf: create unfolding theorem for wf-rec in one go (#9646)
This PR uses a more simple approach to proving the unfolding theorem for
a function defined by well-founded recursion. Instead of looping a bunch
of tactics, it uses simp in single-pass mode to (try to) exactly undo
the changes done in `WF.Fix`, using a dedicated theorem that pushes the
extra argument in for each matcher (or `casesOn`).

Improves performance for recursive functions with large `match`
statements, as in #9598.
2025-08-02 15:26:02 +00:00
Cameron Zwarich
b60f97cc19 chore: remove unused code in comment (#9687) 2025-08-02 15:18:41 +00:00
Leonardo de Moura
ab946fdf2c feat: clear implDetail local declarations in grind (#9686)
This PR applies `clear` to implementation detail local declarations
during the `grind` preprocessing steps.
2025-08-02 14:28:15 +00:00
Sebastian Ullrich
d9956a9d05 perf: properly specialize through PrefixTree (#9681)
The previous specialize annotations weren't doing anything
2025-08-02 13:59:56 +00:00
Leonardo de Moura
2713c846f1 chore: update tests/lean/grind todo folder (#9683)
Remove examples that we have already moved to `tests/lean/run`, and add
notes for possible fixes.
2025-08-02 13:10:34 +00:00
Leonardo de Moura
3056848819 fix: unfoldReducible' optimization regression in grind (#9682)
This PR fixes a regression introduced by an optimization in the
`unfoldReducible` step used by the `grind` normalizer. It also ensures
that projection functions are not reduced, as they are folded in a later
step.
2025-08-02 12:57:25 +00:00
Leonardo de Moura
08c3f3c236 feat: warn grind redundant parameters (#9679)
This PR produces a warning for redundant `grind` arguments.
2025-08-02 05:37:07 +00:00
Mac Malone
a01eda79e8 feat: lake: build times & --no-build jobs (#9677)
This PR adds build times to each build step of the build monitor (under
`-v` or in CI) and delays exiting on a `--no-build` until after the
build monitor finishes. Thus, a `--no-build` failure will now report
which targets blocked Lake by needing a rebuild.
2025-08-02 04:28:02 +00:00
Leonardo de Moura
f6e19f1f93 fix: nonstandard Nat and Int instances (#9676)
This PR adds normalizers for nonstandard arithmetic instances. The types
`Nat` and `Int` have built-in support in `grind`, which uses the
standard instances for these types and assumes they are the ones in use.
However, users may define their own alternative instances that are
definitionally equal to the standard ones. This PR normalizes such
instances using simprocs. This situation actually occurs in Mathlib.
Example:

```lean
class Distrib (R : Type _) extends Mul R where

namespace Nat

instance instDistrib : Distrib Nat where
  mul := (· * ·)

theorem odd_iff.extracted_1_4 {n : Nat} (m : Nat)
  (hm : n =
    @HMul.hMul _ _ _ (@instHMul Nat instDistrib.toMul)
      2 m + 1) :
    n % 2 = 1 := by
  grind

end Nat
```
2025-08-01 23:48:57 +00:00
Leonardo de Moura
bad582ed45 feat: Fin.val support in grind cutsat (#9675)
This PR adds support for `Fin.val` in `grind cutsat`. Examples:
```lean
example (a b : Fin 2) (n : Nat) : n = 1 → ↑(a + b) ≠ n → a ≠ 0 → b = 0 → False := by
  grind

example (m n : Nat) (i : Fin (m + n)) (hi : m ≤ ↑i) : ↑i - m < n := by
  grind

example {n : Nat} (m : Nat) (i : Fin n) ⦃j : Fin (n + m)⦄
    (this : ↑i + m ≤ ↑j) : ↑j - m < n := by
  grind

example {n : Nat} (i : Fin n) (j : Nat) (hj : j < ↑i) : j < n := by
  grind
```
2025-08-01 22:29:30 +00:00
Leonardo de Moura
18e1cdb7bb fix: user provided ToInt.toInt applications (#9673)
This PR ensures that `grind cutsat` processes `ToInt.toInt` applications
provided by the user. Example:

```lean
open Lean Grind
example (x : Fin 3) : ToInt.toInt x ≠ 0 → ToInt.toInt x ≠ 1 → ToInt.toInt x ≠ 2 → False := by
  grind -ring

example (x y z : Fin 5) : ToInt.toInt (x + z) = ToInt.toInt y → z = 0 → x = y := by
  grind -ring
```
2025-08-01 21:30:54 +00:00
Kyle Miller
aa3e50ee76 chore: revert reversion (#9672)
This PR reverts the test that was re-added #9669, since it remains
flaky.
2025-08-01 20:16:55 +00:00
Leonardo de Moura
eb6cede35d fix: normalize SMul.smul for Semiring and Ring (#9671)
This PR fixes support for `SMul.smul` in `grind ring`. `SMul.smul`
applications are now normalized. Example:
```lean
example (x : BitVec 2) : x - 2 • x + x = 0 := by
  grind
```
2025-08-01 20:16:03 +00:00
Leonardo de Moura
f8cdb03352 fix: add CommRing.Expr.intCast k and CommRing.Expr.natCast k (#9670)
This PR add constructors `.intCast k` and `.natCast k` to
`CommRing.Expr`. We need them because terms such as `Nat.cast (R := α)
1` and `(1 : α)` are not definitionally equal. This is pervaise in
Mathlib for the numerals `0` and `1`.

```lean
import Mathlib

example {α : Type} [AddMonoidWithOne α] : Nat.cast (R := α) 0 = (0 : α) := rfl -- not defeq
example {α : Type} [AddMonoidWithOne α] : Nat.cast (R := α) 1 = (1 : α) := rfl -- not defeq
example {α : Type} [AddMonoidWithOne α] : Nat.cast (R := α) 2 = (2 : α) := rfl -- defeq from here
-- Similarly for everything past `AddMonoidWithOne` in the Mathlib hierarchy, e.g. `Ring`.
```
2025-08-01 19:35:13 +00:00
Kyle Miller
08ff19d973 chore: add code action test back in (#9669)
This PR re-adds the code action test that was reverted in
5b18ea1545, now with more robustness.
2025-08-01 18:41:41 +00:00
Cameron Zwarich
2ea6b5068c chore: make Compiler.findJoinPoints trace messages more useful (#9668) 2025-08-01 17:42:32 +00:00
Paul Reichert
4cd917aa65 chore: make datokrat code owner for iterators, ranges and slices (#9667)
This PR adds some lines for `datokrat` to the `CODEOWNERS` file.
2025-08-01 17:34:43 +00:00
Joachim Breitner
417031fc17 chore: large match statement benchmark (#9665)
This PR adds a benchmark with a large, two-level, not-overlapping match
statement, including the splitter generation.
2025-08-01 15:25:07 +00:00
Sebastian Ullrich
416a8372cd perf: shorten rebuild critical path by 19% (#9626)
This PR adjusts the import graph, primarily of `Lean`, such that the
worst case rebuild time of core (`lean` only) is below 3 minutes on the
speedcenter machine (not captured by benchmark yet).
2025-08-01 11:18:21 +00:00
Henrik Böving
6eaf406305 chore: bump stack limit in benchmark (#9660) 2025-08-01 09:33:39 +00:00
Henrik Böving
009bcf1a27 perf: optimize fuzzyMatching (#9563)
This PR performs some micro optimizations on fuzzy matching for a `~20%`
instructions win.

The three key changes are:
- try to remove some unnecessary allocations of things such as tuples
- change `containsInOrderLower` to use the efficient `get'` and `next'`
primitives. I hope that we can replace these with iterators on strings
in the second half of this quarter
- Do the same thing as clangd and use `Int16` with the `minValue` being
used for "worst score" while this does have the potential to
over/underflow, if the user is working with a score in the 10000s
something weird is certainly going on already (the score usually seems
to be in the 2 digit area based on some).

As an additional bonus, once we finally have unboxed arrays we will get
some additional cache wins on the 16 bit arrays!
2025-08-01 09:11:15 +00:00
Sebastian Ullrich
335c5ca5c8 fix: trace.profiler.output with newer Firefox Profiler (#9659)
This PR fixes compatibility of the `trace.profiler.output` option with
newer versions of Firefox Profiler

Fixes #9473
2025-08-01 09:00:15 +00:00
Sebastian Ullrich
5b18ea1545 chore: remove flaky code action tests (#9658) 2025-08-01 07:58:13 +00:00
Rob23oba
d817fb0ef3 fix: handle NUL bytes in IO functions (#9616)
This PR introduces checks to make sure that the IO functions produce
errors when inputs contain NUL bytes (instead of ignoring everything
after the first NUL byte).
2025-08-01 06:12:53 +00:00
Lean stage0 autoupdater
37bf79b0e2 chore: update stage0 2025-08-01 06:29:07 +00:00
Mario Carneiro
7cdd65d5fb fix: build with libuv pre-1.45.0 (part 2) (#9652)
This PR continues #9644 , fixing the core build when using an older
system libuv.

This only affected users building Lean from scratch, since the lean
binaries we ship as part of toolchains statically link their own copy of
libuv 1.50+.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
2025-08-01 05:53:55 +00:00
Mac Malone
1901e2ecfd fix: lake: use server header for workspace modules (#9559)
This PR changes `lake setup-file` to use the server-provided header for
workspace modules.

This also reverts #9163 as the underlying issue is now fixed.
2025-08-01 05:08:44 +00:00
Kyle Miller
76051ab1fe feat: use name resolution for dot identifier notation (#9634)
This PR modifies dot identifier notation so that `(.a : T)` resolves
`T.a` with respect to the root namespace, like for generalized field
notation. This lets the notation refer to private names, follow aliases,
and also use open namespaces. The LSP completions are improved to follow
how dot ident notation is resolved, but it doesn't yet take into account
aliases or open namespaces.

Closes #9629
2025-08-01 02:27:40 +00:00
Kim Morrison
062ac89c34 chore: failing test cases for grind regressions vs omega (#9656) 2025-08-01 02:19:16 +00:00
jrr6
0c686e09db feat: add explanations for large elimination errors (#9653)
This PR adds error explanations for two common errors caused by large
elimination from `Prop`. To support this functionality, "nested" named
errors thrown by sub-tactics are now able to display their error code
and explanation.
2025-07-31 23:33:38 +00:00
Kyle Miller
4575799f8e chore: library style cleanup (#9654)
This PR cleans up the style of the library in anticipation of a future
PR that requires strict indentation for tactic sequences.
2025-07-31 21:28:59 +00:00
Sebastian Ullrich
271c8ab9cb fix: macros unfolding to multiple commands inside mutual (#9649)
This PR fixes an issue where a macro unfolding to multiple commands
would not be accepted inside `mutual`
2025-07-31 21:00:53 +00:00
jrr6
ee1854a607 feat: note potential discrepancies in deprecation warning (#9606)
This PR adds notes to the deprecation warning when the replacement
constant has a different type, visibility, and/or namespace.

Closes #7993
2025-07-31 16:41:14 +00:00
jrr6
9b186297c7 feat: add conversion-mode clear tactic (#6732)
This PR adds support for the `clear` tactic in conversion mode.

Closes #5734
2025-07-31 16:39:57 +00:00
Joachim Breitner
c8ef2fae1a chore: add #9598 as benchmark (#9642)
This PR adds the example from #9598 as a benchmark.
2025-07-31 15:32:54 +00:00
Sebastian Ullrich
0aba471758 perf: do not export LCNF/IR function summaries under the module system (#9645)
to avoid unexpected rebuilds
2025-07-31 15:23:04 +00:00
Sebastian Ullrich
467d905709 fix: more deriving handlers under the module system (#9647)
This PR fixes further deriving handlers to apply visibilities correctly
2025-07-31 15:00:58 +00:00
jrr6
62f14514da refactor: update built-in tactic error messages (#9633)
This PR updates various error messages produced by or associated with
built-in tactics and adapts their formatting to current conventions.
2025-07-31 14:16:57 +00:00
Lean stage0 autoupdater
5ece18cede chore: update stage0 2025-07-31 14:06:09 +00:00
Markus Himmel
33eac4497b fix: build with libuv pre-1.45.0 (#9644)
This PR fixes the core build when using an older system libuv.

This only affected users building Lean from scratch, since the `lean`
binaries we ship as part of toolchains statically link their own copy of
libuv 1.50+.
2025-07-31 13:18:41 +00:00
Wojciech Rozowski
fa449aab14 feat: add mutual_induct for (co)inductive predicates in mutual blocks (#9628)
This PR introduces a `mutual_induct` variant of the generated
(co)induction proof principle for mutually defined (co)inductive
predicates. Unlike the standard (co)induction principle (which projects
conclusions separately for each predicate), `mutual_induct` produces a
conjunction of all conclusions.

## Example

Given the following mutual definition:

```lean4
mutual
  def f : Prop := g
  coinductive_fixpoint

  def g : Prop := f
  coinductive_fixpoint
end
```

Standard coinduction principles:
```lean4 
f.coind : ∀ (pred_1 pred_2 : Prop), (pred_1 → pred_2) → (pred_2 → pred_1) → pred_1 → f
g.coind : ∀ (pred_1 pred_2 : Prop), (pred_1 → pred_2) → (pred_2 → pred_1) → pred_2 → g
```

New `mutual_induct`principle:
```lean4
f.mutual_induct: ∀ (pred_1 pred_2 : Prop), (pred_1 → pred_2) → (pred_2 → pred_1) → (pred_1 → f) ∧ (pred_2 → g)
```

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2025-07-31 12:39:52 +00:00
Sebastian Ullrich
5f20213876 refactor: minimize Lean.Meta.Tactic.TryThis imports (#9539) 2025-07-31 12:21:48 +00:00
Sebastian Ullrich
28f64e57ae chore: [match_pattern] should enforce [expose] (#9534) 2025-07-31 11:51:47 +00:00
Sebastian Ullrich
5e7c4557f8 refactor: minimize Lean.Meta.Diagnostics imports (#9546) 2025-07-31 08:23:13 +00:00
Joachim Breitner
c517f8fc9e chore: resurrect #8978, #8992, #8973 from bad merge (#9641)
This PR resurrects the changes from #8978, #8992, #8973 which were
accidentally removed by #8996.

Fixes #8962.

---------

Co-authored-by: Wojciech Rozowski <wojciech@lean-fro.org>
2025-07-31 08:04:40 +00:00
jrr6
3a3c816a27 chore: break up universe level error message (#9637)
This PR improves the readability of the "maximum universe level offset
exceeded" error message.
2025-07-30 23:52:53 +00:00
Sebastian Ullrich
b8e801ecad fix: deriving BEq on public inductives with private ctors (#9630)
Make the instance public while the body becomes private
2025-07-30 14:57:17 +00:00
Wojciech Rozowski
7f17970551 feat: generate (co)induction proof principles for mutually (co)inductive predicates (#9358)
This PR adds support for generating lattice-theoretic (co)induction
proof principles for predicates defined via `mutual` blocks using
`inductive_fixpoint`/`coinductive_fixpoint` constructs.

### Key Changes
- The order on product lattices (used to define fixpoints of mutual
blocks) is unfolded.
- Hypotheses in generated principles are curried.
- Conclusions are projected to focus only on the predicate of interest
(rather than being a conjunction of conclusions for all functions
defined in the `mutual` block.

### Example
Given:
```lean4
mutual
    def f : Prop :=
      g
    coinductive_fixpoint

    def g : Prop :=
      f
    coinductive_fixpoint
  end
```
The system now generates these coinduction principles:
```lean4
f.coinduct (pred_1 pred_2 : Prop) (hyp_1 : pred_1 → pred_2) (hyp_2 : pred_2 → pred_1) : pred_1 → f
```
and 
```lean4
g.coinduct (pred_1 pred_2 : Prop) (hyp_1 : pred_1 → pred_2) (hyp_2 : pred_2 → pred_1) : pred_2 → g
```

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2025-07-30 11:18:41 +00:00
Joachim Breitner
0f1fb8bafe chore: improve trace messages around wf_preprocess (#9625)
This PR improves trace messages around wf_preprocess.
2025-07-30 08:16:26 +00:00
Cameron Zwarich
7931e19572 perf: use xType field rather than conservatively recomputing it (#9345) 2025-07-30 04:34:13 +00:00
Kim Morrison
285f0e329f feat: add List/Array/Vector.sum_append_nat (#9622)
This PR adds a missing lemma about `List.sum`, and a grind annotation.

Noticed in @b-mehta's work.
2025-07-30 04:12:04 +00:00
Kim Morrison
9006af4a96 chore: rename Xor to XorOp (#9621)
This PR renames `Xor` to `XorOp`, to match `AndOp`, etc.
2025-07-30 00:51:10 +00:00
Kim Morrison
5f17e3bf15 feat: tweaks to List.Pairwise API (#9620)
This PR adds the separate directions of
`List.pairwise_iff_forall_sublist` as named lemmas.

I want to explore how they could/should be used by `grind` in Mathlib.
2025-07-29 23:47:33 +00:00
Kim Morrison
366b4b2810 feat: Nat.dfold (#7450)
This PR implements `Nat.dfold`, a dependent analogue of `Nat.fold`.
2025-07-29 23:36:47 +00:00
jcreedcmu
e3517f1c86 doc: freshen up Mac OSX build instructions (#9618)
This PR brings the Mac OSX build instructions up to date slightly. (They
currently refer to facts "...as of November 2014...")

- Remove specific OS version number from the title as it is out of date
with respect to filename.

- Nonetheless don't change filename for the sake of not breaking
incoming links.

- Update C++ language version to C++14, which I believe is what is
currently required, based on other platform documentation.

- Bump versions of C++ compilers that seem to be current. I expect the
exact values of these version numbers aren't crucial but maybe good for
the reader calibrating a vague sense of whether their compiler is in the
right ballpark.

- Add `lld` to the homebrew clang instructions, because homebrew changed
the way they package llvm tools, spinning the linker off into its own
package.
2025-07-29 21:42:24 +00:00
jrr6
fa1da03d50 feat: update structure/inductive error messages (#9592)
This PR updates the styling and wording of error messages produced in
inductive type declarations and anonymous constructor notation,
including hints for inferable constructor visibility updates.
2025-07-29 21:27:30 +00:00
Henrik Böving
5c2ae7b414 perf: optimize Name.toString (#9594)
This PR optimizes `Lean.Name.toString`, giving a 10% instruction
benefit.

Crucially this is a breaking change as the old `Lean.Name.toString`
method used to support a method for identifying tokens. This method is
now available as `Lean.Name.toStringWithToken` in order to allow for
specialization of the (highly common) `toString` code path which sets
this function to just return `false`.
2025-07-29 07:20:56 +00:00
David Thrane Christiansen
6ae31ea2d6 chore: simplify docstring for propext (#9593)
This PR simplifies the docstring for `propext` significantly.

The old docstring explained general concepts of axioms that are now
covered in the reference manual, and had a large example that was out of
date and has been subsumed by reference manual content.
2025-07-29 03:51:34 +00:00
Kim Morrison
edade0cea8 chore: add failing grind test about exponents (#9611) 2025-07-29 02:53:43 +00:00
Kim Morrison
969136b0d6 feat: add @[grind =] to Prod.lex_def (#9609)
This PR adds `@[grind =]` to `Prod.lex_def`. Note that `omega` has
special handling for `Prod.Lex`, and this is needed for `grind`'s cutsat
module to achieve parity.
2025-07-29 02:45:02 +00:00
Kim Morrison
1726a61e88 chore: add failing test for grind and BitVec (#9608)
This PR adds a failing test for `grind`, reported by @eric-wieser.

```
example {x : BitVec 2} : x - 2 • x + x = 0 := by
  grind -- fails
```

There are several independent problems here!

1. Cutsat doesn't evaluate `2 ^ 2`:
```
-- [cutsat] Assignment satisfying linear constraints
-- [assign] 「2 ^ 2」 := 0
```

2. We don't normalize `3 * 2 • x` to `6 * x` in the ring solver:
```
-- [ring] Rings ▼
--   [] Ring `BitVec 2` ▼
--     [diseqs] Disequalities ▼
--       [_] ¬2 * x + 3 * 2 • x = 0
```
This should then give a contradiction because the characteristic of
`BitVec 2` is 4.

3. In `Int`, we're not normalizing `*` and `•`:
```
-- [ring] Rings ▼
--   [] Ring `Int` ▼
--     [basis] Basis ▼
--       [_] 2 * ↑x + -1 * ↑(2 • x) + -4 * ((2 * ↑x + -1 * ↑(2 • x)) / 4) + -1 * ((2 * ↑x + -1 * ↑(2 • x)) % 4) = 0
```
2025-07-29 02:03:30 +00:00
Kim Morrison
9399b2ee36 chore: add failing grind test (#9607)
This PR adds a failing grind test.
2025-07-29 01:36:53 +00:00
jrr6
e53f944c83 fix: function field notation errors when head is an fvar (#9595)
This PR improves the error message displayed when writing an invalid
projection on a free variable of function type.
2025-07-28 23:07:02 +00:00
Mac Malone
dbfeb9e2da chore: upload build directory as artifact in cache CI (#9600)
This PR adds a step to the cached Linux Lake CI to upload the build
directory. This will help us debug any cache failures.
2025-07-28 20:29:51 +00:00
Lean stage0 autoupdater
ab87a6f797 chore: update stage0 2025-07-28 18:23:37 +00:00
Cameron Zwarich
475bd65c90 perf: during specialization, don't abstract all local fun decls under binders (#9596)
The `isUnderBinder` check is intended to avoid inlining repeated
computations into specializations, but this doesn’t apply to local
function decls whose bodies are already delayed.
2025-07-28 17:36:43 +00:00
Cameron Zwarich
0fe7cc8794 perf: increase usage of the tagged IR type for app return values (#9589) 2025-07-28 14:09:38 +00:00
Kim Morrison
2cdb547af0 chore: add 'public section' in Data/Vector/Algebra (#9588) 2025-07-28 13:07:21 +00:00
pandaman
fd25fd70f1 feat: add Iter.toArray lemmas (#9538)
This PR adds two lemmas related to `Iter.toArray`.

[Zulip
discussion](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Iterator.20Library.3A.20Request.20for.20Feedback/near/530567667)

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-07-28 11:46:38 +00:00
Sebastian Graf
8a58037df9 feat: Add List.zipWithM and Array.zipWithM (#9528)
This PR adds `List.zipWithM` and `Array.zipWithM`.
2025-07-28 08:39:52 +00:00
Kim Morrison
e38f0c6990 chore: remove bad grind annotation from pairwise_iff_forall_sublist (#9584) 2025-07-28 05:57:51 +00:00
Kim Morrison
557592aa97 feat: componentwise algebra operations on Vector (#9586)
This PR adds componentwise algebraic operations on `Vector α n`, and
relevant instances.
2025-07-28 05:56:10 +00:00
Eric Wieser
e5600afddc feat: missing pow lemmas for UInt (#9577)
This PR adds lemmas about `UIntX.toBitVec` and `UIntX.ofBitVec` and `^`.

These match the existing lemas for `*`.

After #7887 these can be made true by `rfl`.
2025-07-28 00:06:18 +00:00
Leonardo de Moura
87dae299b8 fix: ite and dite should not be used in E-matching patterns (#9579)
This PR ensures `ite` and `dite` are to selected as E-matching patterns.
They are bad patterns because the then/else branches are only
internalized after `grind` decided whether the condition is
`True`/`False`.

The issue reported by #9572 has been fixed, but the fix exposed another
issue. The patterns for `List.Pairwise` produce an unbounded number of
E-matching instances.
```lean
example (l : List α) : l.Pairwise R := by
  grind
```
2025-07-27 17:51:23 +00:00
Leonardo de Moura
7034310a3b fix: disequality proof construction in grind (#9578)
This PR fixes an issue in `grind`'s disequality proof construction. The
issue occurs when an equality is merged with the `False` equivalence
class, but it is not the root of its congruence class, and its
congruence root has not yet been merged into the `False` equivalence
class yet.

closes #9562
2025-07-27 14:49:10 +00:00
Cameron Zwarich
d7e7bd16a6 chore: increase code sharing in IR LiveVars computation (#9576) 2025-07-27 13:29:58 +00:00
Leonardo de Moura
bdd1918cd8 perf: optimizes grind ring proof terms (#9575)
This PR optimizes the proof terms generated by `grind ring`. For
example, before this PR, the kernel took 2.22 seconds (on a M4 Max) to
type-check the proof in the benchmark `grind_ring_5.lean`; it now takes
only 0.63 seconds.
2025-07-27 11:43:17 +00:00
Leonardo de Moura
30ba416fe3 feat: add grind option abstractProof (#9574)
This PR adds the option `abstractProof` to control whether `grind`
automatically creates an auxiliary theorem for the generated proof or
not.
2025-07-27 11:33:16 +00:00
Kim Morrison
95e753c6b4 feat: generalize Process.output/run to allow an input (#9532)
This PR generalizes `Process.output` and `Process.run` with an optional
`String` argument that can be piped to `stdin`.

To date we have been using shims `Process.runCmdWithInput` in Batteries.
2025-07-27 03:09:34 +00:00
Kyle Miller
5d54b0b13f fix: erroneous "no goals" in empty tactic list in induction/cases and other tactic info improvements (#9553)
This PR fixes a bug introduced in #7830 where if the cursor is at the
indicated position
```lean
example (as bs : List Nat) : (as.append bs).length = as.length + bs.length := by
  induction as with
  | nil => -- cursor
  | cons b bs ih =>
```
then the Infoview would show "no goals" rather than the `nil` goal. The
PR also fixes a separate bug where placing the cursor on the next line
after the `induction`/`cases` tactics like in
```lean
  induction as with
  | nil => sorry
  | cons b bs ih => sorry
  I -- < cursor
```
would report the original goal in the goal list. Furthermore, there are
numerous improvements to error recovery (including `allGoals`-type logic
for pre-tactics) and the visible tactic states when there are errors.
Adds `Tactic.throwOrLogErrorAt`/`Tactic.throwOrLogError` for throwing or
logging errors depending on the recovery state.
2025-07-26 23:15:31 +00:00
Wojciech Nawrocki
d2153064ec doc: clarify nondep behaviour (#9570)
This PR clarifies the behaviour of `mkLetFVars` and family on
nondependent `ldecl`s.

Zulip discussion
[here](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/mkLetFVars.20with.20nondependent.20let).
2025-07-26 22:46:48 +00:00
Kyle Miller
4d295d85b6 fix: make zero/succ hoverable in induction/cases (#9571)
This PR restores the feature where in `induction`/`cases` for `Nat`, the
`zero` and `succ` labels are hoverable. This was added in #1660, but
broken in #3629 and #3655 when custom eliminators were added. In
general, if a custom eliminator `T.elim` for an inductive type `T` has
an alternative `foo`, and `T.foo` is a constant, then the `foo` label
will have `T.foo` hover information.
2025-07-26 22:31:53 +00:00
Cameron Zwarich
8ce0e045a8 chore: increase code sharing in IR FreeVars computation (#9569) 2025-07-26 20:37:10 +00:00
Cameron Zwarich
2be6c75c2b chore: replace partially redundant calls to FnBody.split with .body (#9568) 2025-07-26 20:18:37 +00:00
Lean stage0 autoupdater
af84f76f31 chore: update stage0 2025-07-26 15:58:53 +00:00
Cameron Zwarich
dd45a21257 chore: remove unused FnBody.mdata constructor (#9564) 2025-07-26 15:20:13 +00:00
Sebastian Ullrich
8177de88cd perf: remove grind blockers (#9328)
This PR removes all blocking waits in `grind_bitvec2.lean` that can be
avoided by more fine-grained requests.
2025-07-26 06:15:33 +00:00
Sebastian Ullrich
99dac6aec0 doc: building core with Lake (#9547) 2025-07-26 06:13:09 +00:00
jrr6
30afb0dbec feat: improve set_option error messages (#9496)
This PR improves the error messages produced by the `set_option`
command.
2025-07-26 02:04:45 +00:00
jrr6
309a3c364f fix: avoid RPC errors in nonexistent identifier hovers (#9494)
This PR fixes an issue that caused some error messages to attempt to
display hovers for nonexistent identifiers.
2025-07-26 02:04:43 +00:00
jrr6
fcbd1037fd refactor: update and consolidate attribute-related error messages (#9495)
This PR consolidates common attribute-related error messages into
reusable functions and updates the wording and formatting of relevant
error messages.
2025-07-26 02:03:18 +00:00
Cameron Zwarich
aa769e7677 chore: make inferVisibility LCNF pass style match others (#9558) 2025-07-26 00:49:52 +00:00
Cameron Zwarich
737105fd78 chore: remove syntax for extern arity specifications (#9556) 2025-07-26 00:44:36 +00:00
Cameron Zwarich
1285a3c9a7 chore: clean up IR.Arg usage (#9557) 2025-07-26 00:22:38 +00:00
jrr6
17a477393c feat: allow custom preview spans in hint suggestions (#9555)
This PR allows hints in message data to specify custom preview spans
that extend beyond the edit region specified by the code action.
2025-07-26 00:04:28 +00:00
Lean stage0 autoupdater
437b4a4f9b chore: update stage0 2025-07-25 22:06:31 +00:00
Cameron Zwarich
eddc3b421e chore: remove support for unused arity specification in ExternAttrData (#9552)
This just removes the data for this specification. Removing the parser
support for it seems to require a stage0 update in between.
2025-07-25 21:23:56 +00:00
Kyle Miller
98569c7cf0 fix: make sure "dependent elimination failed" error is on cases (#9551)
This PR fixes the error position for the "dependent elimination failed"
error for the `cases` tactic.
2025-07-25 19:02:42 +00:00
Cameron Zwarich
7f39e56a79 chore: adopt List.find? in getExternEntryForAux (#9550) 2025-07-25 17:38:22 +00:00
Sebastian Ullrich
bc5526cacb fix: widgets broken by overzealous modularization (#9548) 2025-07-25 16:51:18 +00:00
Cameron Zwarich
6300329057 perf: consider functions with ordinary implicit arguments of instance type to be template-like (#9536)
This extends the specialization behavior of functions taking instance
implicits to ordinary implicit arguments that are of instance type. The
choice between the two is often made for subtle inference-related
reasons. It also affects visibility of these functions, because the
module system makes template-like decls visible to the compiler in other
modules.
2025-07-25 16:03:30 +00:00
Cameron Zwarich
15f0cd9527 fix: run inferVisibility after saveMono (#9545)
This PR makes the second instance of the `inferVisibility` pass run
after the `saveMono` pass. As the comment above the first instance of
the pass indicates, this needs to be after `saveMono` in order to see
all decls with their updated bodies.
2025-07-25 15:36:52 +00:00
Sebastian Ullrich
b437232ab6 refactor: minimize Lean.DefEqAttrib imports (#9543) 2025-07-25 15:18:17 +00:00
Sebastian Ullrich
3ff069911e refactor: remove some unnecessary meta imports (#9542) 2025-07-25 15:14:02 +00:00
Sebastian Ullrich
e74a97d5a8 perf: do not even open .olean.server when not necessary (#9531) 2025-07-25 14:52:24 +00:00
Sebastian Ullrich
7f4d673d33 perf: make builtin_initialize backing def private (#9540) 2025-07-25 14:41:49 +00:00
Sebastian Ullrich
81fe5243d3 chore: add grind tests as benchmarks (#9537) 2025-07-25 14:21:38 +00:00
Lean stage0 autoupdater
3f19182afc chore: update stage0 2025-07-25 12:44:14 +00:00
Sebastian Ullrich
ff1d3138bf refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
Kim Morrison
0071bea64e feat: helper instances for NameSet (#9529)
This PR upstreams some helper instances for `NameSet` from Batteries.

(These could be generalized to an arbitrary TreeSet, but I'll leave that
for someone else.)
2025-07-25 09:33:19 +00:00
Sebastian Ullrich
5244ac3bb5 feat: note inaccessible private declarations in unknown constant error (#9516)
This PR ensures that private declarations made inaccessible by the
module system are noted in the relevant error messages
2025-07-25 09:23:52 +00:00
Sebastian Ullrich
26be599e65 fix: inaccessible private messages in the module system (#9518)
This PR ensures previous "is marked as private" messages are still
triggered under the module system
2025-07-25 09:09:17 +00:00
Sebastian Ullrich
671057eecf fix: unif_hint under the module system (#9530) 2025-07-25 09:05:31 +00:00
Kim Morrison
0ab69a32cb chore: parameterize NoNatZeroDivisors by NatModule instead of HMul (#9527)
This PR changes `Lean.Grind.NoNatZeroDivisors` so that it is
parametrised by a `NatModule` instance rather than just a `HMul`
instance. This is sufficiently general for our purposes, and is a
band-aid (~40% improvement) for the performance problems we've been
seeing coming from inference here. The problems observed in Mathlib may
not see much improvement, however.
2025-07-25 08:46:05 +00:00
Joachim Breitner
6995f280b4 fix: unfold abstracted proofs before processing recursion (#9191)
This PR lets the equation compiler unfold abstracted proofs again if
they would otherwise hide recursive calls.
    
This fixes #8939.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-07-25 08:00:57 +00:00
Kim Morrison
73422d52fd chore: remove simp from unindexable Array.filterMap_some_fun (#9521) 2025-07-25 06:22:42 +00:00
Mac Malone
4875c6447f fix: lake: import all transitivity & related bugs (#9525)
This PR fixes Lake's handling of a module system `import all`.
Previously, Lake treated `import all` the same a non-module `import`,
importing all private data in the transitive import tree. Lake now
distinguishes the two, with `import all M` just importing the private
data of `M`. The direct private imports of `M` are followed, but they
are not promoted.

This also fixes some other Lake bugs with module system imports that
were discovered in the process.
2025-07-25 05:56:38 +00:00
Cameron Zwarich
820c1e6f15 chore: remove tests that recompile builtin definitions (#9523)
In the early days of the new compiler, it was common to make tests that
manually compiled a definition with the new compiler. The arity
reduction pass in LCNF deliberately does not compute a fixed point to
find a minimal set of used parameters for performance reasons, but
running it a second time can lead to different decisions being made and
a decl arity mismatch. This has been an issue for multiple people during
development. Removing the tests fixes the problem.

Fixes #9186.
2025-07-25 04:37:33 +00:00
Leonardo de Moura
92b870da4a fix: kernel deep recursion with normalizer (#9522)
This PR uses `withAbstractAtoms` to prevent the kernel from accidentally
reducing the atoms in the arith normlizer while typechecking. This PR
also sets `implicitDefEqProofs := false` in the `grind` normalizer
2025-07-25 04:37:17 +00:00
Kim Morrison
3eaa44dd4d fix: definition of Lean.Grind.Field (#9520)
This PR corrects the changes to `Lean.Grind.Field` made in #9500. 

(The lack of examples of fields in the core repository is a problem! I
guess it is likely that for interval arithmetic we will at least need
`Rat` soon.)
2025-07-25 00:35:43 +00:00
Rob23oba
e148871087 chore: fix spelling errors (#9175)
(Almost) only typos in constant names and doc-strings were considered;
grammar was not considered. Also, along others,
`mkDefinitionValInferrringUnsafe` has been fixed :-)
2025-07-24 23:35:32 +00:00
Henrik Böving
75b5c8b0aa perf: phashmap benchmark (#9517)
This PR adds a benchmark for the persistent hashmap, in particular also
covering the non
linear insert case which is often hit in practical uses. Furthermore the
same test case is also
added to the treemap benchmark.
2025-07-24 14:57:07 +00:00
Sebastian Ullrich
4177f123bc fix: expose LCNF of private inline decl referenced by implemented_by (#9514) 2025-07-24 13:05:21 +00:00
Sebastian Ullrich
db292b4c82 chore: minimize benchmark imports so we don't spend a majority in importing (#9513) 2025-07-24 12:14:12 +00:00
Henrik Böving
9669c6d5f1 perf: add benchmark for congruence reasoning in simp (#9511)
This PR adds a benchmark for putting pressure on simp's congruence
abilities.
2025-07-24 10:47:37 +00:00
Sebastian Graf
2748633637 fix: Make mframe, mspec and mvcgen hygienic (#9512)
This PR makes `mframe`, `mspec` and `mvcgen` respect hygiene.
Inaccessible stateful hypotheses can now be named with a new tactic
`mrename_i` that works analogously to `rename_i`.
2025-07-24 10:30:16 +00:00
Joachim Breitner
2075103cd9 fix: show kernel diagnostics even for examples (#9509)
This PR surfaces kernel diagnostics even in `example`.

The problem was that the kernel checking happens asynchronously. We
cannot use `reportDiag` in `addDecl`, which spawns that task, due to the
module hierarchy. For non `example`-declaration, `reportDiag` is called
somewhere else later, but for `example`, the `withoutModifyingEnv` in
`elabMutualDef` hid the kernel diagnostics. (But only the kernel
diagnostics; they are in the `Environment`, while the others are in the
`State`).

I also observed that the `reportDiag` in `elabAsync` (but not in
`elabSync`) duplicated the reporting, so without `elab.Async true` you
get the message twice. To fix this, `reportDiag` now resets the
diagnostics. This should avoid reporting counts twice in general (at
least within a linear use of the state).

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-07-24 09:21:47 +00:00
Sebastian Graf
b7dfda4f45 chore: Extract collectFreshMVars from withCollectingNewGoalsFrom (#9502) 2025-07-24 07:44:06 +00:00
Sebastian Graf
45514a955e feat: Add missing simp lemmas to mleave (#9506)
This PR adds a few missing simp lemmas to `mleave`.
2025-07-24 07:12:32 +00:00
Sebastian Graf
4fdf74500d fix: Remove duplicate syntax definitions for mvcgen* (#9505)
This PR removes vestigial syntax definitions in
`Lean.Elab.Tactic.Do.VCGen` that when imported undefine the `mvcgen`
tactic. Now it should be possible to import Mathlib and still use
`mvcgen`.
2025-07-24 06:57:00 +00:00
Sebastian Graf
d8f9463af3 feat: Add *.by_wp adequacy theorems for ReaderM and ExceptM (#9504)
This PR adds a few more `*.by_wp` "adequacy theorems" that allows to
prove facts about programs in `ReaderM` and `ExceptM` using the `Std.Do`
framework.
2025-07-24 06:53:59 +00:00
Sebastian Graf
ab18c82371 chore: Remove unused definitions relating to PredTrans (#9503) 2025-07-24 06:50:57 +00:00
Kim Morrison
68adcdb475 chore: maintain failing grind tests about Nat as a semiring (#9501)
These tests (still failing until we embed a NatModule in its IntModule
envelope) had further broken because of name changes.
2025-07-24 06:44:39 +00:00
Kim Morrison
3cde12567f feat: add HPow Int field to Field (#9500)
This PR adds a `HPow \a Int \a` field to `Lean.Grind.Field`, and
sufficient axioms to connect it to the operations, so that in future we
can reason about exponents in `grind`. To avoid collisions, we also move
the `HPow \a Nat \a` field in `Semiring` from the extends clause to a
field. Finally, we add some failing tests about normalizing exponents.
2025-07-24 06:00:11 +00:00
Kim Morrison
8d5da6491a chore: remove provable fields from Grind.Nat/IntModule (#9499) 2025-07-24 05:23:35 +00:00
Kim Morrison
eea7e50519 chore: script/release_steps.py only merges nightly-testing on rc1 (#9498) 2025-07-24 04:31:11 +00:00
Lean stage0 autoupdater
c4c3497776 chore: update stage0 2025-07-24 01:57:24 +00:00
Kyle Miller
d45cc674ea feat: make cdot expansion take hygiene into account (#9443)
This PR makes cdot function expansion take hygiene information into
account, fixing "parenthesis capturing" errors that can make erroneous
cdots trigger cdot expansion in conjunction with macros. For example,
given
```lean
macro "baz% " t:term : term => `(1 + ($t))
```
it used to be that `baz% ·` would expand to `1 + fun x => x`, but now
the parentheses in `($t)` do not capture the cdot. We also fix an
oversight where cdot function expansion ignored the fact that type
ascriptions and tuples were supposed to delimit expansion, and also now
the quotation prechecker ignores the identifier in `hygieneInfo`. (#9491
added the hygiene information to the parenthesis and cdot syntaxes.)

This fixes a bug discovered by [Google
DeepMind](https://storage.googleapis.com/deepmind-media/DeepMind.com/Blog/imo-2024-solutions/P1/index.html),
which made use of `useλy . x=>y.rec λS p=>?_`. The `use` tactic from
Mathlib wrapped the provided term in a type ascription, and so this was
equivalent to `use fun x => λy x x=>y.rec λS p=>?_`. (Note that cdot
function expansion is not able to take into account *where* the cdots
are located, and it is syntactically valid to insert an identifier into
the binder list like this. If we ever want to address this in the
future, we could have cdots expand into a special term that wraps an
identifier that evaluates to a local, but which would cause errors in
other contexts.)

Design note: we put the `hygieneInfo` on the open parenthesis rather
than at the end, since that way the hygiene information is available
even when there are parsing errors. This is important since we rely on
being able to elaborate partial syntax to get elab info (e.g. in `(a.`
to get completion info). Note that syntax matchers check that the
`hygieneInfo` is actually present, so such partial syntax would not be
matched.
2025-07-24 00:43:32 +00:00
Cameron Zwarich
8a0d036e82 perf: use an FVarIdHashSet for ReduceArity.State.used (#9497) 2025-07-24 00:25:26 +00:00
Lean stage0 autoupdater
9d93b10919 chore: update stage0 2025-07-23 21:41:23 +00:00
Kyle Miller
2412d52536 feat: add hygiene info to paren/tuple/typeAscription syntaxes (#9491)
This PR adds hygiene info to paren/tuple/typeAscription syntaxes, which
will be used to implement hygienic cdot function expansion in #9443.
2025-07-23 20:57:06 +00:00
Kyle Miller
e686d040ea fix: add missing spaces for pretty printing (#9475)
This PR fixes the way some syntaxes are pretty printed due to missing
whitespace advice.

Removes a vestigal `have'` tactic macro introduced in
0032578d5b back when `let` syntax looked
like `let Type := v`.

While we're here, extends the `let`/`have` docstrings to mention `(eq :=
h)` syntax.

Whitespace issues were reported by Damiano Testa [on
Zulip](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Some.20pretty.20printing.20quirks/near/529964215).
2025-07-23 19:35:04 +00:00
Leonardo de Moura
2dce18655d fix: incorrect proof term in grind linarith (#9487)
This PR fixes an incorrect proof term constructed by `grind linarith`,
as reported in #9485.

closes #9485
2025-07-23 17:34:44 +00:00
Kyle Miller
6cf22b32aa feat: custom structure constructors can update binder kinds of parameters (#9480)
This PR adds a feature where `structure` constructors can override the
inferred binder kinds of the type's parameters. In the following, the
`(p)` binder on `toLp` causes `p` to be an explicit parameter to
`WithLp.toLp`:
```lean
structure WithLp (p : Nat) (V : Type) where toLp (p) ::
  ofLp : V
```
This reflects the syntax of the feature added in #7742 for overriding
binder kinds of structure projections. Similarly, only those parameters
in the header of the `structure` may be updated; it is an error to try
to update binder kinds of parameters included via `variable`.

Closes #9072.

Fixes a possible bug from stale caches when creating the type of the
constructor.
2025-07-23 16:33:34 +00:00
Rob23oba
d24219697e feat: unexpand Vector.mk #[...] _ to #v[...] (#8391)
This PR adds an unexpander for `Vector.mk` that unexpands `Vector.mk
#[...] _` to `#v[...]`.
```lean
-- previously:
#check #v[1, 2, 3] -- { toArray := #[1, 2, 3], size_toArray := ⋯ } : Vector Nat 3
-- now:
#check #v[1, 2, 3] -- #v[1, 2, 3] : Vector Nat 3
```

---------

Co-authored-by: Kyle Miller <kmill31415@gmail.com>
2025-07-23 16:27:51 +00:00
Lean stage0 autoupdater
d353a25a36 chore: update stage0 2025-07-23 16:53:11 +00:00
Sebastian Ullrich
9dc4dbebe1 perf: do not try to mmap .ir to the same address as .olean (#9488) 2025-07-23 16:12:44 +00:00
Sebastian Ullrich
04be1c6b5c chore: CI: cached Lake as secondary job (#9486) 2025-07-23 13:26:35 +00:00
Sebastian Ullrich
e46a3108d9 perf: do not export specializations (#9465)
Trading an insignificant amount of IR bloat for better recompilation
avoidance
2025-07-23 13:12:15 +00:00
Sebastian Ullrich
4cbfa485fa chore: fix test on macOS (#9483) 2025-07-23 12:10:13 +00:00
Sebastian Ullrich
9328271dd0 perf: do not export LCNF decls of closed terms (#9484)
This was only necessary when `isDeclMeta` and `isDeclPublic` were
intertwined
2025-07-23 09:50:29 +00:00
Lean stage0 autoupdater
f137d43931 chore: update stage0 2025-07-23 09:39:13 +00:00
Sebastian Ullrich
0ba5413266 refactor: remove unused Environment.extraConstNames (#9470)
Obsoleted in #9356
2025-07-23 08:58:32 +00:00
Sebastian Ullrich
fefc033515 chore: disable artifacts cache for building stage2+ (#9482) 2025-07-23 08:44:08 +00:00
Lean stage0 autoupdater
d888039468 chore: update stage0 2025-07-23 08:54:57 +00:00
Sebastian Ullrich
ddc4cf0a97 refactor: private field use in Meta.Context (#9468)
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.
2025-07-23 08:16:44 +00:00
Leonardo de Moura
aa5b392e35 fix: canonicalization of non-standard OfNat.ofNat terms (#9481)
This PR fixes a kernel type mismatch that occurs when using `grind` on
goals containing non-standard `OfNat.ofNat` terms. For example, in issue
#9477, the `0` in the theorem `range_lower` has the form:
```lean
(@OfNat.ofNat
  (Std.PRange.Bound (Std.PRange.RangeShape.lower (Std.PRange.RangeShape.mk Std.PRange.BoundShape.closed Std.PRange.BoundShape.open)) Nat)
  (nat_lit 0)
  (instOfNatNat (nat_lit 0)))
```
instead of the more standard form:
```lean
(@OfNat.ofNat
  Nat
  (nat_lit 0)
  (instOfNatNat (nat_lit 0)))
```

Closes #9477
2025-07-23 04:10:21 +00:00
Lean stage0 autoupdater
6346fdb253 chore: update stage0 2025-07-23 02:31:29 +00:00
Leonardo de Moura
7d2a7dba81 fix: improve evalInt? (#9479)
This PR improves the `evalInt?` function, which is used to evaluate
configuration parameters from the `ToInt` type class. This PR also adds
a new `evalNat?` function for handling the `IsCharP` type class, and
introduces a configuration option:
```
grind (exp := <num>)
```
This option controls the maximum exponent size considered during
expression evaluation. Previously, `evalInt?` used `whnf`, which could
run out of stack space when reducing terms such as `2^1024`.

closes #9427
2025-07-23 01:51:04 +00:00
Aaron Liu
98f05c47d0 fix: add binrel% macros for notation in Init.Core (#9084)
This PR adds `binrel%` macros for `!=` and `≠` notation defined in
`Init.Core`. This allows the elaborator to insert coercions on both
sides of the relation, instead of committing to the type on the left
hand side.

I first discovered this bug while working on Brouwer's fixed point
theorem. See the discussion on Zulip at [#lean4 > Elaboration of
&#96;≠&#96; @
💬](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Elaboration.20of.20.60.E2.89.A0.60/near/526236907).
2025-07-23 01:34:55 +00:00
Mac Malone
67bbc947af feat: lake: meta import support (#9478)
This PR adds proper Lake support for `meta import`. Module IR is now
tracked in traces and in the pre-resolved modules Lake passes to `lean
--setup`.
2025-07-23 01:17:20 +00:00
Leonardo de Moura
64219ac91e fix: assertNatCast in grind (#9476)
This PR fixes the bridge between `Nat` and `Int` in `grind cutsat`.

Closes #9467
2025-07-22 21:59:38 +00:00
Leonardo de Moura
dedd9275ec fix: mkCongrSimpCore? (#9472)
This PR fixes another issue at the `congr_simp` theorems that was
affecting Mathlib. Many thanks to Johan Commelin for creating the mwe.

closes #9466
2025-07-22 18:09:24 +00:00
Sebastian Ullrich
4dbe84dc98 chore: ensure Lake and Lean agree when .ir is needed (#9471) 2025-07-22 17:34:41 +00:00
Giles Shaw
0cc4c91800 fix: change the proof of Nat.zero_mod to rfl (#9391)
This PR replaces the proof of the simplification lemma `Nat.zero_mod`
with
`rfl` since it is, by design, a definitional equality. This solves an
issue
whereby the lemma could not be used by the simplifier when in 'dsimp'
mode.

Closes #9389

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2025-07-22 13:21:48 +00:00
Sebastian Graf
548d564c18 feat: Introduce mleave tactic that leaves the SPred proof mode (#9363) (#9454)
This PR introduces tactic `mleave` that leaves the `SPred` proof mode by
eta expanding through its abstractions and applying some mild
simplifications. This is useful to apply automation such as `grind`
afterwards.

Relates to #9363.
2025-07-22 11:50:16 +00:00
Sebastian Graf
2d30e3913c fix: Handle let/have in mintro (#9365) (#9451)
This PR adds support in the `mintro` tactic for introducing `let`/`have`
binders in stateful targets, akin to `intro`. This is useful when
specifications introduce such let bindings.

Closes #9365.
2025-07-22 11:35:46 +00:00
Joachim Breitner
ec13bb963f fix: PProdN.reduceProjs to also look for projection functions (#9464)
This PR makes `PProdN.reduceProjs` also look for projection functions.
Previously, all redexes were created by the functions in `PProdN`, which
used primitive projections. But with `mkAdmProj` the projection
functions creep in via the types of the `admissible_pprod_fst` theorem.
So let's just reduce both of them.

Fixes #9462.
2025-07-22 09:22:50 +00:00
Lean stage0 autoupdater
9006597f59 chore: update stage0 2025-07-22 09:47:42 +00:00
Sebastian Ullrich
e28569f2a1 perf: minimize exported codegen data (#9356)
To be documented
2025-07-22 09:05:49 +00:00
Kenny Lau
751947482f fix: use let rec for Fin.reverseInduction (#9142)
This PR changes `Fin.reverseInduction` from using well-founded recursion
to using `let rec`, which makes it have better definitional equality.
Co-authored by @digama0. See the test below:

```lean
namespace Fin

/-- The new one. -/
@[elab_as_elim] def reverseInduction' {motive : Fin (n + 1) → Sort _} (last : motive (Fin.last n))
    (cast : ∀ i : Fin n, motive i.succ → motive (castSucc i)) (i : Fin (n + 1)) : motive i :=
  let rec go (j : Nat) (h) (h2 : i ≤ j) (x : motive ⟨j, h⟩) : motive i :=
    if hi : i.1 = j then (show i = ⟨j, h⟩ by simp [← hi]) ▸ x
    else match j with
      | 0 => by omega
      | j+1 => go j (by omega) (by omega) (cast ⟨j, by omega⟩ x)
  go _ _ (by omega) last

/-- Same code but using reverseInduction'. -/
@[elab_as_elim] def lastCases' {n : Nat} {motive : Fin (n + 1) → Sort _} (last : motive (Fin.last n))
    (cast : ∀ i : Fin n, motive (castSucc i)) (i : Fin (n + 1)) : motive i :=
  reverseInduction' last (fun i _ => cast i) i

end Fin

theorem foo : (Fin.lastCases (-4) (fun i ↦ (i : Int) * 2 + 1) (2 : Fin 3) : Int) = -4 := rfl
#eval (Fin.lastCases (-4) (fun i ↦ (i : Int) * 2 + 1) (2 : Fin 3) : Int)
theorem foo' : (Fin.lastCases' (-4) (fun i ↦ (i : Int) * 2 + 1) (2 : Fin 3) : Int) = -4 := rfl
#eval (Fin.lastCases' (-4) (fun i ↦ (i : Int) * 2 + 1) (2 : Fin 3) : Int)

theorem bar : (Fin.reverseInduction (n := 2) (motive := fun _ ↦ Int)
    (-4) (fun i _ ↦ (i : Int) * 2 + 1) (2 : Fin 3) : Int) = -4 := rfl
#eval (Fin.reverseInduction (n := 2) (motive := fun _ ↦ Int)
    (-4) (fun i _ ↦ (i : Int) * 2 + 1) (2 : Fin 3) : Int)
theorem bar' : (Fin.reverseInduction' (n := 2) (motive := fun _ ↦ Int)
    (-4) (fun i _ ↦ (i : Int) * 2 + 1) (2 : Fin 3) : Int) = -4 := rfl
#eval (Fin.reverseInduction' (n := 2) (motive := fun _ ↦ Int)
    (-4) (fun i _ ↦ (i : Int) * 2 + 1) (2 : Fin 3) : Int)
```
[Link to Lean 4
Web](https://live.lean-lang.org/#project=lean-nightly&codez=HYQwtgpgzgDiDGEAEAxAlsAUJg9AWjyQBUALZYCAdyQHsKA6JPHTAAQG0IAbEAIwH0QUftzRgAukgAmEAGZIAThABuEBVAgBJYFICu8AC5o6AciQBvMDSOqkALlQYkACmBIA1EgCMASiSAkwiQAZRoFAyR+AF8XHihwhysbZGd0YHpY8OAfH0wkPJd4IXikQAAiJDR7RzdgABokRLRbNHoofXgA+utG5MK4oLby7JcKh1SXN09fPwSupvsAXlykLghwpXaAcxoXACtKgDkQAz9nEhOSACZKisATIiQdk4APSobbQAvyHbqSQEvyac6k8oLJZ5NDyEgjcr0LxIeb3JAGMhuZxQEg0agVWEfL7fJC8ACeSCgYhgSHYgATCJDg8R+QAdpEhHsCkNwNPUjvASHDKGgEYy8gAfJAABhhAD5cQSaJANiBeUgBTt3ND5mKtnDnPjaFKQCcNZKINKTr1wljxZr9SAcY8cnlVfwIi5dVq/BlsPhCEFwMh4DQZLjdOFdETgBtFCo1BptHpDMZgCZGMw2JweAIhCIuGJJDJ5BkAMJCaBmcxuByHAzRSyzZCjJyuDzePyBEJhCLRZwZF6VlypdJFJBZa35ZxGyplCFjWr/boFIr9eDtNBDZxjmsTet/V7IEaLPJKVTqLQ6fRGUzLXvOWS6NwVO3KpDDhflbAQHRVbAIiChCBgJCyGjbBwpBgPZxHmGhQC4eAACwnBeV5IIAZYTDJU2jHEgABUSBXJMJxXNWbgAMx/ChfiwlBCyKLIXCYAAxCoIBcF2QG5vm4HOFBMGXoCiFLshwCoRhWH1i4uFVEghG8ccmDvp+36/jQZgAd2zFgWYbHQS4sFcUhDjEehmF1r4wmVGM4k6XxJFMJB5EKJRNF0QxgFpMpBYQep56cRU3EQrpAkGThxlOKZSDEW+ZAybiIAKJUjn0Lu4YHlGx5IsWsIXCcG7kZpdqISF+SuRxcHZdpwXmXpgmGc4IkmURpWkVZdiwjZVG0co9GMWkcX7pGR4xuM5FpS4GUNT+nFFblg7sRpHn2l5El+L52FGXhYk1ZJ0lKN+vCRQp7WxWGXWHtGJ61sNA3OENsJZQhJWSXlakFYCRU8WZ/H6YtlUBQRq0WWRw1NXZrUOd2nURodSWqSlmHpZ2w1XTl5mMvdU2Fddz03fNb1CR9y1BcRQA)

Notice how `rfl` fails for the 1st and 5th tests that use the original
`Fin.reverseInduction`, but the 3rd and 7th tests that use the new code
in this PR succeed.

Closes #9141.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
2025-07-22 08:34:14 +00:00
Rob23oba
b7ab7ea745 fix: behavior of String.next (#9449)
This PR fix the behavior of `String.next` on the scalar boundary (`2 ^
63 - 1` on 64-bit platforms).

Closes #9440
2025-07-22 06:48:33 +00:00
Cameron Zwarich
6f5532f069 perf: make function types object rather than tobject (#9461) 2025-07-22 01:16:45 +00:00
Cameron Zwarich
30ca6c82e0 refactor: use named params (#9460) 2025-07-22 00:11:25 +00:00
Cameron Zwarich
968a708a9f perf: update type information in cases arms for RC optimizations (#9457)
The `isRef` check being removed here used to be an optimization, because
this structure only tracked whether ref counting operations need to be
inserted at all. Now the structure also tracks whether the value needs
to be checked for being a scalar or not, which is something that can be
refined by a `cases` arm, since inductive types can have a mix of scalar
and non-scalar constructors.
2025-07-21 23:10:11 +00:00
Cameron Zwarich
bb23700f24 chore: add named params to MonadWithReader.withReader (#9459)
This matches `MonadWithReaderOf`.
2025-07-21 23:02:19 +00:00
Cameron Zwarich
9a34f6bc95 refactor: remove questionable defaults in Context structure (#9458) 2025-07-21 22:16:14 +00:00
Cameron Zwarich
f3e1795175 refactor: clean up monad setup (#9456) 2025-07-21 21:22:20 +00:00
jrr6
d57d1fcd36 fix: prevent deriving handlers from generating ambiguous identifiers (#9371)
This PR fixes an issue that caused some `deriving` handlers to fail when
the name of the type being declared matched that of a declaration in an
open namespace.

Closes #9366
2025-07-21 17:45:54 +00:00
Lean stage0 autoupdater
e134cfea8f chore: update stage0 2025-07-21 16:24:20 +00:00
Marc Huisinga
8b8561a699 feat: improved go to definition (#9040)
This PR improves the 'Go to Definition' UX, specifically:
- Using 'Go to Definition' on a type class projection will now extract
the specific instances that were involved and provide them as locations
to jump to. For example, using 'Go to Definition' on the `toString` of
`toString 0` will yield results for `ToString.toString` and `ToString
Nat`.
- Using 'Go to Definition' on a macro that produces syntax with type
class projections will now also extract the specific instances that were
involved and provide them as locations to jump to. For example, using
'Go to Definition' on the `+` of `1 + 1` will yield results for
`HAdd.hAdd`, `HAdd α α α` and `Add Nat`.
- Using 'Go to Declaration' will now provide all the results of 'Go to
Definition' in addition to the elaborator and the parser that were
involved. For example, using 'Go to Declaration' on the `+` of `1 + 1`
will yield results for `HAdd.hAdd`, `HAdd α α α`, `Add Nat`,
``macro_rules | `($x + $y) => ...`` and `infixl:65 " + " => HAdd.hAdd`.
- Using 'Go to Type Definition' on a value with a type that contains
multiple constants will now provide 'Go to Definition' results for each
constant. For example, using 'Go to Type Definition' on `x` for `x :
Array Nat` will yield results for `Array` and `Nat`.

### Details
'Go to Definition' for type class projections was first implemented by
#1767, but there were still a couple of shortcomings with the
implementation. E.g. in order to jump to the instance in `toString 0`,
one had to add another space within the application and then use 'Go to
Definition' on that, or macros would block instances from being
displayed. Then, when the .ilean format was added, most 'Go to
Definition' requests were already handled using the .ileans in the
watchdog process, and so the file worker never received them to handle
them with the semantic information that it has available.

This PR resolves most of the issues with the previous implementation and
refactors the 'Go to Definition' control flow so that 'Go to Definition'
requests are always handled by the file worker, with the watchdog merely
using its .ilean position information to update the positions in the
response to a more up-to-date state. This is necessary because the file
worker obtains its position information from the .oleans, which need to
be rebuilt in order to be up-to-date, while the watchdog always receives
.ilean update notifications from each active file worker with the
current position information in the editor.

Finally, all of the 'Go to Definition' code is refactored to be easier
to maintain.

### Breaking changes
`InfoTree.hoverableInfoAt?` has been generalized to
`InfoTree.hoverableInfoAtM?` and now takes a general `filter` argument
instead of several boolean flags, as was the case before.
2025-07-21 15:47:44 +00:00
Lean stage0 autoupdater
51ae98ae30 chore: update stage0 2025-07-21 14:40:51 +00:00
Henrik Böving
09de5cd70e refactor: remove Lean.RBMap usages (#9260)
This PR removes uses of `Lean.RBMap` in Lean itself.

Furthermore some massaging of the import graph is done in order to avoid
having `Std.Data.TreeMap.AdditionalOperations` (which is quite
expensive) be the critical path for a large chunk of Lean. In particular
we can build `Lean.Meta.Simp` and `Lean.Meta.Grind` without it thanks to
these changes.

We did previously not conduct this change as `Std.TreeMap` was not
outperforming `Lean.RBMap` yet, however this has changed with the new
code generator.
2025-07-21 14:04:45 +00:00
Joachim Breitner
23e88b4e1d chore: test for issue #9018 (#9452) 2025-07-21 13:55:36 +00:00
Joachim Breitner
fcd60e73f8 fix: use withIncRecDepth in SizeOf deriving (#9448)
This PR addresses the lean crash (stack overflow) with nested induction
and the generation of the `SizeOf` spec lemmas, reported at #9018.

It does not address the underlying issue that in these cases, the
generated SizeOf code does not match the the SizeOf function found by
instance search, and thus the generation fails.

This seem hard to fix: `mkSizeOfMinors` would have to recognize that
given, say, `List (Id Tree)`, the derived instance (assuming there was
one for `Tree`) is not the same as for `List Tree`.

The problem seems just about as hard as getting derived SizeOf right in
the presence of nested induction and non-canonical SizeOf instances.
2025-07-21 12:43:19 +00:00
Rob23oba
b7f433c5b9 fix: behavior of String.prev (#9441)
This PR fixes the behavior of `String.prev`, aligning the runtime
implementation with the reference implementation. In particular, the
following statements hold now:
- `(s.prev p).byteIdx` is at least `p.byteIdx - 4` and at most
`p.byteIdx - 1`
- `s.prev 0 = 0`
- `s.prev` is monotone

Closes #9439
2025-07-21 10:50:14 +00:00
Sebastian Graf
f3ac38ff2c fix: Close pure, trivial goals in mvcgen (#9362) (#9447)
This PR ensures that `mvcgen` not only tries to close stateful subgoals
by assumption, but also pure Lean goals.

Closes #9362.
2025-07-21 10:12:34 +00:00
Lean stage0 autoupdater
c5a5c5572f chore: update stage0 2025-07-21 05:32:04 +00:00
Cameron Zwarich
2f7c0366f5 perf: treat partial application and eta expansion equally for specialization (#9438) 2025-07-20 14:57:21 +00:00
Cameron Zwarich
1a9757d1f6 refactor: make withReader calls more readable (#9442) 2025-07-20 13:39:35 +00:00
Mac Malone
3aaa3beeee feat: lake: job count in build success message (#9436)
This PR adds the number of jobs run to the final message Lake produces
on a successfully run of `lake build`.


**Examples**
```
Build completed successfully (1 job).
Build completed successfully (6 jobs).
```
2025-07-19 04:59:39 +00:00
Mac Malone
deef4e8e23 feat: lake: libPrefixOnWindows (#9435)
This PR adds the `libPrefixOnWindows` package and library configuration
option. When enabled, Lake will prefix static and shared libraries with
`lib` on Windows (i.e., the same way it does on Unix).
2025-07-19 04:46:42 +00:00
Mac Malone
c660f63748 refactor: lake: restore libs & exes from cache (#9434)
This PR changes the Lake local cache infrastructure to restore
executables and shared and static libraries from the cache. This means
they keep their expected names, which some use cases still rely on.
2025-07-19 03:28:42 +00:00
jrr6
b7e220039f feat: add hints for tuple projections (#9387)
This PR adds a hint to the "invalid projection" message suggesting the
correct nested projection for expressions of the form `t.n` where `t` is
a tuple and `n > 2`.

This feature was originally proposed by @nomeata in #8986.
2025-07-18 23:55:13 +00:00
jrr6
34bd6e8bfd feat: improve split error messages (#9424)
This PR improves the error messages produced by the `split` tactic,
including suggesting syntax fixes and related tactics with which it
might be confused.

Note that, to avoid clashing with the new error message styling
conventions used in these messages, this PR also updates the formatting
of the message produced by `throwTacticEx`.

Closes #6224
2025-07-18 22:36:10 +00:00
Cameron Zwarich
5cd5885da4 fix: make IRType.erased a tobject when boxing it (#9431)
This PR changes `IRType.boxed` to map `erased` to `tobject` rather than
`object`, since `erased` has a representation of a boxed scalar 0 when
we are forced to represent it at runtime. This case does not occur at
all in the Lean codebase.
2025-07-18 20:10:52 +00:00
jrr6
5f4e6a86d5 feat: update and explain "unknown constant" and "failed to infer type" errors (#9423)
This PR updates the formatting of, and adds explanations for, "unknown
identifier" errors as well as "failed to infer type" errors for binders
and definitions.

It attempts to ameliorate some of the confusion encountered in #1592 by
modifying the wording of the "header is elaborated before body is
processed" note and adding further discussion and examples of this
behavior in the corresponding error explanation.
2025-07-18 19:20:31 +00:00
Cameron Zwarich
1043569648 perf: use more precise IR types for overapplication (#9428) 2025-07-18 16:34:19 +00:00
Paul Reichert
383256defa chore: reintroduce Subarray.foldl on top of Slice.foldl (#9234)
An earlier PR (#9017) replaced certain subarray functions such as
`Subarray.foldl` with generic slice functions `Slice.foldl`. For
backward compatibility reasons, This PR reintroduces `Subarray.foldl`
etc. as aliases for the `Slice` versions.
2025-07-18 15:23:50 +00:00
Cameron Zwarich
cdab726e3d refactor: clean up creation of IR over-application (#9426) 2025-07-18 06:11:06 +00:00
Mac Malone
7b9ead4a1a chore: lake: module system tests & fixes (#9422)
This PR adds Lake tests for builds involving the Lean module system and
fixes some bugs encountered in the process. In particular, it fixes the
parsing of private imports and how Lake handles the `import all` of a
private import.
2025-07-18 02:34:13 +00:00
jrr6
6e191720b3 fix: open error explanations in new window in web editor (#9421)
This PR fixes a bug that caused error explanations to "steal" the
Infoview's container in the Lean web editor.
2025-07-17 23:20:35 +00:00
Sebastian Ullrich
9fc31abb1f chore: benchmark using USE_LAKE (#9361) 2025-07-17 18:44:29 +00:00
Markus Himmel
3878d6da85 chore: Grove: bump version (#9419) 2025-07-17 15:02:17 +00:00
Henrik Böving
097952c48f perf: simp subexpr benchmark (#9404)
This PR adds a simp benchmark to our suite, specifically targeting
caching of subexpression
rewriting results.
2025-07-17 11:53:48 +00:00
Sebastian Ullrich
e5730e9b7e refactor: module-ize remainder of Std (#9195) 2025-07-17 11:43:57 +00:00
Sebastian Ullrich
49546687d9 chore: update stage0 2025-07-17 11:54:06 +02:00
Sebastian Ullrich
2c08280854 fix: meta def should never be exposed (#9415) 2025-07-17 11:52:32 +02:00
Mac Malone
ebe68faf7f fix: lake: test script bugs w/ Mathlib & non-Linux (#9397)
This PR fixes some issues with the Lake tests on Windows and macOS. It
also avoids downloading Mathlib in the `init` test, which was currently
doing this after changes to the `math-lax` template in #8866.

To skip the Mathlib download in `init`, an undocumented `--offline`
option was added`. This option is currently meant for internal use only.
2025-07-17 07:08:00 +00:00
Leonardo de Moura
65abbd90bf perf: isArrowProposition (#9414)
This PR increases the number of cases where `isArrowProposition` returns
a result other than `.undef`. This function is used to implement the
`isProof` predicate, which is invoked on every subterm visited by
`simp`.
2025-07-17 04:12:15 +00:00
jrr6
119854e248 feat: add hints for missing structure instance fields (#9317)
This PR adds to the "fields missing" error message for structure
instance notation a code-action hint that inserts all missing fields.
2025-07-17 03:22:34 +00:00
jrr6
442ef6e64c feat: add case name hints (#9316)
This PR adds clickable code-action hints to the "invalid case name"
error message.
2025-07-17 03:22:30 +00:00
jrr6
fb462fdf9e feat: add named argument hints (#9315)
This PR adds improves the "invalid named argument" error message in
function applications and match patterns by providing clickable hints
with valid argument names. In so doing, it also fixes an issue where
this error message would erroneously flag valid match-pattern argument
names.
2025-07-17 03:22:25 +00:00
Cameron Zwarich
d667522524 refactor: remove special cases for subsingleton casesOn (#9412) 2025-07-16 23:41:41 +00:00
Cameron Zwarich
c1b5d54737 feat: compiler support for casesOn of subsingletons (#9411)
This PR adds support for compilation of `casesOn` for subsingletons. We
rely on the elaborator's type checking to restrict this to inductives in
`Prop` that can actually eliminate into `Type n`. This does not yet
cover other recursors of these types (or of inductives not in `Prop` for
that matter).
2025-07-16 23:07:32 +00:00
Sebastian Ullrich
f94d7b333a fix: do not export private instances (#9407)
Fixes #9383
2025-07-16 18:59:48 +00:00
Leonardo de Moura
d7ef2880c8 perf: avoid "dependent implications" as local E-matching theorems in grind (#9408)
This PR implements a simple optimization: dependent implications are no
longer treated as E-matching theorems in `grind`. In
`grind_bitvec2.lean`, this change saves around 3 seconds, as many
dependent implications are generated. Example:
```lean
 ∀ (h : i + 1 ≤ w), x.abs.getLsbD i = x.abs[i]
 ```
2025-07-16 17:13:52 +00:00
Sebastian Ullrich
f3944a3d49 chore: fix test 2025-07-16 17:51:42 +02:00
Sebastian Ullrich
263a77fa89 chore: update stage0 2025-07-16 16:04:47 +02:00
Sebastian Ullrich
2584b6abf9 fix: assorted module system fixes (#9406)
Encountered when porting `Std` and `Lean`
2025-07-16 13:31:08 +00:00
Markus Himmel
ca9b804163 chore: ci: specify which Linux toolchain Grove should download (#9405)
Since the old version of the workflow will run on PRs, we'll have to
"test" this on master.
2025-07-16 13:15:13 +00:00
Henrik Böving
e9ccdeecd0 perf: add a benchmark for simp on local hypotheses (#9403)
This PR adds a benchmark to our suite, specifically targeting the fact
that local hypotheses
are currently not indexed in simp and can thus cause significant
slowdowns compared to having them
as external declarations.
2025-07-16 12:16:29 +00:00
Sebastian Ullrich
2ed4f39ffe chore: adapt core to preceding syntax change 2025-07-16 13:32:11 +02:00
Sebastian Ullrich
1959e6088b chore: update stage0 2025-07-16 13:32:11 +02:00
Sebastian Ullrich
ffbb21a032 fix: order of @[expose] public section
This PR makes the order of `@[expose] public` at `section` consistent with that at `def`
2025-07-16 13:32:11 +02:00
Sebastian Ullrich
e088549330 refactor: module-ize Std.Time (#9100) 2025-07-16 09:57:53 +00:00
Mac Malone
587979341a refactor: lake: optimize module build code for new compiler (#9400)
This PR splits up `Module.recBuildLean` into smaller functions and
optimizes the implementation of `Module.cacheOutputArtifacts` for the
new compiler. Now, all functions within `Lake.Build.Module` take Lean
<1s to compile.
2025-07-16 07:27:34 +00:00
Mac Malone
180bfeaba4 feat: lake: pre-resolve module imports (#9053)
This PR updates Lake to resolve the `.olean` files for transitive
imports for Lean through the `modules` field of `lean --setup`. This
enables means the Lean can now directly use the `.olean` files from the
Lake cache without needed to locate them at a specific hierarchical
path.

Resolving transitive imports still has a performance penalty, but it is
now much less.
2025-07-16 04:21:31 +00:00
Lean stage0 autoupdater
e6cce355e3 chore: update stage0 2025-07-16 04:26:10 +00:00
Cameron Zwarich
e9b75e34b7 perf: decide whether to use _ref variants of inc/dec using IR types (#9399) 2025-07-16 03:52:58 +00:00
Leonardo de Moura
e286f20179 perf: avoid inferType at simpArith (#9398)
This PR avoids the expensive `inferType` call in `simpArith`. It also
cleans up some of the code and removes anti-patterns.
2025-07-16 03:42:26 +00:00
Lean stage0 autoupdater
d4afa3caaa chore: update stage0 2025-07-16 02:48:16 +00:00
Cameron Zwarich
e069c9eb0e perf: use IR type info to decide whether to insert RC ops (#9396)
This is mostly a refactoring that replaces other analyses with type
information, but due to the introduction of `tagged` it also has the
side effect of eliminating ref counting ops entirely for types that
always have a tagged scalar representation, e.g. `Unit`.
2025-07-16 02:02:32 +00:00
Leonardo de Moura
dc2f256448 fix: bug at mkCongrSimpCore? (#9395)
This PR fixes a bug at `mkCongrSimpCore?`. It fixes the issue reported
by @joehendrix at #9388.
The fix is just commit: afc4ba617f. The
rest of the PR is just cleaning up the file.

closes #9388
2025-07-16 00:54:31 +00:00
Cameron Zwarich
62ded77e81 chore: add a new tagged IRType for inline tagged scalars (#9394) 2025-07-16 00:42:56 +00:00
Cameron Zwarich
466e8a6c5e fix: adjust unsafe trick for upcoming optimization (#9393)
This PR fixes an unsafe trick where a sentinel for a hash table of Exprs
(keyed by pointer) is created by constructing a value whose runtime
representation can never be a valid Expr. The value chosen for this
purpose was Unit.unit, which violates the inference that Expr has no
scalar constructors. Instead, we change this to a freshly allocated Unit
× Unit value.
2025-07-16 00:10:01 +00:00
Cameron Zwarich
b131e8b97f chore: adopt tobject IRType (#9392) 2025-07-15 23:56:49 +00:00
Cameron Zwarich
d7ef2a8d1c refactor: add a CtorFieldInfo.object field for the object type (#9390) 2025-07-15 23:18:23 +00:00
jrr6
3b58a7d36b fix: improve error message when projecting from zero-field type (#9386)
This PR improves a confusing error message that occurred when attempting
to project from a zero-field structure.

Closes #9312
2025-07-15 21:32:59 +00:00
jrr6
e9a318df16 fix: reorder "application type mismatch" message (#9287)
This PR rewords the "application type mismatch" error message so that
the argument and its type precede the application expression.
2025-07-15 19:20:18 +00:00
Leonardo de Moura
166d1c0dab perf: avoid isDefEq test at simpEq simproc used in grind (#9385)
This PR replaces the `isDefEq` test in the `simpEq` simproc used in
`grind`. It is too expensive.
2025-07-15 18:38:11 +00:00
Joachim Breitner
0926d27100 chore: fix benchmark added in #9380 (#9384) 2025-07-15 18:24:34 +00:00
Henrik Böving
aa6f22d102 chore: reduce import closure of MPL (#9382)
This PR reduces the import closure of the monadic verification framework
from `Lean.Meta` to only
the submodules actually required.
2025-07-15 16:36:03 +00:00
Joachim Breitner
6adeab2160 chore: add simple simp benchmark (#9380)
A micro-benchmark for plain, mostly first-order rewriting of simp:

This uses axiom to make it independent of specific optimization (e.g.
for `Nat`).

It generates a “list” of 128 `b`s followed by 128 `a` and uses
bubble-sort to to sort it and compares it against the expected output.
2025-07-15 15:04:49 +00:00
Malhar A. Patel
6cbdd6b815 doc: correct the Option.getD docString example (#9190)
This PR corrects the second example in the `Option.getD` docString

Closes #9189
2025-07-15 12:39:58 +00:00
Henrik Böving
a8c0348300 chore: re-simp Std.LawfulEqCmp.compare_eq_iff_eq (#9377)
This PR readds `simp` annotations accidentally lost in previous PRs
2025-07-15 12:10:50 +00:00
Filippo A. E. Nuccio
08d8bed022 doc: fix a typo in Pairwise doc (#9375)
doc: fix a typo in Pairwise doc

This PR fixes a sentence in the Pairwise doc in List/Basic
2025-07-15 11:39:02 +00:00
Henrik Böving
6e9bc1359d fix: don't delay lake logging when cloning a dependency (#9332)
This PR changes the dependency cloning mechanism in lake so the log
message that lake is cloning a
dependency occurs before it is finished doing so (and instead before it
starts). This has been a
huge source of confusion for users that don't understand why lake seems
to be just stuck for no
reason when setting up a new project, the output now is:
```
λ lake +lean4 new math math
info: downloading mathlib `lean-toolchain` file
info: math: no previous manifest, creating one from scratch
info: leanprover-community/mathlib: cloning https://github.com/leanprover-community/mathlib4
<hang>
info: leanprover-community/mathlib: checking out revision 'cd11c28c6a0d514a41dd7be9a862a9c8815f8599'
```
2025-07-15 09:38:35 +00:00
Cameron Zwarich
aac501a645 refactor: split up mkExpr helper in lowerLet (#9374) 2025-07-15 05:26:21 +00:00
Cameron Zwarich
cf94e1b162 refactor: get the type of a literal from lowerLitValue (#9373)
This will let us have value-dependent types in the future for tracking
tagged/boxed values.
2025-07-15 04:46:47 +00:00
Leonardo de Moura
96e7ab078d fix: performance issue when elaborating match-expressions with many literals (#9372)
This PR fixes a performance issue that occurs when generating equation
lemmas for functions that use match-expressions containing several
literals. This issue was exposed by #9322 and arises from a combination
of factors:

1. Literal values are compiled into a chain of dependent if-then-else
expressions.
2. Dependent if-then-else expressions are significantly more expensive
to simplify than regular ones.
3. The `split` tactic selects a target, splits it, and then invokes
`simp` on the resulting subgoals. Moreover, `simp` traverses the entire
goal bottom-up and does not stop after reaching the target.

This PR addresses the issue by introducing a custom simproc that avoids
recursively simplifying nested if-then-else expressions. It does **not**
alter the user-facing behavior of the `split` tactic because such a
change would be highly disruptive. Instead, the PR adds a new flag,
`backward.split` to control the behavior of the user-facing `split`
tactic. It is currently set to `true`, i.e., the old behavior is still
the default one. In a future PR, we should set this flag to `false` by
default and begin repairing all affected proofs.

closes #9322
2025-07-15 03:52:23 +00:00
Cameron Zwarich
9d33f2ad33 chore: make IR.Arg pattern matching more exhaustive (#9370) 2025-07-14 22:46:40 +00:00
Leonardo de Moura
a4b5eecb8e perf: skip unnecessary preprocessing steps in grind when possible (#9369)
This PR optimizes the `grind` preprocessor by skipping unnecessary steps
when possible.
2025-07-14 22:05:02 +00:00
Cameron Zwarich
f224452971 chore: simplify box/unbox casting logic (#9368) 2025-07-14 21:51:09 +00:00
Sebastian Ullrich
caf815b009 feat: improve infer binder type failure message and range (#8263)
This PR improves the message and range of infer binder type failures.

---------

Co-authored-by: Joseph Rotella <7482866+jrr6@users.noreply.github.com>
2025-07-14 20:19:11 +00:00
Cameron Zwarich
c0079fd9dd perf: allow boxed scalars passed to scalar params to be borrowed (#9360) 2025-07-14 19:58:01 +00:00
Leonardo de Moura
cfb13b1689 perf: add unfoldReducible' using inShareCommon (#9367)
This PR implements a minor optimization to the `grind` preprocessor.
2025-07-14 19:04:04 +00:00
jrr6
105843519c doc: expand elab_as_elim docstring and fix typo (#9359)
This PR adds additional information from a recent Zulip thread to the
docstring for the `elab_as_elim` attribute and fixes the associated
example code.

The Zulip thread can be found
[here](https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/what.20is.20.60elab_as_elim.60/with/505631084).
2025-07-14 17:53:42 +00:00
Sebastian Ullrich
97698bfc38 chore: CI: use faster Windows runners for releases (#9357) 2025-07-14 16:26:22 +00:00
Sebastian Ullrich
7f1869016a chore: CI: do not use large runners for secondary jobs (#9352)
macOS in particular is expensive to use large machines for more than
necessary
2025-07-14 15:00:58 +00:00
Markus Himmel
0931033c72 chore: Grove: add some data (#9354) 2025-07-14 10:22:59 +00:00
Markus Himmel
a7789d863c chore: Grove: update and enable on master (#9353) 2025-07-14 09:21:51 +00:00
Leonardo de Moura
bcc6fb54c2 perf: use inShareCommon to skip preprocessing steps (#9351)
This PR optimizes the `grind` preprocessing steps by skipping steps when
the term is already present in the hash-consing table.
2025-07-14 04:53:49 +00:00
Cameron Zwarich
b04ee0de57 chore: remove outdated comments (#9349) 2025-07-14 01:15:36 +00:00
Cameron Zwarich
7a83adf10d refactor: rename mmodifyBody functions to modifyBodyM (#9348) 2025-07-14 01:01:46 +00:00
Leonardo de Moura
d642880b7d chore: remove leftovers (#9347)
after update stage0
2025-07-14 00:40:32 +00:00
Lean stage0 autoupdater
74206c755f chore: update stage0 2025-07-14 00:11:34 +00:00
Leonardo de Moura
c7b4d843e2 refactor: support for Nat in grind cutsat (#9340)
This PR modifies the encoding from `Nat` to `Int` used in `grind
cutsat`. It is simpler, more extensible, and similar to the generic
`ToInt`. After update stage0, we will be able to delete the leftovers.
2025-07-13 23:40:03 +00:00
Cameron Zwarich
c90cc392f7 fix: populate the xType field of FnBody.case (#9344)
This PR correctly populates the `xType` field of the `IR.FnBody.case`
constructor. It turns out that there is no obvious consequence for this
being incorrect, because it is conservatively recomputed by the `Boxing`
pass.
2025-07-13 21:56:07 +00:00
Leonardo de Moura
f298360ff9 refactor: more "efficient" contraint propagation theorems (#9343)
The certificates perform a single pass over the polynomials.
2025-07-13 19:52:43 +00:00
Leni Aniva
275e483885 refactor: Expose DeclNameGenerator idx (#9020)
This PR exposes the internal of DeclNameGenerator to facilitate merger
of two branches of goal state or proof snapshots.
2025-07-13 10:24:04 +00:00
Cameron Zwarich
e87ce2bd5b refactor: rename "irrelevant" to "erased" in IR (#9339)
This matches the terminology used by LCNF.
2025-07-13 04:51:34 +00:00
Cameron Zwarich
3c6a923f1b refactor: use the usize index in the CtorFieldInfo struct (#9337) 2025-07-13 03:05:13 +00:00
Cameron Zwarich
b25ef7682d chore: fix spacing (#9338) 2025-07-13 03:03:50 +00:00
Cameron Zwarich
71b5bf3ef6 fix: include ._closed decls in trace.Compiler.result output (#9336)
This PR changes the implementation of `trace.Compiler.result` to use the
decls as they are provided rather than looking them up in the LCNF mono
environment extension, which was seemingly done to save the trouble of
re-normalizing fvar IDs before printing the decl. This means that the
`._closed` decls created by the `extractClosed` pass will now be
included in the output, which was definitely confusing before if you
didn't know what was happening.
2025-07-13 02:24:00 +00:00
jrr6
8dfc71c4fd chore: remove superfluous whitespace from error message (#9335)
This PR fixes a typo that caused the "cannot infer resulting universe
level of inductive datatype" error message to have leading whitespace.
2025-07-12 23:04:02 +00:00
Leonardo de Moura
243bbd74a5 chore: compilation time for EMatch.lean (#9334)
This PR improves the compilation time for `EMatch.lean`
2025-07-12 22:01:16 +00:00
Cameron Zwarich
aba49508f1 refactor: port IR Checker to CompilerM (and thus CoreM) (#9331) 2025-07-12 15:25:46 +00:00
Leonardo de Moura
ae2a9b4688 perf: propagateEqUp (#9326)
This PR optimizes `propagateEqUp` used in `grind`.
2025-07-12 03:09:59 +00:00
Leonardo de Moura
d36fc8df67 perf: propagateBoolDiseq (#9325)
This PR optimizes the Boolean disequality propagator used in `grind`.
2025-07-12 02:20:48 +00:00
Leonardo de Moura
6c20cd08f1 perf: isDiseq and mkDiseqProof? in grind (#9324)
This PR improves the functions for checking whether two terms are
disequal in `grind`
2025-07-12 01:26:48 +00:00
Cameron Zwarich
46b04c8405 chore: lower Nat.zero in toMono (#9320)
This currently relies on the encoding pun of Nat.zero as the first
tagged constructor of Nat. Since Nat.succ is lowered to addition, it
makes sense to also lower Nat.zero to a zero literal. This might also
expose more optimization opportunities in the future.
2025-07-11 23:25:05 +00:00
Cameron Zwarich
efc101d3b4 chore: move Nat.succ lowering from toIR to toMono (#9319)
It makes more sense to do it here, since `cases` on `Nat` is also
lowered in `toMono`.
2025-07-11 22:49:41 +00:00
Cameron Zwarich
e2e36087e1 refactor: split noncomputable error into its own helper (#9314) 2025-07-11 17:30:22 +00:00
Cameron Zwarich
d4e11f754a chore: clean up loop over ctor fields (#9313) 2025-07-11 16:46:48 +00:00
Cameron Zwarich
837ea41ede fix: correctly compile irrelevant args to relevant ctor params (#9310)
This PR fixes IR constructor argument lowering to correctly handle an
irrelevant argument being passed for a relevant parameter in all cases.
This happened because constructor argument lowering (incompletely)
reimplemented general LCNF-to-IR argument lowering, and the fix is to
just adopt the generic helper functions. This is probably due to an
incomplete refactoring when the new compiler was still on a branch.
2025-07-11 15:29:12 +00:00
simon-dima
5778a3c0f2 chore: fix "isRuntimeBultinType" typo (#9307) 2025-07-11 12:27:07 +00:00
Lean stage0 autoupdater
668a892cdb chore: update stage0 2025-07-11 08:18:55 +00:00
Leonardo de Moura
0fdb63f258 perf: use mkCongrSimpForConst? (#9305)
This PR uses the `mkCongrSimpForConst?` API in `simp` to reduce the
number of times the same congruence lemma is generated. Before this PR,
`grind` would spend `1.5`s creating congruence theorems during
normalization in the `grind_bitvec2.lean` benchmark. It now spends
`0.6`s. This PR should make an even bigger difference after we merge
#9300.
2025-07-11 02:29:20 +00:00
Sebastian Graf
338456e765 feat: help simp and grind reasoning about Std.Do invariants (#9301)
This PR adds a `simp` and a `grind` annotation on `Zipper`-related
theorems to improve reasoning about `Std.Do` invariants.
2025-07-10 15:44:29 +00:00
Tasiro
18a82c04fc fix: remove BEq from (Array|Vector).(any|all)_push (#9285)
This PR removes the unnecessary requirement of `BEq α` for
`Array.any_push`, `Array.any_push'`, `Array.all_push`, `Array.all_push'`
as well as `Vector.any_push` and `Vector.all_push`.
2025-07-10 06:02:14 +00:00
Leonardo de Moura
4520206f4a chore: minor perf improvement (#9296) 2025-07-10 05:41:54 +00:00
Cameron Zwarich
9ee8e0c896 chore: remove outdated comment (#9294) 2025-07-10 03:29:22 +00:00
Leonardo de Moura
62dc8d64fa perf: use custom reduceCtorEq simproc in grind (#9293)
This PR replaces the `reduceCtorEq` simproc used in `grind` by a much
more efficient one. The default one use in `simp` is just overhead
because the `grind` normalizer is already normalizing arithmetic.
In a separate PR, we will push performance improvements to the default
`reduceCtorEq`.
2025-07-10 03:18:44 +00:00
Cameron Zwarich
7845154a3d refactor: base the IR phase of the compiler on CoreM (#9291) 2025-07-10 01:39:27 +00:00
Cameron Zwarich
66de09bc9c refactor: use getEnv/modifyEnv more in IR (#9290) 2025-07-10 00:01:56 +00:00
Cameron Zwarich
3e37eef9ea refactor: remove unused addBoxedVersion variants (#9289) 2025-07-09 23:44:18 +00:00
Cameron Zwarich
d3a4bb29a7 chore: remove comment indicating that implicit conversion should be removed (#9284) 2025-07-09 17:31:34 +00:00
Cameron Zwarich
1db5e35b59 chore: remove ABI hack for the old compiler (#9283) 2025-07-09 17:25:38 +00:00
Cameron Zwarich
efe5e9a752 refactor: remove unnecessary export attributes (#9281) 2025-07-09 16:55:00 +00:00
Cameron Zwarich
a4f38cc782 refactor: remove code marked for deletion after old compiler (#9280) 2025-07-09 15:30:11 +00:00
Cameron Zwarich
b579c5c7d8 fix: make compiler.extract_closed option work again after migration (#9279)
This PR fixes the `compiler.extract_closed` option after migrating it to
Lean (and adds a test so it would be caught in the future).
2025-07-09 14:31:58 +00:00
Cameron Zwarich
575adbae18 chore: remove now-unused Lean.Compiler.AtMostOnce (#9278) 2025-07-09 14:31:15 +00:00
Cameron Zwarich
5e19c47710 chore: remove now-unused Lean.Compiler.ConstFolding (#9277) 2025-07-09 14:18:32 +00:00
Cameron Zwarich
a7675ad4b2 chore: remove unnecessary export attributes in IR code (#9276) 2025-07-09 14:18:07 +00:00
Cameron Zwarich
d2e604f74d feat: remove the old compiler (#9275)
This PR removes the old compiler written in C++.
2025-07-09 06:00:46 +00:00
Chase Johnson
4c93ab7602 fix: typos in ISO 8601 formatted datetime (#9235) (#9263)
This PR fixes `toISO8601String` to produce a string that conforms to the
ISO 8601 format specification. The previous implementation separated the
minutes and seconds fragments with a `.` instead of a `:` and included
timezone offsets without the hour and minute fragments separated by a
`:`.

Closes #9235
2025-07-09 05:52:25 +00:00
Cameron Zwarich
625de14b23 chore: remove options from 'run' tests that are now meaningless (#9274) 2025-07-09 05:26:58 +00:00
Cameron Zwarich
b13b916b7e chore: move compiler.ir trace class registration to Lean (#9273) 2025-07-09 05:15:38 +00:00
Cameron Zwarich
9f2b796639 chore: move compiler.extract_closed option from C++ to Lean (#9272) 2025-07-09 04:36:16 +00:00
Leonardo de Moura
4955dde748 perf: grind normalizer (#9271)
This PR improves the performance of the formula normalizer used in
`grind`.
2025-07-09 03:49:44 +00:00
Cameron Zwarich
3b18ae2209 chore: move llvm.cpp from library/compiler to library (#9270) 2025-07-09 02:13:08 +00:00
Cameron Zwarich
9620cb1b90 chore: have shell.cpp use library/util.h rather than library/compiler… (#9269) 2025-07-09 01:41:04 +00:00
Cameron Zwarich
d664b6b888 fix: move lean_add_extern implementation to Lean (#9268)
This PR moves the implementation of `lean_add_extern`/`addExtern` from
C++ into Lean. I believe is the last C++ helper function from the
library/compiler directory being relied upon by the new compiler. I put
it into its own file and duplicated some code because this function
needs to execute in CoreM, whereas the other IR functions live in their
own monad stack. After the C++ compiler is removed, we can move the IR
functions into CoreM.
2025-07-09 00:02:56 +00:00
Leonardo de Moura
192c0c8e67 perf: skip canonicalization of Decidable instances and add congruence-closure support (#9267)
This PR optimizes support for `Decidable` instances in `grind`. Because
`Decidable` is a subsingleton, the canonicalizer no longer wastes time
normalizing such instances, a significant performance bottleneck in
benchmarks like `grind_bitvec2.lean`. In addition, the
congruence-closure module now handles `Decidable` instances, and can
solve examples such as:
```lean
example (p q : Prop) (h₁ : Decidable p) (h₂ : Decidable (p ∧ q)) : (p ↔ q) → h₁ ≍ h₂ := by
  grind
```
2025-07-08 21:55:40 +00:00
Cameron Zwarich
cec0c82f1c fix: support .mdata in LCNF mono types (#9266)
This PR adds support for `.mdata` in LCNF mono types (and then drops it
at the IR type level instead). This better matches the behavior of
extern decls in the C++ code of the old compiler, which is still being
used to create extern decls at the moment and will soon be replaced.

This is covered by existing tests.
2025-07-08 21:35:30 +00:00
Cameron Zwarich
4ff4ed88bc chore: move the IR interpreter from library/compiler to library (#9265) 2025-07-08 20:45:55 +00:00
Cameron Zwarich
a05311d1ec chore: split IR types out into their own header file (#9264) 2025-07-08 19:49:27 +00:00
Cameron Zwarich
f675ee2062 chore: remove unnecessary include of ir_interpreter.h (#9262) 2025-07-08 18:09:20 +00:00
Cameron Zwarich
cb127b42ac chore: rename compileDeclsNew to compileDeclsImpl (#9261) 2025-07-08 17:55:11 +00:00
Cameron Zwarich
c7c5de38b3 chore: clean up getDeclNamesForCodeGen (#9259) 2025-07-08 17:00:46 +00:00
Cameron Zwarich
6ad12525ad chore: make compileDecls and friends take an Array rather than a List (#9257) 2025-07-08 16:18:44 +00:00
Cameron Zwarich
bb5df157bc chore: remove unused optional parameter from compileDecls (#9255) 2025-07-08 15:31:06 +00:00
Sebastian Graf
77442f5486 chore: revert DefEq changes until it has passed proper review (#9254) 2025-07-08 14:54:18 +00:00
Hagb (Junyu Guo 郭俊余)
97aca690d0 fix: walk through types of axioms in collectAxioms (#8842)
This PR fixes the bug that `collectAxioms` didn't collect axioms
referenced by other axioms. One of the results of this bug is that
axioms collected from a theorem proved by `native_decide` may not
include `Lean.trustCompiler`.

Closes #8840.
2025-07-08 14:42:11 +00:00
Cameron Zwarich
173629ebd5 chore: remove compiler.enableNew option (#9252) 2025-07-08 14:17:05 +00:00
Cameron Zwarich
beeeead99f chore: remove mentions of the compiler being new from trace messages (#9253) 2025-07-08 14:15:15 +00:00
Lean stage0 autoupdater
d38c36001d chore: update stage0 2025-07-08 14:35:54 +00:00
Sebastian Graf
7386cc3b12 chore: Turn Std.Do.Triple elaborator into a macro (#9251)
This PR demotes the builtin elaborators for `Std.Do.PostCond.total` and
`Std.Do.Triple` into macros, following the DefEq improvements of #9015.

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-07-08 13:57:22 +00:00
Henrik Böving
7958e01b1c perf: basic micro benchmarks for Std.Data.TreeMap (#9250)
This PR adds micro-benchmarks for `Std.Data.TreeMap` in the same style
as for the hashmap.
2025-07-08 13:55:13 +00:00
Lean stage0 autoupdater
47e8483b38 chore: update stage0 2025-07-08 13:35:02 +00:00
Sebastian Graf
0b2bdaebd6 fix: More stuck definitional equalities involving smart unfoldings (#8766) (#9015)
This PR makes `isDefEq` detect more stuck definitional equalities
involving smart unfoldings. Specifically, if `t =?= defn ?m` and `defn`
matches on its argument, then this equality is stuck on `?m`. Prior to
this change, we would not see this dependency and simply return `false`.

Fixes #8766.

Co-authored-by: Kyle Miller <kmill31415@gmail.com>
2025-07-08 12:56:50 +00:00
Kyle Miller
ac600853c0 fix: let the congr tactic handle "under-applied" applications (#9225)
This PR improves the `congr` tactic so that it can handle function
applications with fewer arguments than the arity of the head function.
This also fixes a bug where `congr` could not make progress with
`Set`-valued functions in Mathlib, since `Set` was being unfolded and
making such functions have an apparently higher arity.

This addresses issue #2128 for the `congr` tactic, but not `simp` and
others.
2025-07-08 11:48:08 +00:00
Luisa Cicolini
77a0c2bf9b feat: add BitVec.clzAuxRec_eq_clzAuxRec_of_getLsbD_false (#9249)
This PR adds theorem `BitVec.clzAuxRec_eq_clzAuxRec_of_getLsbD_false` as
a more general statement than `BitVec.clzAuxRec_eq_clzAuxRec_of_le`,
replacing the latter in the bitblaster too.
2025-07-08 10:40:40 +00:00
Henrik Böving
46c43c3ecb perf: first set of HashMap benchmarks (#9233)
This PR adds basic microbenchmarks for `Std.Data.HashMap`
2025-07-08 08:11:52 +00:00
Cameron Zwarich
6de68dd8ef chore: remove compiler.enableNew=true from a test and rename it (#9247) 2025-07-08 05:49:57 +00:00
Cameron Zwarich
97fd75c660 chore: remove redundancy in toMono trivial structure check (#9245) 2025-07-08 05:07:16 +00:00
Leonardo de Moura
cf6a182f69 chore: profile grind satellite solvers (#9246) 2025-07-08 05:05:39 +00:00
Leonardo de Moura
655c7ab548 perf: optimize instance generation in grind linarith (#9244)
This PR improves the instance generation in the `grind linarith` module.
2025-07-08 05:04:06 +00:00
Cameron Zwarich
70368ed1a5 chore: reduce rightward drift (#9243) 2025-07-08 03:41:37 +00:00
Cameron Zwarich
765f98770b chore: improve pattern matching (#9242) 2025-07-08 03:36:34 +00:00
Leonardo de Moura
05630fc149 perf: synthesize ToInt instances on demand (#9241)
This PR ensures that the type class instances used to implement the
`ToInt` adapter (in `grind cutsat`) are generated on demand.
2025-07-08 02:36:16 +00:00
Cameron Zwarich
2d173615ba chore: remove unreachable branches (#9240)
There is a global `tryIrDecl?` check above all of this code.
2025-07-08 00:16:12 +00:00
Cameron Zwarich
b2920d6410 chore: consolidate noncomputable diagnostics (#9239) 2025-07-07 23:39:49 +00:00
Leonardo de Moura
aee2da809a chore: test for issue #9216 (#9238)
This PR adds a new test with the analysis for issue #9216.
2025-07-07 23:25:25 +00:00
Leonardo de Moura
2bf9130b63 chore: tests for #9206 (#9237)
Add examples in issue #9206 and Zulip thread as tests for `grind`.
2025-07-07 23:01:38 +00:00
Sebastian Graf
67d9d9d936 chore: Update CODEOWNERS (#9232)
Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-07-07 13:11:41 +00:00
Sebastian Graf
0c5946ab3f feat: Make Std.Do universe polymorphic (#9194)
This PR makes the logic and tactics of `Std.Do` universe polymorphic, at
the cost of a few definitional properties arising from the switch from
`Prop` to `ULift Prop` in the base case `SPred []`.

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-07-07 13:11:41 +00:00
Paul Reichert
98e4b2882f refactor: migrate to new ranges (#8841)
This PR migrates usages of `Std.Range` to the new polymorphic ranges.

This PR unfortunately increases the transitive imports for
frequently-used parts of `Init` because the ranges now rely on iterators
in order to provide their functionality for types other than `Nat`.
However, iteration over ranges in compiled code is as efficient as
before in the examples I checked. This is because of a special
`IteratorLoop` implementation provided in the PR for this purpose.

There were two issues that were uncovered during migration:

* In `IndPredBelow.lean`, migrating the last remaining range causes
`compilerTest1.lean` to break. I have minimized the issue and came to
the conclusion it's a compiler bug. Therefore, I have not replaced said
old range usage yet (see #9186).
* In `BRecOn.lean`, we are publicly importing the ranges. Making this
import private should theoretically work, but there seems to be a
problem with the module system, causing the build to panic later in
`Init.Data.Grind.Poly` (see #9185).
* In `FuzzyMatching.lean`, inlining fails with the new ranges, which
would have led to significant slowdown. Therefore, I have not migrated
this file either.
2025-07-07 12:41:53 +00:00
Henrik Böving
6e98dfbc64 perf: bv_decide rewriting benchmark (#9231)
This PR adds a benchmark for the rewriting engine of bv_decide, based on
a problem extracted from
SMT-LIB. Note that this problem has significant elaboration time itself
due to its sheer size though
the overall execution time is split approximately 50:50 between
elaboration and rewriting.
2025-07-07 10:24:08 +00:00
Cameron Zwarich
e7e4119cf4 chore: move handling of Quot.{mk, lcInv} from toIR to toMono (#9230) 2025-07-07 05:11:23 +00:00
Cameron Zwarich
6cf8828ce7 chore: remove unused code in the axiom path of toIR (#9229)
This must have been the result of an earlier refactoring, since there
are no axioms with IR decls.
2025-07-07 03:45:39 +00:00
Leonardo de Moura
5d46391dde perf: generate grind ring instances on demand (#9228)
This PR improves the startup time for `grind ring` by generating the
required type classes on demand. This optimization is particularly
relevant for files that make hundreds of calls to `grind`, such as
`tests/lean/run/grind_bitvec2.lean`. For example, before this change,
`grind` spent 6.87 seconds synthesizing type classes, compared to 3.92
seconds after this PR.
2025-07-07 03:29:42 +00:00
Cameron Zwarich
c9debdaf2a chore: move lcUnreachable handling from toIR to toLCNF (#9227)
We can probably remove `lcUnreachable` once we delete the old compiler,
but for now it makes more sense to move it earlier, since LCNF already
has `Code.unreachable`.
2025-07-07 02:17:30 +00:00
Cameron Zwarich
9b7a14b156 fix: erase args for erased app params in toMono (#9224)
This PR changes the `toMono` pass to consider the type of an application
and erase all arguments corresponding to erased params. This enables a
lightweight form of relevance analysis by changing the mono type of a
decl. I would have liked to unify this with the behavior for
constructors, but my attempt to give constructors the same behavior in
#9222 (which was in preparation for this PR) had a minor performance
regression that is really incidental to the change. Still, I decided to
hold off on it for the time being. In the future, we can hopefully
extend this to constructors, extern decls, etc.
2025-07-06 23:27:48 +00:00
Cameron Zwarich
ff5d96096a chore: use Array instead of PArray in elimDeadBranches state (#9220)
This is alway used linearly.
2025-07-06 21:31:47 +00:00
Cameron Zwarich
53d4139cf1 chore: revert #9218 (#9223)
I thought I understood why the the minor !bench performance regression
was spurious, but now I'm not so sure.
2025-07-06 15:33:10 +00:00
Cameron Zwarich
c1f1287e24 fix: delete code with false assumption that LCNF local vars can occur in types (#9221)
This PR removes code that has the false assumption that LCNF local vars
can occur in types. There are other comments in `ElimDead.lean`
asserting that this is not possible, so this must have been a change
early in the development of the new compiler.
2025-07-06 15:04:13 +00:00
Cameron Zwarich
4322a0c7d3 fix: make LCNF elimDeadBranches more optimistic on unsafe decls (#9218)
This PR makes the LCNF `elimDeadBranches` pass handle unsafe decls a bit
more carefully. Now the result of an unsafe decl will only become ⊤ if
there is value flow from a recursive call.
2025-07-06 13:28:07 +00:00
Cameron Zwarich
d0e097cd1d chore: remove IRType.{isStruct,isUnion} (#9219)
These are used by the checker for `.ctor`, but I don't think that that
unboxed types will reuse `.ctor`, whose implementation details are
intimately connected to our runtime representation of objects.
2025-07-06 13:24:24 +00:00
Cameron Zwarich
bd7e6c3c61 chore: use ``-prefixed Names when possible (#9217) 2025-07-06 12:58:13 +00:00
Leonardo de Moura
1443982924 perf: restore cache at withoutModifyingMCtx (#9215)
instead of resetting it.
2025-07-06 04:18:37 +00:00
Leonardo de Moura
15586e28a8 feat: local and scoped grind_pattern (#9214)
This PR implements support for local and scoped `grind_pattern`
commands.
2025-07-05 20:36:56 -07:00
Cameron Zwarich
6f5fdf5c3e chore: adopt do notation in IR checker (#9213)
I plan to make some changes here in the future, so I figured it would be
good to make it a bit more idiomatic first.
2025-07-06 02:39:03 +00:00
Eric Wieser
bd06e07624 fix: make the name in dependsOnNoncomputable clickable (#9207)
This PR makes the offending declaration clickable in the error message
produced when something should be marked `noncomputable`.
2025-07-05 21:28:35 +00:00
Leonardo de Moura
2cf6c2ddc9 feat: track type class inference time in grind (#9211) 2025-07-05 20:24:32 +00:00
Cameron Zwarich
38d4dc7058 chore: add deriving Repr to IR.Arg (#9210)
This is helpful when debugging.
2025-07-05 19:57:41 +00:00
Cameron Zwarich
149fc2173c fix: correctly handle constructor params in elimDeadBranches (#9209)
This PR changes the `getLiteral` helper function of `elimDeadBranches`
to correctly handle inductives with constructors. This function is not
used as often as it could be, which makes this issue rare to hit outside
of targeted test cases.
2025-07-05 19:52:12 +00:00
Leonardo de Moura
12536d2015 chore: remove old grind normalizers (#9205) 2025-07-05 06:19:34 +00:00
Cameron Zwarich
36c036d952 chore: replace custom instances with deriving for IR types (#9204) 2025-07-05 05:43:07 +00:00
Lean stage0 autoupdater
bebffc0d20 chore: update stage0 2025-07-05 05:51:10 +00:00
Leonardo de Moura
dd7bc0e643 perf: simproc for grind normalizations and decls to unfold (#9202)
This PR extends the `Eq` simproc used in `grind`. It covers more cases
now. It also adds 3 reducible declarations to the list of declarations
to unfold.
2025-07-05 05:13:49 +00:00
Cameron Zwarich
264aac4a33 chore: convert local functions to use where instead (#9203) 2025-07-05 05:10:55 +00:00
Leonardo de Moura
d981a2a9a8 chore: remove old normalizers (#9201) 2025-07-05 02:43:00 +00:00
Lean stage0 autoupdater
2ca6c3bf4d chore: update stage0 2025-07-05 02:09:15 +00:00
Leonardo de Moura
722ab706c8 perf: normalize exists expressions using a simproc in grind (#9200)
This PR implements `exists` normalization using a simproc instead of
rewriting rules in grind. This is the first part of the PR, after update
stage0, we must remove the normalization theorems.
2025-07-05 01:37:36 +00:00
Lean stage0 autoupdater
9697c7264d chore: update stage0 2025-07-05 01:13:38 +00:00
Leonardo de Moura
01b0c3e0cc perf: unfold GT.gt and GE.ge in the grind normalizer (#9199) 2025-07-05 00:41:43 +00:00
Cameron Zwarich
37cffbda51 fix: consider Prop-rebundled higher-order params to be fixed (#9198)
This PR changes the compiler's specialization analysis to consider
higher-order params that are rebundled in a way that only changes their
`Prop` arguments to be fixed. This means that they get specialized with
a mere `@[specialize]`, rather than the compiler having to opt-in to
more aggressive parameter-specific specialization.
2025-07-05 00:02:24 +00:00
Leonardo de Moura
f5e47480f2 chore: #9196 part 2 (#9197)
#9196 part 2 after update stage0
2025-07-04 23:27:00 +00:00
Lean stage0 autoupdater
66ffd8d5c2 chore: update stage0 2025-07-04 21:12:35 +00:00
Leonardo de Moura
162e81af57 perf: normalize forall expressions using a simproc in grind (#9196)
This PR implements `forall` normalization using a simproc instead of
rewriting rules in `grind`. This is the first part of the PR, after
update stage0, we must remove the normalization theorems.
2025-07-04 20:41:02 +00:00
Leonardo de Moura
2bf4192ab7 fix: unexpected kernel projection issue in grind (#9193)
This PR fixes the unexpected kernel projection issue reported by issue
#9187

closes #9187
2025-07-04 17:17:40 +00:00
Lean stage0 autoupdater
106d50e46c chore: update stage0 2025-07-04 13:05:44 +00:00
Sebastian Graf
d89f336db2 fix: Scope PostCond.total to Std.Do by making it non-builtin (#9184)
This PR fixes stealing of `⇓` syntax by the new notation for total
postconditions by demoting it to non-builtin syntax and scoping it to
`Std.Do`.

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-07-04 12:33:45 +00:00
Leonardo de Moura
e9a55bfff7 chore: move test to run (#9183) 2025-07-04 00:33:39 +00:00
Leonardo de Moura
55d5ace68e feat: pattern inference using symbol priorities in grind (#9182)
This PR tries to improve the E-matching pattern inference for `grind`.
That said, we still need better tools for annotating and maintaining
`grind` annotations in libraries.

closes #9125
2025-07-03 16:47:38 -07:00
Sebastian Ullrich
357b5f9ed8 chore: CI: restore cache in update-stage0 (#9179)
Avoid rebuilding stage 0 all the time
2025-07-03 20:55:14 +00:00
Cameron Zwarich
b1e5ecc582 chore: add a #guard_msgs to tests/lean/run/instanceUsingFalse.lean (#9180)
This test originally failed by hitting unreachable code, which is caught
by the test harness, but it's probably good to also check the result.
2025-07-03 20:42:12 +00:00
Paul Reichert
cd445dce76 refactor: replace some Subarray functions with generic slice functions (#9017)
This PR removes the `Subarray`-specific `toArray`, `foldlM` and `foldl`
methods and instead provides these operations on `Std.Slice`, which are
implemented with the `ToIterator` instance of the slice. Calling
`subarray.toArray` etc. still works, since `Subarray` is an abbreviation
for `Slice _`.

Because the benchmarks are not so clear, to be safe, I will merge this
only after the release. In contrast to the ranges, the iteration over
slices is not quite as efficient as the old `Subarray`-specific
implementation, which would require either more optimizations in the
iterator library (special `IteratorLoop` and `IteratorCollect`
implementations) or better unboxing support by the compiler.
2025-07-03 19:33:19 +00:00
Cameron Zwarich
501993eb7f fix: don't pull instances depending on erased propositions (#9177)
This PR makes the `pullInstances` pass avoid pulling any instance
expressions containing erased propositions, because we don't correctly
represent the dependencies that remain after erasure.
2025-07-03 19:17:25 +00:00
Mac Malone
9ed51959ef refactor: ignore the setup-file header in the server for now (#9163)
This PR disables the use of the header produced by `lake setup-file` in
the server for now. It will be re-enabled once Lake takes into account
the header given by the server when processing workspace modules.
Without that, `setup-file` header can produce odd behavior when the file
on disk and in an editor disagree on whether the file participates in
the module system.
2025-07-03 17:58:07 +00:00
Eric Wieser
0106ca3bec fix: undefined symbol without LEAN_USE_GMP (#9106)
This PR fixes `undefined symbol: lean::mpz::divexact(lean::mpz const&,
lean::mpz const&)` when building without `LEAN_USE_GMP`

This fixes a regression in #8089
2025-07-03 16:50:21 +00:00
Sebastian Ullrich
ba7135d73c fix: exposed wellfounded recursion (#9173)
This PR fixes an incompatibility in the experimental module system when
trying to combine wellfounded recursion with public exposed definitions.
2025-07-03 16:48:15 +00:00
Joachim Breitner
47b795a302 chore: CI: run stage0 update on faster runner (#9178)
To avoid it losing races against the merge queue.
2025-07-03 16:14:46 +00:00
Lean stage0 autoupdater
0b6df7d6a4 chore: update stage0 2025-07-03 16:14:28 +00:00
Sebastian Graf
c6689584ea fix: split ifs in mvcgen rather than relying on a spec (#9176)
This PR makes `mvcgen` split ifs rather than applying specifications.
Doing so fixes a bug reported by Rish.

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-07-03 14:29:17 +00:00
grunweg
a7c982204e doc: use modern configuration syntax in the Simp.Config documentation (#9174)
The new config syntax is preferred for new code: change the
documentation to use it.

This was [discussed on
zulip](https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/Using.20config.20vs.20optConfig.20in.20language.20documentation/with/526948836).
2025-07-03 14:16:37 +00:00
François G. Dorais
77d79f705f fix: typos in Std.Classes.Ord.Basic (#9145)
This PR fixes two typos.
2025-07-03 12:04:25 +00:00
Leonardo de Moura
ff130a25a2 fix: bug at matchEqBwdPat (#9172)
This PR fixes a bug at `matchEqBwdPat`. The type may contain pattern
variables.
2025-07-03 07:05:01 +00:00
Kim Morrison
c06af84d9f fix: refactor grind's module/ring design to avoid a diamond (#9168)
This PR resolves a defeq diamond, which caused a problem in Mathlib:
```
import Mathlib

example (R : Type) [I : Ring R] :
  @AddCommGroup.toGrindIntModule R (@Ring.toAddCommGroup R I) =
    @Lean.Grind.Ring.instIntModule R (@Ring.toGrindRing R I) := rfl -- fails
```
2025-07-03 06:50:46 +00:00
Leonardo de Moura
5f818826d1 feat: add [grind symbol <prio>] attribute (#9169)
This PR adds the attribute `[grind symbol <prio>]`. This is just the
first part of the PR.
2025-07-03 06:06:55 +00:00
Cameron Zwarich
c8ab8f45aa chore: share duplicated code for enum scalar representation (#9170) 2025-07-03 05:33:35 +00:00
Mac Malone
6f85e32501 fix: lake: recreate static archives & use T, not --thin (#9165)
This PR fixes two issues with Lake's process of creating static
archives.

Lake now always recreates static archives by first deleting any existing
one and then recreating it. `ar rcs` does not remove delete files, so
running it when the archive already exists can leave behind "ghost"
symbols of removed object files.

Second, Lake now use `T` rather than `--thin` to create thin archives.
While `--thin` is the recommended spelling, older versions of LLVM `ar`
do not support it. Thus, either choice produces tradeoffs. `T` is chosen
to make Lake consistent with the Lean core's own (Make) build scripts.
2025-07-03 03:33:10 +00:00
Cameron Zwarich
174b1301d8 chore: remove VarInfo defaults in IR RC pass (#9167)
These defaults don't make the code easier to understand.
2025-07-03 03:15:07 +00:00
Cameron Zwarich
01d32aa408 chore: add test for #9156 after stage0 update (#9166)
Fixes #9156.
2025-07-03 02:06:21 +00:00
Lean stage0 autoupdater
c832577470 chore: update stage0 2025-07-03 01:40:52 +00:00
Cameron Zwarich
cc7c9b48a0 fix: don't inline computed fields _override implementations in base phase (#9159)
This PR enforces the non-inlining of _override impls in the base phase
of LCNF compilation. The current situation allows for constructor/cases
mismatches to be exposed to the simplifier, which triggers an assertion
failure. The reason this didn't show up sooner for Expr is that Expr has
a custom extern implementation of its computed field getter.

Fixes #9156.
2025-07-03 00:26:01 +00:00
Cameron Zwarich
2b788b1a62 chore: make tests/lean/run/2291.lean less sensitive (#9164)
This test was originally checked in for a panic in the pretty printer,
but at some point the output of every LCNF simp pass was added to
#guard_msgs output. Since this is printing LCNF built by the stage0
compiler, this causes a lot of unnecessary churn.
2025-07-02 23:27:06 +00:00
Mac Malone
2e8102424f refactor: lake: use r for ir key in content hashes (#9162)
This PR changes the key Lake uses for the `,ir` artifact in the content
hash data structure to `r`, maintaining the convention of single
character key names.
2025-07-02 22:59:13 +00:00
Rob23oba
a0bb5f4961 chore: fixes for #9158 after stage0 update (#9161) 2025-07-02 18:46:21 +00:00
Lean stage0 autoupdater
921d252253 chore: update stage0 2025-07-02 18:26:42 +00:00
Rob23oba
3ede96accc fix: use patternIgnore(...) in grind syntax (#9158)
This PR fixes the syntax of `grind` modifiers to use `patternIgnore` for
cases where both unicode and ascii variants are matched. This fixes an
issue where several variants of grind syntax weren't accepted (e.g.
`@[grind ← gen]`). Additionally, this reduces the chance that we get
another syntax matching bootstrap hell.
2025-07-02 17:14:21 +00:00
Rob23oba
7aca460c11 fix: add groups around simpLemma and grindLemma syntax (#9157)
This PR wraps `simpLemma` and `grindLemma` in `ppGroup` to make sure
that the modifiers aren't printed separately from the term / identifier.
Example:
```
simp only [very_long_lemma_oh_no_can_you_please_stop_we're_getting_to_the_limit, ←
  wait_this_is_rewritten_backwards_oh_uhh_where's_the_arrow_you_ask?_oh_wait_it's_up_there!]
==>
simp only [very_long_lemma_oh_no_can_you_please_stop_we're_getting_to_the_limit,
  ← wait_this_is_rewritten_backwards_and_wow_it's_very_clear_and_obvious]
```
2025-07-02 15:11:51 +00:00
Cameron Zwarich
8954354216 fix: tighten IR typing rules for applications of closures (#9154)
This PR tightens the IR typing rules around applications of closures.
When re-reading some code, I realized that the code in `mkPartialApp`
has a clear typo—`.object` and `type` should be swapped. However, it
doesn't matter, because later IR passes smooth out the mismatch here. It
makes more sense to be strict up-front and require applications of
closures to always return an `.object`.
2025-07-02 14:06:24 +00:00
Joachim Breitner
977ae92e43 fix: module system: remove WellFounded-specific hacks (#9143)
This PR removes a rather ugly hack in the module system, exposing the
bodies of theorems whose type mention `WellFounded`.

The original motivation was that reducing well-founded definitions (e.g.
in `by rfl`) requires reducing proofs, so they need to be available.

But reducing proofs is generally fraught with peril, and we have been
nudging our users away from using it for a while, e.g. in #5182. Since
the module system is opt-in and users will gradually migrate to it, it
may be reasonable to expect them to avoid reducing well-founded
recursion in the process

This way we don't need hacks like this (which, without evidence, I
believe would be incomplete anyways) and we get the nice guarantee that
within the module system, theorems bodies are always private.
2025-07-02 11:58:50 +00:00
Sebastian Ullrich
2f162005b8 refactor: module-ize Std.Data.DHashMap (#9098) 2025-07-02 10:00:17 +00:00
Paul Reichert
84cd2c49eb feat: remove unnecessary decidability requirements (#9096)
This PR removes some unnecessary `Decidable*` instance arguments by
using lemmas in the `Classical` namespace instead of the `Decidable`
namespace.

This might lead to some additional dependency on classical axioms, but
large parts of the standard library are relying on them either way.
2025-07-02 06:20:50 +00:00
Paul Reichert
561f347f5a feat: universe-polymorphic loop operations on pure iterators (#9135)
This PR allows the result type of `forIn`, `foldM` and `fold` on pure
iterators (`Iter`) to be in a different universe than the iterators.
2025-07-02 06:18:20 +00:00
Leonardo de Moura
a4a3a3b596 feat: improve linarith markVars (#9153)
This PR improves the linarith `markVars`, and ensures it does not
produce spurious issue messages.
2025-07-02 05:05:10 +00:00
David Thrane Christiansen
8c0cff83bd doc: update obsolete docstring for registerDerivingHandler (#9152)
This PR fixes an obsolete docstring for `registerDerivingHandler`
2025-07-02 04:03:00 +00:00
Leonardo de Moura
094dd588d6 chore: simproc and helper theorems for grind (#9151) 2025-07-02 03:57:12 +00:00
Rob23oba
e6954b7837 fix: revert state on compilation failure (new compiler) (#8691)
This PR ensures that the state is reverted when compilation using the
new compiler fails. This is especially important for noncomputable
sections where the compiler might generate half-compiled functions which
may then be erroneously used while compiling other functions.
2025-07-02 03:42:00 +00:00
Leonardo de Moura
4a539715c8 fix: missing case at CommRing.toPoly (#9150)
This PR adds a missing case in the `toPoly` function used in `grind`.
2025-07-02 02:53:48 +00:00
Leonardo de Moura
2b1b2ed45c feat: pow_add for any semirings in grind (#9149)
This PR generalizes the `a^(m+n)` grind normalizer to any semirings.
Example:
```
variable [Field R]

example (M : R) (h₀ : M ≠ 0) {n : Nat} (hn : n > 0) : M ^ n / M = M ^ (n - 1) := by
  cases n <;> grind
```
2025-07-02 01:43:35 +00:00
Leonardo de Moura
b67fb4fa66 feat: polynomial operations with deep recursion and heartbeat checks (#9146)
This PR adds "safe" polynomial operations to `grind ring`. The use the
usual combinators: `withIncRecDepth` and `checkSystem`.
2025-07-02 00:05:28 +00:00
Cameron Zwarich
2864efb222 feat: support enums modulo irrelevance (#9144)
This PR adds support for representing more inductive as enums,
summarized up as extending support to those that fail to be enums
because of parameters or irrelevant fields. While this is nice to have,
it is actually motivated by correctness of a future desired
optimization. The existing type representation is unsound if we
implement `object`/`tobject` distinction between values guaranteed to be
an object pointer and those that may also be a tagged scalar. In
particular, types like the ones added in this PR's tests would have all
of their constructors encoded via tagged values, but under the natural
extension of the existing rules of type representation they would be
considered `object` rather than `tobject`.
2025-07-01 22:35:50 +00:00
Cameron Zwarich
f91d6ce16f chore: cache IR types of named types (#9140)
This PR converts the `lowerEnumToScalarType?` cache to a cache of IR
types of named types. This is more sensible than just focusing on the
enum optimization, and due to uniform representation of polymorphism we
have to compile `Constant T1` and `Constant T2` to the same
representation.
2025-07-01 21:39:05 +00:00
dependabot[bot]
8e5dfb0fd1 chore: CI: bump softprops/action-gh-release from 2.2.2 to 2.3.2 (#9139)
Bumps
[softprops/action-gh-release](https://github.com/softprops/action-gh-release)
from 2.2.2 to 2.3.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/softprops/action-gh-release/releases">softprops/action-gh-release's
releases</a>.</em></p>
<blockquote>
<h2>v2.3.2</h2>
<ul>
<li>fix: revert fs <code>readableWebStream</code> change</li>
</ul>
<h2>v2.3.1</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix: fix file closing issue by <a
href="https://github.com/WailGree"><code>@​WailGree</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/629">softprops/action-gh-release#629</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/WailGree"><code>@​WailGree</code></a>
made their first contribution in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/629">softprops/action-gh-release#629</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/softprops/action-gh-release/compare/v2.3.0...v2.3.1">https://github.com/softprops/action-gh-release/compare/v2.3.0...v2.3.1</a></p>
<h2>v2.3.0</h2>
<!-- raw HTML omitted -->
<ul>
<li>Migrate from jest to vitest</li>
<li>Replace <code>mime</code> with <code>mime-types</code></li>
<li>Bump to use node 24</li>
<li>Dependency updates</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/softprops/action-gh-release/compare/v2.2.2...v2.3.0">https://github.com/softprops/action-gh-release/compare/v2.2.2...v2.3.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md">softprops/action-gh-release's
changelog</a>.</em></p>
<blockquote>
<h2>2.3.2</h2>
<ul>
<li>fix: revert fs <code>readableWebStream</code> change</li>
</ul>
<h2>2.3.1</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix: fix file closing issue by <a
href="https://github.com/WailGree"><code>@​WailGree</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/629">softprops/action-gh-release#629</a></li>
</ul>
<h2>2.3.0</h2>
<ul>
<li>Migrate from jest to vitest</li>
<li>Replace <code>mime</code> with <code>mime-types</code></li>
<li>Bump to use node 24</li>
<li>Dependency updates</li>
</ul>
<h2>2.2.2</h2>
<h2>What's Changed</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix: updating release draft status from true to false by <a
href="https://github.com/galargh"><code>@​galargh</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/316">softprops/action-gh-release#316</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>chore: simplify ref_type test by <a
href="https://github.com/steinybot"><code>@​steinybot</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/598">softprops/action-gh-release#598</a></li>
<li>fix(docs): clarify the default for tag_name by <a
href="https://github.com/muzimuzhi"><code>@​muzimuzhi</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/599">softprops/action-gh-release#599</a></li>
<li>test(release): add unit tests when searching for a release by <a
href="https://github.com/rwaskiewicz"><code>@​rwaskiewicz</code></a> in
<a
href="https://redirect.github.com/softprops/action-gh-release/pull/603">softprops/action-gh-release#603</a></li>
<li>dependency updates</li>
</ul>
<h2>2.2.1</h2>
<h2>What's Changed</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix: big file uploads by <a
href="https://github.com/xen0n"><code>@​xen0n</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/562">softprops/action-gh-release#562</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>chore(deps): bump <code>@​types/node</code> from 22.10.1 to 22.10.2
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/559">softprops/action-gh-release#559</a></li>
<li>chore(deps): bump <code>@​types/node</code> from 22.10.2 to 22.10.5
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/569">softprops/action-gh-release#569</a></li>
<li>chore: update error and warning messages for not matching files in
files field by <a
href="https://github.com/ytimocin"><code>@​ytimocin</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/568">softprops/action-gh-release#568</a></li>
</ul>
<h2>2.2.0</h2>
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="72f2c25fcb"><code>72f2c25</code></a>
release 2.3.2</li>
<li><a
href="552dc5524b"><code>552dc55</code></a>
fix: revert <code>fs:readableWebStream</code> change (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/632">#632</a>)</li>
<li><a
href="f3cad8bcbf"><code>f3cad8b</code></a>
release 2.3.1</li>
<li><a
href="07a2257003"><code>07a2257</code></a>
fix: fix file closing issue (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/629">#629</a>)</li>
<li><a
href="d5382d3e6f"><code>d5382d3</code></a>
release 2.3.0</li>
<li><a
href="a0e2122208"><code>a0e2122</code></a>
feat: migrate from jest to vitest (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/626">#626</a>)</li>
<li><a
href="8836085300"><code>8836085</code></a>
chore: replace <code>mime</code> with <code>mime-types</code> (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/624">#624</a>)</li>
<li><a
href="86463358d8"><code>8646335</code></a>
chore: bump node to 20.19.2</li>
<li><a
href="46b284799f"><code>46b2847</code></a>
chore(deps): bump the npm group across 1 directory with 5 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/623">#623</a>)</li>
<li><a
href="37fd9d0351"><code>37fd9d0</code></a>
chore(deps): bump undici from 5.28.5 to 5.29.0 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/621">#621</a>)</li>
<li>Additional commits viewable in <a
href="da05d55257...72f2c25fcb">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=softprops/action-gh-release&package-manager=github_actions&previous-version=2.2.2&new-version=2.3.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-01 21:22:15 +00:00
dependabot[bot]
5c86fd271f chore: CI: bump dawidd6/action-download-artifact from 10 to 11 (#9137)
Bumps
[dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
from 10 to 11.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/dawidd6/action-download-artifact/releases">dawidd6/action-download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v11</h2>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v10...v11">https://github.com/dawidd6/action-download-artifact/compare/v10...v11</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ac66b43f0e"><code>ac66b43</code></a>
node_modules: upgrade</li>
<li><a
href="9b54a0a70c"><code>9b54a0a</code></a>
Update README.md</li>
<li>See full diff in <a
href="https://github.com/dawidd6/action-download-artifact/compare/v10...v11">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dawidd6/action-download-artifact&package-manager=github_actions&previous-version=10&new-version=11)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-01 21:21:43 +00:00
dependabot[bot]
402cba6f09 chore: CI: bump dcarbone/install-jq-action from 3.1.1 to 3.2.0 (#9138)
Bumps
[dcarbone/install-jq-action](https://github.com/dcarbone/install-jq-action)
from 3.1.1 to 3.2.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/dcarbone/install-jq-action/releases">dcarbone/install-jq-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.2.0</h2>
<h2>What's Changed</h2>
<ul>
<li>case sensitive is off by <a
href="https://github.com/Rupreht"><code>@​Rupreht</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/19">dcarbone/install-jq-action#19</a></li>
<li>Adding 1.8.0 stuff by <a
href="https://github.com/dcarbone"><code>@​dcarbone</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/20">dcarbone/install-jq-action#20</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Rupreht"><code>@​Rupreht</code></a> made
their first contribution in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/19">dcarbone/install-jq-action#19</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dcarbone/install-jq-action/compare/v3.1.1...v3.2.0">https://github.com/dcarbone/install-jq-action/compare/v3.1.1...v3.2.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="b7ef57d46e"><code>b7ef57d</code></a>
Adding 1.8.0 stuff (<a
href="https://redirect.github.com/dcarbone/install-jq-action/issues/20">#20</a>)</li>
<li><a
href="2eac2baa38"><code>2eac2ba</code></a>
case sensitive is off (<a
href="https://redirect.github.com/dcarbone/install-jq-action/issues/19">#19</a>)</li>
<li>See full diff in <a
href="https://github.com/dcarbone/install-jq-action/compare/v3.1.1...v3.2.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dcarbone/install-jq-action&package-manager=github_actions&previous-version=3.1.1&new-version=3.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-01 21:21:20 +00:00
Cameron Zwarich
c0aad8a27c chore: remove unnecessary special case for Bool (#9136) 2025-07-01 20:42:58 +00:00
Cameron Zwarich
dbcf5b9d9d fix: call lowerEnumToScalarType? with ConstructorVal.induct (#9134)
This PR changes ToIR to call `lowerEnumToScalarType?` with
`ConstructorVal.induct` rather than the name of the constructor itself.
This was an oversight in some refactoring of code in the new compiler
before landing it. It should not affect runtime of compiled code (due to
the extra tagging/untagging being optimized by LLVM), but it does make
IR for the interpreter slightly more efficient.
2025-07-01 20:00:34 +00:00
jrr6
d31dfe92de fix: account for namespaces/open decls in inlineExpr (#9108)
This PR fixes an issue that may have caused inline expressions in
messages to be unnecessarily rendered on a separate line.
2025-07-01 19:28:22 +00:00
Kyle Miller
a018ed3f0f feat: add usedLetOnly to LocalContext binder functions (#9131)
This PR adds a `usedLetOnly` parameter to `LocalContext.mkLambda` and
`LocalContext.mkForall`, to parallel the `MetavarContext` versions.
2025-07-01 18:41:49 +00:00
Leonardo de Moura
535ce0b8fd feat: pow_add normalization in grind (#9133)
This PR adds support for `a^(m+n)` in the `grind` normalizer.
2025-07-01 17:52:16 +00:00
Leonardo de Moura
2bfcb1f25c fix: expand pattern offset gadget in constant patterns (#9130)
This PR fixes unexpected occurrences of the `Grind.offset` gadget in
ground patterns. See new test
2025-07-01 16:31:58 +00:00
Rob23oba
0e5ce1496b fix: pretty-printing of grind syntax (#9128)
This PR fixes spacing in the `grind` attribute and tactic syntax.
Previously `@[grind]` was incorrectly pretty-printed as `@[grind ]`, and
`grind [...] on_failure ...` was pretty-printed `grind [...]on_failure
...`. Fixes that `on_failure` was reserved as keyword.
2025-07-01 16:15:11 +00:00
Eric Wieser
688d9a30d2 fix: incorrectly parenthesized Bool.nots (#9129)
This PR fixes simp lemmas about boolean equalities to say `(!x) = y`
instead of `(!decide (x = y)) = true`

This might be an argument for changing the operator precedence of `!`,
or writing a linter to detect these mistakes.

Zulip thread: [#lean4 > Sum.bnot_isLeft and Sum.bnot_isRight @
💬](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Sum.2Ebnot_isLeft.20and.20Sum.2Ebnot_isRight/near/525938158)
2025-07-01 15:57:14 +00:00
Parth Shastri
2c13d145dc fix: match against app fn for reducing recursor in whnfCore (#9090)
This PR fixes a bug in `whnfCore` where it would fail to reduce
applications of recursors/auxiliary defs.

Closes #9089
2025-07-01 13:30:31 +00:00
Eric Wieser
232443371b perf: add missing std::moves (#9107)
Continues from #4700.

This will save a handful of refcounts here and there.
2025-07-01 12:39:12 +00:00
Paul Reichert
c231b742ca refactor: move well-founded relations used by the iterators to init (#9095)
This PR moves the construction of the `Option.SomeLtNone.lt` (and `le`)
relation, in which `some` is less than `none`, to
`Init.Data.Option.Basic` and moves well-foundedness proofs for
`Option.lt` and `Option.SomeLtNone.lt` into `Init.Data.Option.Lemmas`.
2025-07-01 12:02:48 +00:00
Paul Reichert
c9dea51f7a chore: create iterator benchmark (#9094)
This PR adds a benchmark file that exemplifies some iterator usages
2025-07-01 11:47:36 +00:00
Eric Wieser
72f421054d fix: do not truncate at null bytes in panic messages (#9103)
This PR prevents truncation of `panic!` messages containing null bytes.

The C api for `lean_panic` is left untouched.

Closes #9102
2025-07-01 11:34:16 +00:00
Joachim Breitner
8424ddbb3e feat: prettier expected type mismatch error message (#9099)
This PR improves the “expected type mismatch” error message by omitting
the type's types when they are defeq, and putting them into separate
lines when not.

I found it rather tediuos to parse the error message when the expected
type is long, because I had to find the `:` in the middle of a large
expression somewhere. Also, when both are of sort `Prop` or `Type` it
doesn't add much value to print the sort (and it’s only one hover away
anyways).
2025-07-01 07:50:53 +00:00
Kim Morrison
6ab8ed34d0 chore: grind test case for matching Nat arguments (#9123) 2025-07-01 07:21:36 +00:00
Kim Morrison
0af3659d14 feat: attribute [grind cases eager] PProd MProd (#9121)
This PR allows `grind` to case on the universe variants of `Prod`.
2025-07-01 04:02:47 +00:00
Kim Morrison
8c1e5c5c07 chore: allow grind to unfold Array ifInBounds operations (#9120) 2025-07-01 02:44:27 +00:00
Kim Morrison
293d1dfd57 chore: improvements to release automation (#9119) 2025-07-01 02:39:10 +00:00
Cameron Zwarich
604312a3df chore: update doc/dev/ffi.md after #9088 (#9112) 2025-07-01 01:00:59 +00:00
Kim Morrison
835bc675ca chore: begin development cycle for v4.23.0 (#9118) 2025-07-01 00:40:35 +00:00
Cameron Zwarich
463f2c5f25 chore: improve readability of a zipWith call (#9116) 2025-07-01 00:10:54 +00:00
Cameron Zwarich
52ab0141cd chore: share more code in toIRType (#9115) 2025-06-30 23:13:02 +00:00
Kim Morrison
cd60e3b8fd feat: further release automation (#9114)
This PR further improves release automation, automatically incorporating
material from `nightly-testing` and `bump/v4.X.0` branches in the bump
PRs to downstream repositories.
2025-06-30 22:28:00 +00:00
Leonardo de Moura
b9e440d280 doc: improve grind doc string (#9113)
This PR improves the `grind` doc string and tries to make it more
approachable to new user.
2025-06-30 21:47:40 +00:00
Lean stage0 autoupdater
5296fa1dd5 chore: update stage0 2025-06-30 21:08:11 +00:00
Sebastian Ullrich
3d74e1ba44 chore: track .ir output files in Lake (#9060)
Co-authored-by: Mac Malone <tydeu@hatpress.net>
2025-06-30 15:59:18 +00:00
Sebastian Ullrich
de2d6ba37e perf: do not import non-template IR for codegen (#8666)
This PR adjusts the experimental module system to not import the IR of
non-`meta` declarations. It does this by replacing such IR with opaque
foreign declarations on export and adjusting the new compiler
accordingly.

This PR should not be merged before the new compiler.

Based on #8664.
2025-06-30 15:52:56 +00:00
Mac Malone
9db41f9931 fix: lake: source file not in module input trace & some logs dropped (#9101)
This PR fixes a bug introduce by #9081 where the source file was dropped
from the module input trace and some entries were dropped from the
module job log.
2025-06-30 15:48:01 +00:00
Cameron Zwarich
30fee8fb67 chore: update stage0 2025-06-30 15:39:58 +02:00
Cameron Zwarich
4c7ab7fc79 chore: set prefer_native=true for bootstrap 2025-06-30 15:39:58 +02:00
Cameron Zwarich
6f854a97a4 chore: update stage0 2025-06-30 15:39:58 +02:00
Cameron Zwarich
2e627d3692 feat: move constructor layout to Lean and add a few optimizations
This PR moves the constructor layout code from C++ to Lean. When
writing the new compiler, we just reused the existing C++ code,
even though it was a bit inconvenient, because we wanted to
ensure that constructor layout always matched the existing
compiler.

This fixes #2589 by handling struct field types just like any
other type being lowered, and thus applying the trivial structure
optimization in the process. Originally, I wanted to port the
code to Lean without any functional changes, but I found that
it took less code to just implement it "correctly" and get this
fix as a consequence than to emulate the bugs of the existing
C++ implementation.
2025-06-30 15:39:58 +02:00
Sebastian Graf
81fd7edd19 fix: More consistent transparency when calling mspec from mvcgen (#9097)
This PR ensures that `mspec` uses the configured transparency setting
and makes `mvcgen` use default transparency when calling `mspec`.

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-06-30 09:57:57 +00:00
Sebastian Ullrich
dfbebe0683 refactor: module-ize Std.Classes (#9079) 2025-06-30 09:45:24 +00:00
David Thrane Christiansen
9bbd2e64aa doc: add missing docstring for ToFormat.toFormat (#9093)
This PR adds a missing docstring for `ToFormat.toFormat`.
2025-06-30 06:59:12 +00:00
Kim Morrison
ae89b7ed43 feat: further release automation (#9092)
This PR further updates release automation. The per-repository update
scripts `script/release_steps.py` now actually performs the tests,
rather than outputting a script for the release manager to run line by
line. It's been tested on `v4.21.0` (i.e. the easy case of a stable
release), and we'll debug its behaviour on `v4.22.0-rc1` tonight.
2025-06-30 05:44:10 +00:00
David Thrane Christiansen
ede8a7e494 fix: error explanation needs updating (#9091)
This PR updates an error explanation to match the actual error.
2025-06-30 05:10:04 +00:00
Kyle Miller
044bfdb098 feat: eliminate letFun support, deprecate let_fun syntax (#9086)
This PR deprecates `let_fun` syntax in favor of `have` and removes
`letFun` support from WHNF and `simp`.
2025-06-30 02:10:18 +00:00
Mac Malone
5049a4893e refactor: lake: fix local artifact cache bugs, opt-in, & related cleanup (#9068)
This PR fixes some bugs with the local Lake artifact cache and cleans up
the surrounding API. It also adds the ability to opt-in to the cache on
packages without `enableArtifactCache` set using the
`LAKE_ARTIFACT_CACHE` environment variable.

Bug-wise, this fixes an issue where cached executable did not have right
permissions to run on Unix systems and a bug where cached artifacts
would not be invalidated on changes. Lake also now writes a trace file
to local build directory if there is none when fetching an artifact from
the cache. This trace has a new `synthetic` field set to `true` to
distinguish it from traces produced by full builds.
2025-06-30 01:02:55 +00:00
Lean stage0 autoupdater
d6c5c8c880 chore: update stage0 2025-06-30 01:20:30 +00:00
Kyle Miller
32894e7349 feat: remove irreducible from letFun (#9087)
This PR removes the `irreducible` attribute from `letFun`, which is one
step toward removing special `letFun` support; part of #9086.

Removing the attribute seems to break some `module` tests in stage2.
2025-06-30 00:04:59 +00:00
Sebastian Ullrich
d53d4722cc chore: compile stage 0 against correct version string (#9085)
This ensure the correct version string is embedded into shipped .oleans,
though only the githash is relevant for the version check.
2025-06-29 20:52:46 +00:00
Kyle Miller
cb3174b1c6 feat: hovers when pp.oneline is true (#7954)
This PR improves `pp.oneline`, where it now preserves tags when
truncating formatted syntax to a single line. Note that the `[...]`
continuation does not yet have any functionality to enable seeing the
untruncated syntax. Closes #3681.
2025-06-29 20:06:24 +00:00
Kyle Miller
68c006a95b feat: transform nondependent lets into haves in declarations and equation lemmas (#8373)
This PR enables transforming nondependent `let`s into `have`s in a
number of contexts: the bodies of nonrecursive definitions, equation
lemmas, smart unfolding definitions, and types of theorems. A motivation
for this change is that when zeta reduction is disabled, `simp` can only
effectively rewrite `have` expressions (e.g. `split` uses `simp` with
zeta reduction disabled), and so we cache the nondependence calculations
by transforming `let`s to `have`s. The transformation can be disabled
using `set_option cleanup.letToHave false`.

Uses `Meta.letToHave`, introduced in #8954.
2025-06-29 19:45:45 +00:00
Kyle Miller
44c8b0df85 feat: warn.sorry option (#8662)
This PR adds a `warn.sorry` option (default true) that logs the
"declaration uses 'sorry'" warning when declarations contain `sorryAx`.
When false, the warning is not logged.

Closes #8611 (assuming that one would set `warn.sorry` as an extra flag
when building).

Other change: Uses `warn.sorry` when creating auxiliary declarations in
`structure` elaborator, to suppress irrelevant 'sorry' warnings.

We could include the sorries themselves in the message if they are
labeled, letting users "go to definition" to see where the sorries are
coming from.

In an earlier version, added additional information to the warning when
it is a synthetic sorry, since these can be caused by elaboration bugs
and they can also be caused by elaboration failures in previous
declarations. This idea needs some more work, so it's not included.
2025-06-29 19:31:17 +00:00
Cameron Zwarich
85c45c409e chore: move lowerType to ToIRType and rename it (#9083) 2025-06-29 19:16:00 +00:00
Mac Malone
e0354cd856 fix: lake: module builds not appearing in job monitor (#9081)
This PR fixes a bug with Lake where the job monitor would sit on a
top-level build (e.g., `mathlib/Mathlib:default`) instead of reporting
module build progress.

The issue was actually simpler than it initially appeared. The wrong
portion of the module build was being registered to job monitor. Moving
it to right place fixes it, no job priorities necessary.
2025-06-29 18:39:06 +00:00
Cameron Zwarich
5d8cd35471 chore: rename Lean.Compiler.IR.CtorLayout to ToIRType (#9082) 2025-06-29 18:36:55 +00:00
Cameron Zwarich
0b738e07b4 chore: move more functions to CtorLayout (#9080) 2025-06-29 17:31:41 +00:00
Sebastian Ullrich
f475d5a428 chore: module-ize Init.lean 2025-06-29 16:52:13 +02:00
Sebastian Ullrich
5aa1950c3f chore: update stage0 2025-06-29 16:15:49 +02:00
Sebastian Ullrich
8085d3c930 chore: allow use of the module system in all of core (#9078) 2025-06-29 13:49:27 +00:00
Kim Morrison
a35425b192 feat: support for ReflCmp in grind (#9073)
This PR copies #9069 to handle `ReflCmp` the same way; we need to call
this in propagateUp rather than propagateDown.
2025-06-29 11:36:39 +00:00
Leonardo de Moura
8b1d2fc2d5 feat: OfSemiring.toQ unexpander (#9076)
This PR adds an unexpander for `OfSemiring.toQ`. This an auxiliary
function used by the `ring` module in `grind`, but we want to reduce the
clutter in the diagnostic information produced by `grind`. Example:
```
example [CommSemiring α] [AddRightCancel α] [IsCharP α 0] (x y : α)
    : x^2*y = 1 → x*y^2 = y → x + y = 2 → False := by
  grind
```
produces
```
  [ring] Ring `Ring.OfSemiring.Q α` ▼
    [basis] Basis ▼
      [_] ↑x + ↑y + -2 = 0
      [_] ↑y + -1 = 0
```
2025-06-29 11:22:24 +00:00
Kim Morrison
98e868e3d2 feat: BEq instances for ByteArray/FloatArray (#9075)
This PR adds `BEq` instances for `ByteArray` and `FloatArray` (also a
`DecidableEq` instance for `ByteArray`).
2025-06-29 11:12:48 +00:00
Leonardo de Moura
b95b0069e7 feat: use comm ring module to normalize nonlinear polynomials in grind cutsat (#9074)
This PR uses the commutative ring module to normalize nonlinear
polynomials in `grind cutsat`. Examples:
```lean
example (a b : Nat) (h₁ : a + 1 ≠ a * b * a) (h₂ : a * a * b ≤ a + 1) : b * a^2 < a + 1 := by 
  grind

example (a b c : Int) (h₁ : a + 1 + c = b * a) (h₂ : c + 2*b*a = 0) : 6 * a * b - 2 * a ≤ 2 := by 
  grind
```
2025-06-29 11:09:29 +00:00
Leonardo de Moura
f2e06ead54 feat: support for LawfulEqCmp in grind (#9069)
This PR implements support for the type class `LawfulEqCmp`. Examples:
```lean
example (a b c : Vector (List Nat) n)
    : b = c → a.compareLex (List.compareLex compare) b = o → o = .eq → a = c := by
  grind

example [Ord α] [Std.LawfulEqCmp (compare : α → α → Ordering)] (a b c : Array (Vector (List α) n))
    : b = c → o = .eq → a.compareLex (Vector.compareLex (List.compareLex compare)) b = o → a = c := by
  grind
```
2025-06-28 22:41:22 +00:00
Leonardo de Moura
f6bb524406 doc: grind docstring (#9067)
This PR adds a docstring for the `grind` tactic.
2025-06-28 20:20:55 +00:00
Cameron Zwarich
ef77322133 chore: fix a typo in an error message (#9066) 2025-06-28 19:48:50 +00:00
Leonardo de Moura
4247dcfea6 feat: improve counterexamples using ToInt.toInt in grind cutsat (#9065)
This PR improves the counterexamples produced by the `cutsat` procedure
in `grind` when using the `ToInt` gadget.
2025-06-28 19:30:25 +00:00
Cameron Zwarich
05978caa59 chore: move type lowering functions to CoreM (#9064) 2025-06-28 18:10:42 +00:00
Sebastian Ullrich
09a5b34931 feat: make private the default in module (#9044)
This PR adjusts the experimental module system to make `private` the
default visibility modifier in `module`s, introducing `public` as a new
modifier instead. `public section` can be used to revert the default for
an entire section, though this is more intended to ease gradual adoption
of the new semantics such as in `Init` (and soon `Std`) where they
should be replaced by a future decl-by-decl re-review of visibilities.
2025-06-28 16:30:53 +00:00
Cameron Zwarich
5144a3bf74 chore: rename lowerEnumToScalarType to lowerEnumToScalarType? (#9063) 2025-06-28 15:52:11 +00:00
Leonardo de Moura
5ca6eadd50 feat: equations <num> = 0 in grind ring (#9062)
This PR implements support for equations `<num> = 0` in rings and fields
of unknown characteristic. Examples:
```lean
example [Field α] (a : α) : (2 * a)⁻¹ = a⁻¹ / 2 := by grind

example [Field α] (a : α) : (2 : α) ≠ 0 → 1 / a + 1 / (2 * a) = 3 / (2 * a) := by grind

example [CommRing α] (a b : α) (h₁ : a + 2 = a) (h₂ : 2*b + a = 0) : a = 0 := by
  grind

example [CommRing α] (a b : α) (h₁ : a + 6 = a) (h₂ : b + 9 = b) (h₂ : 3*b + a = 0) : a = 0 := by
  grind

example [CommRing α] (a b : α) (h₁ : a + 6 = a) (h₂ : b + 9 = b) (h₂ : 3*b + a = 0) : a = 0 := by
  grind

example [CommRing α] (a b : α) (h₁ : a + 2 = a) (h₂ : b = 0) : 4*a + b = 0 := by
  grind

example [CommRing α] (a b c : α) (h₁ : a + 6 = a) (h₂ : c = c + 9) (h : b + 3*c = 0) : 27*a + b = 0 := by
  grind

```
2025-06-28 14:28:42 +00:00
Sebastian Ullrich
22152b8bfb chore: update stage0 2025-06-28 15:58:14 +02:00
Sebastian Ullrich
d7e35c77ca chore: reserve public import syntax (#9061)
This PR adds the `public import` syntax to be used by the experimental
module system
2025-06-28 13:11:34 +00:00
Leonardo de Moura
e844f9c82c feat: helper theorems for grind ring (#9059)
This PR adds helper theorems for normalizing coefficients in rings of
unknown characteristic.
2025-06-28 10:57:44 +00:00
Sebastian Ullrich
4f2d107b52 chore: update stage0 2025-06-28 12:09:50 +02:00
Paul Reichert
e86e978f26 feat: ToStream instance for ranges (#9058)
This PR provides a `ToStream` instance for slices so that they can be
used in `for i in xs, j in ys do` notation.
2025-06-28 09:38:37 +00:00
Paul Reichert
d380919fa3 feat: lemmas about toList, toListRev and toArray for slices (#9049)
This PR proves that the default `toList`, `toListRev` and `toArray`
functions on slices can be described in terms of the slice iterator.
Relying on new lemmas for the `uLift` and `attachWith` iterator
combinators, a more concrete description of said functions is given for
`Subarray`.
2025-06-28 08:29:09 +00:00
Leonardo de Moura
98b66ec373 feat: variable reordering heuristic for grind cutsat (#9057)
This PR introduces a simple variable-reordering heuristic for `cutsat`.
It is needed by the `ToInt` adapter to support finite types such as
`UInt64`. The current encoding into `Int` produces large coefficients,
which can enlarge the search space when an unfavorable variable order is
used. Example:
```lean
example (a b c : UInt64) : a ≤ 2 → b ≤ 3 → c - a - b = 0 → c ≤ 5 := by
  grind
```
2025-06-28 08:12:43 +00:00
Kim Morrison
291938c748 chore: generalize Array/Vector.extract_push (#9055)
This PR renames `Array/Vector.extract_push` to `extract_push_of_le`, and
replaces the lemma with one without a side condition.
2025-06-28 07:07:57 +00:00
Kim Morrison
c52605dfe3 fix: some inconsistencies in Map grind annotations (#9054)
This PR corrects some inconsistencies in `TreeMap`/`HashMap` grind
annotations, for `isSome_get?_eq_contains` and `empty_eq_emptyc`.
2025-06-28 06:41:19 +00:00
Leonardo de Moura
19fd1f060f feat: ToInt equality in grind cutsat (#9051)
This PR implements support for equalities and disequalities in `grind
cutsat`. We still have to improve the encoding. Examples:
```lean
example (a b c : Fin 11) : a ≤ 2 → b ≤ 3 → c = a + b → c ≤ 5 := by
  grind

example (a : Fin 2) : a ≠ 0 → a ≠ 1 → False := by
  grind
```
2025-06-27 21:52:23 +00:00
jrr6
a0e425748a chore: enable error explanation widget (#9043)
This PR enables the error explanation widget in named error messages.
Note that the displayed links won't work until the new manual version is
released (unless overriding `LEAN_MANUAL_ROOT` with a suitably recent
manual build).
2025-06-27 19:25:29 +00:00
Paul Reichert
6e538c35dd refactor: migrate all usages of old slice notation (#9000)
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.
2025-06-27 18:52:07 +00:00
Leonardo de Moura
422eb68f6f feat: assert ToInt bounds in grind cutsat (#9050)
This PR ensures the `ToInt` bounds are asserted for every `toInt a`
application internalized in `grind cutsat`.
2025-06-27 18:42:35 +00:00
Leonardo de Moura
7f5b47e831 feat: ToInt strict inequalities in grind cutsat (#9048)
This PR implements support for strict inequalities in the `ToInt`
adapter used in `grind cutsat`. Example:
```lean
example (a b c : Fin 11) : c ≤ 9 → a ≤ b → b < c → a < c + 1 := by
  grind
```
2025-06-27 17:34:12 +00:00
Sofia Rodrigues
bf2e91b6d1 feat: add system information functions to the standard library (#8109)
This PR adds system information functions to the standard library
2025-06-27 16:31:34 +00:00
Sebastian Graf
e886373dc8 fix: Avoid a type error in mvcgen and turn fewer natural goals into synthetic opaque ones (#9045)
This PR fixes a type error in `mvcgen` and makes it turn fewer natural
goals into synthetic opaque ones, so that tactics such as `trivial` may
instantiate them more easily.

---------

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-06-27 16:27:06 +00:00
Sebastian Ullrich
7ed1a4b576 perf: inline lean_inc_ref_cold (#4978)
The body is a single instruction
2025-06-27 15:58:00 +00:00
jrr6
4759506bcf chore: use note and hint' for message addenda (#8980)
This PR improves the consistency of error message formatting by
rendering addenda of several existing error messages as labeled notes
and hints.
2025-06-27 15:16:01 +00:00
Sebastian Ullrich
f5c389468f chore: update stage0 2025-06-27 08:13:31 -07:00
Sebastian Ullrich
aadc74bee2 perf: do not import non-meta IR 2025-06-27 08:13:31 -07:00
Sebastian Ullrich
bd16c0f87d chore: update stage0 2025-06-27 16:55:38 +02:00
Sebastian Graf
862a3dc552 fix: Use fullApproxDefEq in mspec to fix a bug reported by Rish (#9041)
This PR makes `mspec` detect more viable assignments by `rfl` instead of
generating a VC.

---------

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
Co-authored-by: Rishikesh Vaishnav <rishhvaishnav@gmail.com>
2025-06-27 14:31:39 +00:00
Markus Himmel
c3319f21ee chore: Grove: start on associative containers (#9039) 2025-06-27 13:34:10 +00:00
David Thrane Christiansen
2bb27af0d4 chore: automatically create reference manual PR branches (#9033)
This PR adds a Mathlib-like testing and feedback system for the
reference manual. Lean PRs will receive comments that reflect the status
of the language reference with respect to the PR.
2025-06-27 13:23:41 +00:00
Sebastian Graf
c79b89fb39 fix: More fixes for Std.Do accumulated while merging tests (#9038)
This PR adds test cases for the VC generator and implements a few small
and tedious fixes to ensure they pass.

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-06-27 13:10:43 +00:00
Henrik Böving
7a1113ada3 feat: extend identifiers to french (#9035)
This PR extends the list of acceptable characters to all the french ones
as well as some others,
by adding characters from the Latin-1-Supplement add Latin-Extended-A
unicode block.
2025-06-27 12:50:09 +00:00
Sebastian Ullrich
7845af3105 chore: reserve public section syntax (#9032)
To be used in the experimental module system
2025-06-27 12:21:01 +00:00
Sebastian Ullrich
35c168cb13 feat: allow access to private names through import all (#8828)
This PR extends the experimental module system to support resolving
private names imported (transitively) through `import all`.
2025-06-27 12:13:46 +00:00
Sofia Rodrigues
fe1b407031 feat: add DNS resolution functions to the standard library (#8072)
This PR adds DNS functions to the standard library

---------

Co-authored-by: Henrik Böving <hargonix@gmail.com>
Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
2025-06-27 11:11:47 +00:00
Sofia Rodrigues
0f2cb91336 feat: add lean_setup_libuv for initializing required LIBUV components (#8636)
This PR adds a function called `lean_setup_libuv` that initializes
required LIBUV components. It needs to be outside of
`lean_initialize_runtime_module` because it requires `argv` and `argc`
to work correctly.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
2025-06-27 11:11:17 +00:00
Sebastian Graf
08737054fc fix: A couple of bootstrapping hiccups related to Std.Do (#9030)
This PR fixes a couple of bootstrapping-related hiccups in the newly
added `Std.Do` module. More precisely,

* The `spec` attribute syntax was registered under the wrong name and
its implementation needed to use a different priority parser
* Elaborators and delaborators for `MGoal`, `Triple`, `PostCond` and
`PostCond.total` were broken and are now properly builtin
* `Std.Do` should not transitively import `Std.Tactic.Do.Syntax`

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-06-27 09:53:17 +00:00
Henrik Böving
56d3de5358 fix: bv_decide internal error (#9031)
This PR fixes a minor usability issue in bv_decide.
2025-06-27 09:10:21 +00:00
Marc Huisinga
1edb7632b5 fix: highlight keywords when keyword is actual identifier (#9019)
This PR fixes a bug where semantic highlighting would only highlight
keywords that started with an alphanumeric character. Now, it uses
`Lean.isIdFirst`.
2025-06-27 08:23:10 +00:00
Paul Reichert
1a6eae16ec feat: introduce uLift iterator combinator, make Subarray.iter universe-polymorphic (#9027)
This PR provides an iterator combinator that lifts the emitted values
into a higher universe level via `ULift`. This combinator is then used
to make the subarray iterators universe-polymorphic. Previously, they
were only available for `Subarray α` if `α : Type`.
2025-06-27 07:34:08 +00:00
Kim Morrison
8d40cf5157 chore: missing Option lemma (#9028) 2025-06-27 07:28:59 +00:00
Leonardo de Moura
0aca10b228 feat: Toint inequalities in cutsat (#9026)
This PR implements support for (non strict) `ToInt` inequalities in
`grind cutsat`. `grind cutsat` can solve simple problems such as:
```lean
example (a b c : Fin 11) : a ≤ b → b ≤ c → a ≤ c := by
  grind

example (a b c : Fin 11) : c ≤ 9 → a ≤ b → b ≤ c → a ≤ c + 1 := by
  grind

example (a b c : UInt8) : a ≤ b → b ≤ c → a ≤ c := by
  grind

example (a b c d : UInt32) : a ≤ b → b ≤ c → c ≤ d → a ≤ d := by
  grind
```
Next step: strict inequalities, and equalities.
2025-06-27 06:29:31 +00:00
Mac Malone
541ff1e287 feat: lake: local artifact cache (#8922)
This PR introduces a local artifact cache for Lake. When enabled, Lake
will shared build artifacts (built files) across different instances of
the same package using an input- and content-addressed cache.

To enable support for the local cache, packages must set
`enableArtifactCache := true` in their package configuration. The reason
for this is twofold. This feature is new and experimental, so it should
be opt-in. Also, some packages may need to disable it as the cache
entails that artifacts are no longer necessarily available within the
build directory, which can break custom build scripts.

The cache location is determined by the system configuration. Lake's
first preference is to store it under the Lean toolchain in a
`lake/cache` directory. If Elan is not available, Lake will store it in
common system location (e.g., `$XDG_CACHE_HOME/lake`, or
`~/.cache/lake`). On an exotic system where neither of these exist, the
cache will be disabled. Users can override this location through the
`LAKE_CACHE_DIR` environment variable. If set to empty, caching will be
disabled.

The cache is both input and content-addressed. Mappings from input hash
to output content hash(es) are stored in a per-package JSON Lines file
(e.g., `<cache-dir>/inputs/<pkg-name>.jsonl`). Thus, mappings are shared
across different instances of a package, but not between packages. The
output content hashes are also now stored in trace files in a new
`outputs` field. The value of this field can be either a single hash or
an object of multiple content hashes for targets which produce multiple
artifacts (e.g., Lean module builds). Separately, artifacts are stored
in a single flat content-addressed cache (e.g.,
`<cache-dir>/artifacts/<hash>.art`. Artifacts are therefore shared
across all cache-enabled packages.

Module `*.olean` and and `*.ilean` artifacts are cached. However, each
package will still copy the files to their build directory, as Lean and
the server currently expect them to be at a specific path. This will be
changed for `*.olean` files when the performance issues with
pre-resolving modules in Lake for `lean --setup` are solved.
2025-06-27 04:06:50 +00:00
Leonardo de Moura
0371509e49 refactor: remove foreignTypes leftover from cutsat (#9024)
We will not use it with the new `ToInt` infrastructure.
2025-06-27 02:47:34 +00:00
Kyle Miller
7abc9106d7 feat: optimized simp routine for let telescopes (#8968)
This PR adds the following features to `simp`:
- A routine for simplifying `have` telescopes in a way that avoids
quadratic complexity arising from locally nameless expression
representations, like what #6220 did for `letFun` telescopes.
Furthermore, simp converts `letFun`s into `have`s (nondependent lets),
and we remove the #6220 routine since we are moving away from `letFun`
encodings of nondependent lets.
- A `+letToHave` configuration option (enabled by default) that converts
lets into haves when possible, when `-zeta` is set. Previously Lean
would need to do a full typecheck of the bodies of `let`s, but the
`letToHave` procedure can skip checking some subexpressions, and it
modifies the `let`s in an entire expression at once rather than one at a
time.
- A `+zetaHave` configuration option, to turn off zeta reduction of
`have`s specifically. The motivation is that dependent `let`s can only
be dsimped by let, so zeta reducing just the dependent lets is a
reasonable way to make progress. The `+zetaHave` option is also added to
the meta configuration.
- When `simp` is zeta reducing, it now uses an algorithm that avoids
complexity quadratic in the depth of the let telescope.
- Additionally, the zeta reduction routines in `simp`, `whnf`, and
`isDefEq` now all are consistent with how they apply the `zeta`,
`zetaHave`, and `zetaUnused` configurations.

The `letToFun` option is addressing a TODO in `getSimpLetCase` ("handle
a block of nested let decls in a single pass if this becomes a
performance problem").

Performance should be compared to before #8804, which temporarily
disabled the #6220 optimizations for `letFun` telescopes.

Good kernel performance depends on carefully handling the `have`
encoding. Due to the way the kernel instantiates bvars (it does *not*
beta reduce when instantiating), we cannot use congruence theorems of
the form `(have x := v; f x) = (have x ;= v'; f' x)`, since the bodies
of the `have`s will not be syntactically equal, which triggers zeta
reduction in the kernel in `is_def_eq`. Instead, we work with `f v = f'
v'`, where `f` and `f'` are lambda expressions. There is still zeta
reduction, but only when converting between these two forms at the
outset of the generated proof.
2025-06-27 02:13:20 +00:00
jrr6
05948f19e4 fix: improve precision of synthesis failure spans in interpolated strings (#9004)
This PR ensures that type-class synthesis failure errors in interpolated
strings are displayed at the interpolant at which they occurred.
2025-06-27 01:47:32 +00:00
Leonardo de Moura
6b520ede08 feat: generic toInt for cutsat (#9022)
This PR completes the generic `toInt` infrastructure for embedding terms
implementing the `ToInt` type classes into `Int`.
2025-06-27 00:28:51 +00:00
jrr6
2fe6d8a70b feat: add word-level hint suggestion diffs (#8574)
This PR adds an additional diff mode to the error-message hint
suggestion widget that displays diffs per word rather than per
character.
2025-06-26 23:56:19 +00:00
Luisa Cicolini
b1a306cf69 feat: add BitVec.toFin_(sdiv, smod, srem) and BitVec.toNat_srem (#8950)
This PR adds `BitVec.toFin_(sdiv, smod, srem)` and `BitVec.toNat_srem`.
The strategy for the `rhs` of the `toFin_*` lemmas is to consider what
the corresponding `toNat_*` theorems do and push the `toFin` closerto
the operands. For the `rhs` of `BitVec.toNat_srem` I used the same
strategy as `BitVec.toNat_smod`.
2025-06-26 20:01:01 +00:00
Kyle Miller
b56ad5a7d2 fix: apply newlines before and after comments when formatting syntax (#8626)
This PR closes #3791, making sure that the Syntax formatter inserts
whitespace before and after comments in the leading and trailing text of
Syntax to avoid having comments comment out any following syntax, and to
avoid comments' lexical syntax from being interpreted as being part of
another syntax. If the text contains newlines before or after any
comments, they are formatted as hard newlines rather than soft newlines.
For example, `--` comments will have a hard newline after them. Note:
metaprograms generating Syntax with comments should be sure to include
newlines at the ends of `--` comments.
2025-06-26 19:23:35 +00:00
jrr6
7ed716f904 feat: improve projection and field-notation errors (#8986)
This PR improves the error messages produced by invalid projections and
field notation. It also adds a hint to the "function expected" error
message noting the argument to which the term is being applied, which
can be helpful for debugging spurious "function expected" messages
actually caused by syntax errors.

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2025-06-26 18:36:47 +00:00
Lean stage0 autoupdater
928d37e4d4 chore: update stage0 2025-06-26 18:04:18 +00:00
Sebastian Graf
f87d05ad4e feat: Hoare logic for monadic programs and verification condition generation (#8995)
This PR introduces a Hoare logic for monadic programs in
`Std.Do.Triple`, and assorted tactics:

*  `mspec` for applying Hoare triple specifications
* `mvcgen` to turn a Hoare triple proof obligation `⦃P⦄ prog ⦃Q⦄` into
pure verification conditoins (i.e., without any traces of Hoare triples
or weakest preconditions reminiscent of `prog`). The resulting
verification conditions in the stateful logic of `Std.Do.SPred` can be
discharged manually with the tactics coming with its custom proof mode
or with automation such as `simp` and `grind`.

This is pre-release of a planned feature and not yet intended for
production use. We are grateful for feedback of early adopters, though.

Co-authored-by: Sebastian Graf <sg@lean-fro.org>
2025-06-26 15:49:56 +00:00
Paul Reichert
83e226204d feat: introduce slices (#8947)
This PR introduces polymorphic slices in their most basic form. They
come with a notation similar to the new range notation. `Subarray` is
now also a slice and can produce an iterator now. It is intended to
migrate more operations of `Subarray` to the `Slice` wrapper type to
make them available for slices of other types, too.

The PR also moves the `filterMap` combinators into `Init` because they
are used internally to implement iterators on array slices.
2025-06-26 15:29:03 +00:00
Rob23oba
9bf5fc2fd3 feat: extensional tree maps (#8721)
This PR adds the types `Std.ExtDTreeMap`, `Std.ExtTreeMap` and
`Std.ExtTreeSet` of extensional tree maps and sets. These are very
similar in construction to the existing extensional hash maps with one
exception: extensional tree maps and sets provide all functions from
regular tree maps and sets. This is possible because in contrast to hash
maps, tree maps are always ordered.
2025-06-26 13:13:45 +00:00
Markus Himmel
2f43f02cb6 chore: Grove: high-level sections (#9011) 2025-06-26 13:06:56 +00:00
Markus Himmel
65ea45b17b chore: ci: fixes to Grove workflow (#9014) 2025-06-26 12:15:51 +00:00
Sebastian Graf
0d7fe9a196 feat: Upstream MPL.SPred.* from mpl (#8928)
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-26 11:15:11 +00:00
Markus Himmel
790ae27f2b chore: ci: fixes to Grove workflow (#9013) 2025-06-26 11:13:19 +00:00
Markus Himmel
40d2c99463 chore: ci: fixes to Grove workflow (#9012) 2025-06-26 09:55:06 +00:00
Lean stage0 autoupdater
2c60f1a254 chore: update stage0 2025-06-26 09:48:45 +00:00
Markus Himmel
4f1d828541 chore: ci: build Linux toolchain for master commits (but not merge queue runs) (#9010) 2025-06-26 08:20:04 +00:00
Paul Reichert
70b4b2b36c feat: polymorphic ranges (#8784)
This PR introduces ranges that are polymorphic, in contrast to the
existing `Std.Range` which only supports natural numbers.

Breakdown of core changes:

* `Lean.Parser.Basic`: Modified the number parser (`Lean.Parser.Basic`)
so that it will only consider a *single* dot to be part of a decimal
number. `1..` will no longer be parsed as `1.` followed by `.`, but as
`1` followed by `..`.
* The test `ellipsisProjIssue` ensures that `#check Nat.add ...succ`
produces a syntax error. After introducing the new range notation (see
below), it returns a different (less nice) error message. I updated the
test to reflect the new error message. (The error message will become
nicer as soon as a delaborator for the ranges is implemented. This is
out of scope for this PR.)

Breakdown of standard library changes:

Modified modules: `Init.Data.Range.Polymorphic` (added),
`Init.Data.Iterators`, `Std.Data.Iterators`

* Introduced the type `Std.PRange` that is parameterized over the type
in which the range operates and the shapes of the lower and upper bound.
* Introduced a new notation for ranges. Examples for this notation are:
`1...*`, `1...=3`, `1...<3`, `1<...=2`, `*...=3`.
* Defined lots of typeclasses for different capabilities of ranges,
depending on their shape and underlying type.
* Introduced `Iter(M).size`.
* Introduced the `Iter(M).stepSize n` combinator, which iterates over an
iterator with the given step size `n`. It will drop `n - 1` values
between every value it emits.
* Replaced `LawfulPureIterator` with a new and better typeclass
`LawfulDeterministicIterator`.
* Simplified some lemma statements in the iterator library such as
`IterM.toList_eq_match`, which unnecessarily matched over a `Subtype`,
hindering rewrites due to type dependencies.

Reasons for the concrete choice of notation:

* `lean4-cli` uses `...`-based notation for the `Cmd` notation and it
clashes with `...a` range notation.
* test `2461` fails when using two-dot-based notation because of the
existing `{ a.. }` notation.
2025-06-26 08:18:11 +00:00
Paul Reichert
3695059504 feat: introduce MonadLiftT Id m (#8977)
This PR adds a generic `MonadLiftT Id m` instance. We do not implement a
`MonadLift Id m` instance because it would slow down instance resolution
and because it would create more non-canonical instances. This change
makes it possible to iterate over a pure iterator, such as `[1, 2,
3].iter`, in arbitrary monads.
2025-06-26 07:33:07 +00:00
Leonardo de Moura
b76bf44654 feat: infrastructure for cutsat generic ToInt (#9008)
This PR implements the basic infrastructure for the generic `ToInt`
support in `cutsat`.
2025-06-26 07:01:19 +00:00
Markus Himmel
d3dda9f6d4 chore: initial Grove setup (#8997) 2025-06-26 05:03:02 +00:00
Kim Morrison
561c18819c chore: typo (#9007) 2025-06-26 03:50:29 +00:00
David Thrane Christiansen
5ec3cc5df7 doc: review Repr and Format docstrings (#8998)
This PR makes the docstrings related to `Format` and `Repr` have
consistent formatting and style, and adds missing docstrings.
2025-06-26 03:20:23 +00:00
Kim Morrison
62e9d73f8b chore: revert BitVec/Lemmas grind proofs; too many bootstrapping difficulties (#9006) 2025-06-26 03:04:01 +00:00
Sofia Rodrigues
b15cfadde8 feat: monadic interface for asynchronous operations in Std (#8003)
This PR adds a new monadic interface for `Async` operations.

This is the design for the `Async` monad that I liked the most. The idea
was refined with the help of @tydeu. Before that, I had some
prerequisites in mind:

1. Good performance
2. Explicit `yield` points, so we could avoid using `bindTask` for every
lifted IO operation
3. A way to avoid creating an infinite chain of `Task`s during recursion

The 2 and 3 points are not covered in this PR, I wish I had a good
solution but right now only a few sketches of this.

### Explicit `yield` points

I thought this would be easy at first, but it actually turned out kinda
tricky. I ended up creating the `suspend` syntax, which is just a small
modification of the lift method (`<- ...`) syntax. It desugars to
`Suspend.suspend task fun _ => ...`. So something like:

```lean
do
  IO.println "a"
  IO.println "b"
  let result := suspend (client.recv? 1024)
  IO.println "c"
  IO.println "d"
```

Would become:

```lean
Bind.bind (IO.println "a") fun _ =>
Bind.bind (IO.println "b") fun _ =>
Suspend.suspend (client.recv? 1024) fun message =>
  Bind.bind (IO.println "c") fun _ =>
  IO.println "d"
```

This makes things a bit more efficient. When using `bind`, we would try
to avoid creating a `Task` chain, and the `suspend` would be the only
place we use `Task.bind`. But there's a problem if we use `bind` with
something that needs `suspend`, it’ll block the whole task. Blocking is
the only way to prevent task accumulation when using plain `bind` inside
a structure like that:

```
inductive AsyncResult (ε σ α : Type u) where
    | ok    : α → σ → AsyncResult ε σ α
    | error : ε → σ → AsyncResult ε σ α
    | ofTask  : Task (EStateM.Result ε σ α) → σ →AsyncResult ε σ α
```

Because we simply need to remove the `ofTask` and transform it into an
`ok`.

### Infinite chain of Tasks

If you create an infinite recursive function using `Task` (which is
super common in servers like HTTP ones), it can lead to a lot of memory
usage. Because those tasks get chained forever and won't be freed until
the function returns.

To get around that, I used CPS and instead of just calling `Task.bind`,
I’d spawn a new task and return an "empty" one like:

```lean
fun k => Task.bind (...) fun value => do k value; pure emptyTask
```

This works great with a CPS-style monad, but it generates a huge IR by
itself.

Just doing CPS alone was too much, though, because every lifted
operation created a new continuation and a `Task.bind`. So, I used it
with `suspend` and got a better performance, but the usage is not good
with `suspend`.

### The current monad

Right now, the monad I’m using is super simple. It doesn't solve the
earlier problems, but the API is clean, and the generated IR is small
enough. An example of how we should use it is:

```lean
-- A loop that repeatedly sends a message and waits for a reply.
partial def writeLoop (client : Socket.Client) (message : String) : Async (AsyncTask Unit) := async do
  IO.println s!"sending: {message}"
  await (← client.send (String.toUTF8 message))

  if let some mes ← await (← client.recv? 1024) then
    IO.println s!"received: {String.fromUTF8! mes}"
    -- use parallel to avoid building up an infinite task chain
    parallel (writeLoop client message)
  else
    IO.println "client disconnected from receiving"

-- Server’s main accept loop, keeps accepting and echoing for new clients.
partial def acceptLoop (server : Socket.Server) (promise : IO.Promise Unit) : Async (AsyncTask Unit) := async do
  let client ← await (← server.accept)
  await (← client.send (String.toUTF8 "tutturu "))

  -- allow multiple clients to connect at the same time
  parallel (writeLoop client "hi!!")

  -- and keep accepting more clients, parallel again to avoid building up an infinite task chain
  parallel (acceptLoop server promise)

-- A simple client that connects and sends a message.
def echoClient (addr : SocketAddress) (message : String) : Async (AsyncTask Unit) := async do
  let socket ← Client.mk
  await (← socket.connect addr)
  parallel (writeLoop socket message)

-- TCP setup: bind, listen, serve, and run a sample client.
partial def mainTCP : Async Unit := do
  let addr := SocketAddressV4.mk (.ofParts 127 0 0 1) 8080

  let server ← Server.mk
  server.bind addr
  server.listen 128

  -- promise exists since the server is (probably) never going to stop
  let promise ← IO.Promise.new
  let acceptAction ← acceptLoop server promise

  await (← echoClient addr "hi!")
  await acceptAction
  await promise

-- Entry point
def main : IO Unit := mainTCP.wait
```

---------

Co-authored-by: Henrik Böving <hargonix@gmail.com>
Co-authored-by: Mac Malone <tydeu@hatpress.net>
2025-06-26 02:51:26 +00:00
Kim Morrison
1e135f2187 fix: refactor ToInt.OfNat (#9005)
This PR changes the definition of `Lean.Grind.ToInt.OfNat`, introducing
a `wrap` on the right-hand-side.
2025-06-26 02:27:15 +00:00
Cameron Zwarich
d6fdbe2b23 fix: implement main type validity check in the new compiler (#9003)
This PR implements the validity check for the type of `main` in the new
compiler. There were no tests for this, so it slipped under the radar.
2025-06-25 23:59:27 +00:00
Cameron Zwarich
567280cb41 chore: remove outdated comment (#9002) 2025-06-25 22:16:36 +00:00
jrr6
8da2f7105c chore: reword redundant alternative error explanation (#9001)
This PR adjusts the `lean.redundantMatchAlt` error explanation to remove
the word "unprefixed," which the reference manual's style linter does
not recognize.
2025-06-25 22:15:22 +00:00
Luisa Cicolini
25b1b46572 feat: add BitVec.msb_(smod, srem) (#8974)
This PR adds `BitVec.msb_(smod, srem)`. 

co-authored with @tobiasgrosser and @bollu

---------

Co-authored-by: Tobias Grosser <github@grosser.es>
Co-authored-by: Siddharth <siddu.druid@gmail.com>
2025-06-25 13:49:33 +00:00
Kim Morrison
0ddd9341d6 feat: refactor of Lean.Grind.ToInt and remaining instances (#8996)
This PR provides the remaining instances for the `Lean.Grind.ToInt`
typeclasses.
2025-06-25 13:32:38 +00:00
Joachim Breitner
b2a8d890c1 refactor: linearNoConfusionType: use PULift, not PUnit → (#8973)
This PR refactors the juggling of universes in the linear
`noConfusionType` construction: Instead of using `PUnit.{…} → ` in the
to get the branches of `withCtorType` to the same universe level, we use
`PULift`.

This fixes https://github.com/leanprover/lean4/issues/8962, although
probably doesn’t solve all issues of that kind while level equality
checking is incomplete.
2025-06-25 09:05:03 +00:00
Joachim Breitner
9641a9ac6c feat: PULift (#8992)
This PR adds `PULift`, a more general form of `ULift` and `PLift` that
subsumes both.

Needed in #8973
2025-06-25 09:04:52 +00:00
Wojciech Rozowski
15d1d38bd9 fix: add isDefEq check in the recursive call case of solveMonoStep inside monotonicity tactic (#8978)
This PR updates the `solveMonoStep` function used in the `monotonicity`
tactic to check for definitional equality between the current goal and
the monotonicity proof obtained from a recursive call. This ensures
soundness by preventing incorrect applications when
`Lean.Order.PartialOrder` instances differ—an issue that can arise with
`mutual` blocks defined using the `partial_fixpoint` keyword, where
different `Lean.Order.CCPO` structures may be involved.

Closes https://github.com/leanprover/lean4/issues/8894.
2025-06-25 08:40:15 +00:00
Kim Morrison
94f48c3cec feat: add ToInt typeclasses for grind (#8991)
This PR adds some missing `ToInt.X` typeclass instances for `grind`.

There are still several more to add (in particular, for `ToInt.Pow`),
but I am going to perform an intermediate refactor first.
2025-06-25 05:38:15 +00:00
Kim Morrison
58c69909a1 feat: doc-strings for grind algebra classes (#8990)
This PR adds missing doc-strings for grind's internal algebra
typeclasses, for inclusion in the reference manual.
2025-06-25 04:46:44 +00:00
Kim Morrison
708c5f1d9a chore: cleanup of grind in BitVec/Lemmas (#8989) 2025-06-25 03:00:31 +00:00
Kim Morrison
af22926d53 chore: updates to (failing) grind algebra tests (#8987) 2025-06-25 02:44:59 +00:00
Mac Malone
311ae6168d feat: lake: avoid use of Lean root directories (#8981)
This PR removes Lake's usage of `lean -R` and `moduleNameOfFileName` to
pass module names to Lean. For workspace names, it now relies on
directly passing the module name through `lean --setup`. For
non-workspace modules passed to `lake lean` or `lake setup-file`, it
uses a fixed module name of `_unknown`.

This means that `lake lean` and `lake setup-file` can be successfully
and consistently used on modules that do not lie under the working
directory or the workspace root.
2025-06-25 01:04:13 +00:00
Leonardo de Moura
f1021e4537 fix: congruence proof for over-applied terms (#8983)
This PR fixes a bug in congruence proof generation in `grind` for
over-applied functions.
2025-06-24 22:04:23 +00:00
Mac Malone
ddbba944d4 fix: pass Lean CMake CI options to the Lake build (#8823)
This PR passes Lean options configured via CMake variables onto the Lake
build. For example, this will ensure CI' setting of `warningAsError` via
`LEAN_EXTRA_MAKE_OPTS` reaches Lake.
2025-06-24 11:39:29 +00:00
Kim Morrison
3e8d28ae6b feat: use grind in BitVec/Lemmas (#8967)
This PR both adds initial `@[grind]` annotations for `BitVec`, and uses
`grind` to remove many proofs from `BitVec/Lemmas`.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-06-24 10:54:43 +00:00
Joachim Breitner
9d363e3541 fix: linter.simpUnusedSimpArgs to check syntax kind (#8971)
This PR fixes `linter.simpUnusedSimpArgs` to check the syntax kind, to
not fire on `simp` calls behind macros. Fixes #8969
2025-06-24 08:31:57 +00:00
Henrik Böving
a223e92f85 chore: remove use of deprecated API (#8970) 2025-06-24 08:22:50 +00:00
Luisa Cicolini
46a7c9108f feat: add BitVec.(getElem, getLsbD, getMsbD)_(smod, sdiv, srem) (#8941)
This PR adds `BitVec.(getElem, getLsbD, getMsbD)_(smod, sdiv, srem)`
theorems to complete the API for `sdiv`, `srem`, `smod`. Even though the
rhs is not particularly succint (it's hard to find a meaning for what it
means to have "the n-th bit of the result of a signed division/modulo
operation"), these lemmas prevent the need to `unfold` of operations.

---------

Co-authored-by: Kim Morrison <477956+kim-em@users.noreply.github.com>
2025-06-24 07:09:00 +00:00
Kyle Miller
a427a8264a chore: cleanup after stage0 update (#8966)
This PR cleans up the bootstrapping code added in #8957.
2025-06-24 05:34:57 +00:00
Kim Morrison
cc493e688b feat: embed a NatModule in its IntModule completion (#8963)
This PR embeds a NatModule into its IntModule completion, which is
injective when we have AddLeftCancel, and monotone when the modules are
ordered. Also adds some (failing) grind test cases that can be verified
once `grind` uses this embedding.
2025-06-24 05:30:43 +00:00
Kim Morrison
5a9d7ae925 feat: revise grind annotations for bitwise operations (#8965)
This PR revises @[grind] annotations on Nat bitwise operations.
2025-06-24 05:16:21 +00:00
Kim Morrison
e0c2263073 chore: add @[expose] in Grind/Ring/Poly.lean (#8964)
This PR adds `@[expose]` attributes to proof terms constructed by
`grind` that need to be evaluated in the kernel.
2025-06-24 05:14:12 +00:00
Lean stage0 autoupdater
e51d2d8747 chore: update stage0 2025-06-24 05:02:20 +00:00
Kim Morrison
449bc31832 chore: adds (failing) grind algebra tests (#8961) 2025-06-24 03:51:39 +00:00
Kim Morrison
8fe068ef68 feat: move lean-pr-testing-NNNN branches to a fork (#8933)
This PR changes the CI setup to generate `lean-pr-testing-NNNN` branches
for Mathlib on the `leanprover-community/mathlib4-nightly-testing` fork,
rather than on the main repo.
2025-06-24 03:30:43 +00:00
Kim Morrison
6970d77ae4 feat: the grothendieck envelope of an ordered semiring is an ordered ring (#8959)
This PR add instances showing that the Grothendieck (i.e. additive)
envelope of a semiring is an ordered ring if the original semiring is
ordered (and satisfies ExistsAddOfLE), and in this case the embedding is
monotone.
2025-06-24 03:23:18 +00:00
Leonardo de Moura
07662aafe3 fix: better case-split for match-conditions in grind (#8958)
This PR improves the case splitting strategy used in `grind`, and
ensures `grind` also considers simple `match`-conditions for
case-splitting. Example:

```lean
example (x y : Nat)
    : 0 < match x, y with
          | 0, 0   => 1
          | _, _ => x + y := by -- x or y must be greater than 0
  grind
```
2025-06-24 02:56:50 +00:00
Kyle Miller
b28dc8c5fb feat: add configuration for let/have tactics (#8957)
This PR adds configuration options to the `let`/`have` tactic syntaxes.
For example, `let (eq := h) x := v` adds `h : x = v` to the local
context. The configuration options are the same as those for the
`let`/`have` term syntaxes.
2025-06-24 02:49:02 +00:00
Cameron Zwarich
81740da50a fix: avoid caching uses of never_extract constants in toLCNF (#8956)
This PR changes `toLCNF` to stop caching translations of expressions
upon seeing an expression marked `never_extract`. This is more
coarse-grained than it needs to be, but it is difficult to do any
better, as the new compiler's `Expr` cache is based on structural
identity (rather than the pointer identity of the old compiler).

The newly added `tests/compiler/never_extract.lean` is also converted
into a `run` tests, because during development I found the order of the
output to `stderr` to be a bit finicky. The reason for making it a
`compiler` test in the first place is that closed term decls work
slightly differently between native code and the interpreter, and it
would be good to test both, but we already have separate tests for
`never_extract` and closed term extraction.

Fixes #8944.
2025-06-24 02:04:56 +00:00
Kyle Miller
32f8a95437 fix: Lean.MVarId.deltaLocalDecl (#8955)
This PR fixes `Lean.MVarId.deltaLocalDecl`, which previously replaced
the local definition with the target.
2025-06-24 01:37:18 +00:00
Kyle Miller
71cf266cd7 feat: add Meta.letToHave and the let_to_have tactic (#8954)
This PR adds a procedure that efficiently transforms `let` expressions
into `have` expressions (`Meta.letToHave`). This is exposed as the
`let_to_have` tactic.

It uses the `withTrackingZetaDelta` technique: the expression is
typechecked, and any `let` variables that don't enter the zeta delta set
are nondependent. The procedure uses a number of heuristics to limit the
amount of typechecking performed. For example, it is ok to skip
subexpressions that do not contain fvars, mvars, or `let`s.
2025-06-24 01:33:53 +00:00
Leonardo de Moura
0941d53f6a feat: semiring normalizer in grind (#8953)
This PR implements support for normalization for commutative semirings
that do not implement `AddRightCancel`. Examples:
```lean
variable (R : Type u) [CommSemiring R]

example (a b c : R) : a * (b + c) = a * c + b * a := by grind
example (a b : R) : (a + b)^2 = a^2 + 2 * a * b + b^2 := by grind
example (a b : R) : (a + 2 * b)^2 = a^2 + 4 * a * b + 4 * b^2 := by grind
example (a b : R) : (a + 2 * b)^2 = 4 * b^2 + b * 4 * a + a^2 := by grind
```
2025-06-24 01:09:22 +00:00
Leonardo de Moura
ba07e46368 refactor: simplify semiring normalization helper theorems (#8946)
This PR simplifies the semiring normalization theorem that will be used
by `grind`.
2025-06-23 23:20:20 +00:00
Cameron Zwarich
24cbd4efbe fix: correctly handle never_extract attribute in LCNF CSE (#8952)
This PR fixes the handling of the `never_extract` attribute in the
compiler's CSE pass. There is an interesting debate to be had about
exactly how hard the compiler should try to avoid duplicating anything
that transitively uses `never_extract`, but this is the simplest form
and roughly matches the check in the old compiler (although due to
different handling of local function decls in the two compilers, the
consequences might be slightly different).

This gets half of the way to #8944.
2025-06-23 23:03:10 +00:00
Cameron Zwarich
b0269d2875 chore: share leading prefix between then/else branches (#8951) 2025-06-23 22:17:54 +00:00
Wojciech Rozowski
22cd34c341 chore: rename keywords for (co)inductive predicates and the names of the associated (co)induction principles 2025-06-23 20:40:08 +02:00
Wojciech Rozowski
b4b68415e0 chore: update stage0 2025-06-23 20:40:08 +02:00
Wojciech Rozowski
07c398e441 chore: rename keywords for (co)inductive predicates and the names of their associated (co)induction principles
chore: rename `fixpoint_induct` to `induct` and `coinduct` for (co)inductive predicates
2025-06-23 20:40:08 +02:00
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
7389 changed files with 229082 additions and 73727 deletions

14
.claude/CLAUDE.md Normal file
View File

@@ -0,0 +1,14 @@
When asked to implement new features:
* begin by reviewing existing relevant code and tests
* write comprehensive tests first (expecting that these will initially fail)
* and then iterate on the implementation until the tests pass.
To build Lean you should use `make -j$(nproc) -C build/release`.
To run a test you should use `cd tests/lean/run && ./test_single.sh example_test.lean`.
*Never* report success on a task unless you have verified both a clean build without errors, and that the relevant tests pass. You have to keep working until you have verified both of these.
All new tests should go in `tests/lean/run/`. Note that these tests don't have expected output, and just run on a success or failure basis. So you should use `#guard_msgs` to check for specific messages.
If you are not following best practices specific to this repository and the user expresses frustration, stop and ask them to help update this `.claude/CLAUDE.md` file with the missing guidance.

View File

@@ -0,0 +1,69 @@
# Release Management Command
Execute the release process for a given version by running the release checklist and following its instructions.
## Before Starting
**IMPORTANT**: Before beginning the release process, read the in-file documentation:
- Read `script/release_checklist.py` for what the checklist script does
- Read `script/release_steps.py` for what the release steps script does
These comments explain the scripts' behavior, which repositories get special handling, and how errors are handled.
## Arguments
- `version`: The version to release (e.g., v4.24.0)
## Process
1. Run `script/release_checklist.py {version}` to check the current status
2. **CRITICAL: If preliminary lean4 checks fail, STOP immediately and alert the user**
- Check for: release branch exists, CMake version correct, tag exists, release page exists, release notes exist
- **IMPORTANT**: The release page is created AUTOMATICALLY by CI after pushing the tag - DO NOT create it manually
- Do NOT create any PRs or proceed with repository updates if these checks fail
3. Create a todo list tracking all repositories that need updates
4. **CRITICAL RULE: You can ONLY run `release_steps.py` for a repository if `release_checklist.py` explicitly says to do so**
- The checklist output will say "Run `script/release_steps.py {version} {repo_name}` to create it"
- If a repository shows "🟡 Dependencies not ready", you CANNOT create a PR for it yet
- You MUST rerun `release_checklist.py` before attempting to create PRs for any new repositories
5. For each repository that the checklist says needs updating:
- Run `script/release_steps.py {version} {repo_name}` to create the PR
- Mark it complete when the PR is created
6. After creating PRs, notify the user which PRs need review and merging
7. **MANDATORY: Rerun `release_checklist.py` to check current status**
- Do this after creating each batch of PRs
- Do this after the user reports PRs have been merged
- NEVER assume a repository is ready without checking the checklist output
8. As PRs are merged and tagged, dependent repositories will become ready
9. Continue the cycle: run checklist → create PRs for ready repos → wait for merges → repeat
10. Continue until all repositories are updated and the release is complete
## Important Notes
- The `release_steps.py` script is idempotent - it's safe to rerun
- The `release_checklist.py` script is idempotent - it's safe to rerun
- Some repositories depend on others (e.g., mathlib4 depends on batteries, aesop, etc.)
- Wait for user to merge PRs before dependent repos can be updated
- Alert user if anything unusual or scary happens
- Use appropriate timeouts for long-running builds (verso can take 10+ minutes)
- ProofWidgets4 uses semantic versioning (v0.0.X) - it's okay to create and push the next sequential tag yourself when needed for a release
## PR Status Reporting
Every time you run `release_checklist.py`, you MUST:
1. Parse the output to identify ALL open PRs mentioned (lines with "✅ PR with title ... exists")
2. Provide a summary to the user listing ALL open PRs that need review
3. Group them by status:
- PRs for repositories that are blocked by dependencies (show these but note they're blocked)
- PRs for repositories that are ready to merge (highlight these)
4. Format the summary clearly with PR numbers and URLs
This summary should be provided EVERY time you run the checklist, not just after creating new PRs.
The user needs to see the complete picture of what's waiting for review.
## Error Handling
**CRITICAL**: If something goes wrong or a command fails:
- **DO NOT** try to manually reproduce the failing steps yourself
- **DO NOT** try to fix things by running git commands or other manual operations
- Both scripts are idempotent and designed to handle partial completion gracefully
- If a script continues to fail after retrying, report the error to the user and wait for instructions

6
.gitattributes vendored
View File

@@ -4,3 +4,9 @@ RELEASES.md merge=union
stage0/** binary linguist-generated
# The following file is often manually edited, so do show it in diffs
stage0/src/stdlib_flags.h -binary -linguist-generated
# These files should not have line endings translated on Windows, because
# it throws off parser tests. Later lines override earlier ones, so the
# runner code is still treated as ordinary text.
tests/lean/docparse/* eol=lf
tests/lean/docparse/*.lean eol=auto
tests/lean/docparse/*.sh eol=auto

5
.github/actionlint.yaml vendored Normal file
View File

@@ -0,0 +1,5 @@
self-hosted-runner:
labels:
- nscloud-ubuntu-22.04-amd64-4x16
- nscloud-ubuntu-22.04-amd64-8x16
- nscloud-macos-sonoma-arm64-6x14

View File

@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: actionlint
uses: raven-actions/actionlint@v2
with:

38
.github/workflows/awaiting-manual.yml vendored Normal file
View File

@@ -0,0 +1,38 @@
name: Check awaiting-manual label
on:
merge_group:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
jobs:
check-awaiting-manual:
runs-on: ubuntu-latest
steps:
- name: Check awaiting-manual label
id: check-awaiting-manual-label
if: github.event_name == 'pull_request'
uses: actions/github-script@v8
with:
script: |
const { labels, number: prNumber } = context.payload.pull_request;
const hasAwaiting = labels.some(label => label.name == "awaiting-manual");
const hasBreaks = labels.some(label => label.name == "breaks-manual");
const hasBuilds = labels.some(label => label.name == "builds-manual");
if (hasAwaiting && hasBreaks) {
core.setFailed('PR has both "awaiting-manual" and "breaks-manual" labels.');
} else if (hasAwaiting && !hasBreaks && !hasBuilds) {
core.info('PR is marked "awaiting-manual" but neither "breaks-manual" nor "builds-manual" labels are present.');
core.setOutput('awaiting', 'true');
}
- name: Wait for manual compatibility
if: github.event_name == 'pull_request' && steps.check-awaiting-manual-label.outputs.awaiting == 'true'
run: |
echo "::notice title=Awaiting manual::PR is marked 'awaiting-manual' but neither 'breaks-manual' nor 'builds-manual' labels are present."
echo "This check will remain in progress until the PR is updated with appropriate manual compatibility labels."
# Keep the job running indefinitely to show "in progress" status
while true; do
sleep 3600 # Sleep for 1 hour at a time
done

View File

@@ -12,7 +12,7 @@ jobs:
- name: Check awaiting-mathlib label
id: check-awaiting-mathlib-label
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const { labels, number: prNumber } = context.payload.pull_request;

View File

@@ -3,9 +3,6 @@ name: build-template
on:
workflow_call:
inputs:
check-level:
type: string
required: true
config:
type: string
required: true
@@ -36,7 +33,7 @@ jobs:
include: ${{fromJson(inputs.config)}}
# complete all jobs
fail-fast: false
runs-on: ${{ matrix.os }}
runs-on: ${{ endsWith(matrix.os, '-with-cache') && fromJSON(format('["{0}", "nscloud-git-mirror-1gb"]', matrix.os)) || matrix.os }}
defaults:
run:
shell: ${{ matrix.shell || 'nix develop -c bash -euxo pipefail {0}' }}
@@ -69,10 +66,16 @@ jobs:
brew install ccache tree zstd coreutils gmp libuv
if: runner.os == 'macOS'
- name: Checkout
uses: actions/checkout@v4
if: (!endsWith(matrix.os, '-with-cache'))
uses: actions/checkout@v5
with:
# the default is to use a virtual merge commit between the PR and master: just use the PR
ref: ${{ github.event.pull_request.head.sha }}
- name: Namespace Checkout
if: endsWith(matrix.os, '-with-cache')
uses: namespacelabs/nscloud-checkout-action@v7
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Open Nix shell once
run: true
if: runner.os == 'Linux'
@@ -97,30 +100,37 @@ jobs:
sudo apt-get update
sudo apt-get install -y gcc-multilib g++-multilib ccache libuv1-dev:i386 pkgconf:i386
if: matrix.cmultilib
- name: Cache
- name: Restore Cache
id: restore-cache
uses: actions/cache/restore@v4
with:
# NOTE: must be in sync with `save` below
# NOTE: must be in sync with `save` below and with `restore-cache` in `update-stage0.yml`
path: |
.ccache
${{ matrix.name == 'Linux Lake' && false && 'build/stage1/**/*.trace
${{ matrix.name == 'Linux Lake' && 'build/stage1/**/*.trace
build/stage1/**/*.olean*
build/stage1/**/*.ilean
build/stage1/**/*.ir
build/stage1/**/*.c
build/stage1/**/*.c.o*' || '' }}
key: ${{ matrix.name }}-build-v3-${{ github.sha }}
key: ${{ matrix.name }}-build-v4-${{ github.sha }}
# fall back to (latest) previous cache
restore-keys: |
${{ matrix.name }}-build-v3
${{ matrix.name }}-build-v4
# open nix-shell once for initial setup
- name: Setup
run: |
ccache --zero-stats
if: runner.os == 'Linux'
- name: Set up NPROC
- name: Set up env
run: |
echo "NPROC=$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || echo 4)" >> $GITHUB_ENV
if ! diff src/stdlib_flags.h stage0/src/stdlib_flags.h; then
echo "src/stdlib_flags.h and stage0/src/stdlib_flags.h differ, will test and pack stage 2"
echo "TARGET_STAGE=stage2" >> $GITHUB_ENV
else
echo "TARGET_STAGE=stage1" >> $GITHUB_ENV
fi
- name: Build
run: |
ulimit -c unlimited # coredumps
@@ -141,6 +151,9 @@ jobs:
if [[ -n '${{ matrix.prepare-llvm }}' ]]; then
wget -q ${{ matrix.llvm-url }}
PREPARE="$(${{ matrix.prepare-llvm }})"
if [ "$TARGET_STAGE" == "stage2" ]; then
cp -r stage1 stage2
fi
eval "OPTIONS+=($PREPARE)"
fi
if [[ -n '${{ matrix.release }}' && -n '${{ inputs.nightly }}' ]]; then
@@ -155,10 +168,28 @@ jobs:
fi
# contortion to support empty OPTIONS with old macOS bash
cmake .. --preset ${{ matrix.CMAKE_PRESET || 'release' }} -B . ${{ matrix.CMAKE_OPTIONS }} ${OPTIONS[@]+"${OPTIONS[@]}"} -DLEAN_INSTALL_PREFIX=$PWD/..
time make -j$NPROC
time make $TARGET_STAGE -j$NPROC
# Should be done as early as possible and in particular *before* "Check rebootstrap" which
# changes the state of stage1/
- name: Save Cache
# Caching on cancellation created some mysterious issues perhaps related to improper build
# shutdown
if: steps.restore-cache.outputs.cache-hit != 'true' && !cancelled()
uses: actions/cache/save@v4
with:
# NOTE: must be in sync with `restore` above
path: |
.ccache
${{ matrix.name == 'Linux Lake' && 'build/stage1/**/*.trace
build/stage1/**/*.olean*
build/stage1/**/*.ilean
build/stage1/**/*.ir
build/stage1/**/*.c
build/stage1/**/*.c.o*' || '' }}
key: ${{ steps.restore-cache.outputs.cache-primary-key }}
- name: Install
run: |
make -C build install
make -C build/$TARGET_STAGE install
- name: Check Binaries
run: ${{ matrix.binary-check }} lean-*/bin/* || true
- name: Count binary symbols
@@ -189,18 +220,18 @@ jobs:
path: pack/*
- name: Lean stats
run: |
build/stage1/bin/lean --stats src/Lean.lean
build/$TARGET_STAGE/bin/lean --stats src/Lean.lean -Dexperimental.module=true
if: ${{ !matrix.cross }}
- name: Test
id: test
run: |
ulimit -c unlimited # coredumps
time ctest --preset ${{ matrix.CMAKE_PRESET || 'release' }} --test-dir build/stage1 -j$NPROC --output-junit test-results.xml ${{ matrix.CTEST_OPTIONS }}
if: (matrix.wasm || !matrix.cross) && (inputs.check-level >= 1 || matrix.test)
time ctest --preset ${{ matrix.CMAKE_PRESET || 'release' }} --test-dir build/$TARGET_STAGE -j$NPROC --output-junit test-results.xml ${{ matrix.CTEST_OPTIONS }}
if: matrix.test
- name: Test Summary
uses: test-summary/action@v2
with:
paths: build/stage1/test-results.xml
paths: build/${{ env.TARGET_STAGE }}/test-results.xml
# prefix `if` above with `always` so it's run even if tests failed
if: always() && steps.test.conclusion != 'skipped'
- name: Check Test Binary
@@ -225,8 +256,13 @@ jobs:
if: matrix.test-speedcenter
- name: Check rebootstrap
run: |
# clean rebuild in case of Makefile changes
make -C build update-stage0 && rm -rf build/stage* && make -C build -j$NPROC
set -e
# clean rebuild in case of Makefile changes/Lake does not detect uncommited stage 0
# changes yet
make -C build update-stage0
make -C build/stage1 clean-stdlib
time make -C build -j$NPROC
time ctest --preset ${{ matrix.CMAKE_PRESET || 'release' }} --test-dir build/stage1 -j$NPROC
if: matrix.check-rebootstrap
- name: CCache stats
if: always()
@@ -238,16 +274,3 @@ jobs:
progbin="$(file $c | sed "s/.*execfn: '\([^']*\)'.*/\1/")"
echo bt | $GDB/bin/gdb -q $progbin $c || true
done
- name: Save Cache
if: always() && steps.restore-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
# NOTE: must be in sync with `restore` above
path: |
.ccache
${{ matrix.name == 'Linux Lake' && false && 'build/stage1/**/*.trace
build/stage1/**/*.olean*
build/stage1/**/*.ilean
build/stage1/**/*.c
build/stage1/**/*.c.o*' || '' }}
key: ${{ steps.restore-cache.outputs.cache-primary-key }}

View File

@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
# the default is to use a virtual merge commit between the PR and master: just use the PR
ref: ${{ github.event.pull_request.head.sha }}

View File

@@ -8,11 +8,11 @@ jobs:
check-stage0-on-queue:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha }}
filter: blob:none
fetch-depth: 0
filter: tree:0
- name: Find base commit
if: github.event_name == 'pull_request'
@@ -31,7 +31,7 @@ jobs:
- if: github.event_name == 'pull_request'
name: Set label
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const { owner, repo, number: issue_number } = context.issue;

View File

@@ -31,10 +31,6 @@ jobs:
configure:
runs-on: ubuntu-latest
outputs:
# 0: PRs without special label
# 1: PRs with `merge-ci` label, merge queue checks, master commits
# 2: PRs with `release-ci` label, releases (incl. nightlies)
check-level: ${{ steps.set-level.outputs.check-level }}
# The build matrix, dynamically generated here
matrix: ${{ steps.set-matrix.outputs.matrix }}
# secondary build jobs that should not block the CI success/merge queue
@@ -54,7 +50,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
# don't schedule nightlies on forks
if: github.event_name == 'schedule' && github.repository == 'leanprover/lean4' || inputs.action == 'release nightly'
- name: Set Nightly
@@ -110,6 +106,9 @@ jobs:
TAG_NAME="${GITHUB_REF##*/}"
echo "RELEASE_TAG=$TAG_NAME" >> "$GITHUB_OUTPUT"
# 0: PRs without special label
# 1: PRs with `merge-ci` label, merge queue checks, master commits
# 2: PRs with `release-ci` label, releases (incl. nightlies)
- name: Set check level
id: set-level
# We do not use github.event.pull_request.labels.*.name here because
@@ -117,6 +116,7 @@ jobs:
# rerun the workflow run after setting the `release-ci`/`merge-ci` labels.
run: |
check_level=0
fast=false
if [[ -n "${{ steps.set-nightly.outputs.nightly }}" || -n "${{ steps.set-release.outputs.RELEASE_TAG }}" || -n "${{ steps.set-release-custom.outputs.RELEASE_TAG }}" ]]; then
check_level=2
@@ -129,29 +129,36 @@ jobs:
elif echo "$labels" | grep -q "merge-ci"; then
check_level=1
fi
if echo "$labels" | grep -q "fast-ci"; then
fast=true
fi
fi
echo "check-level=$check_level" >> "$GITHUB_OUTPUT"
echo "fast=$fast" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ github.token }}
- name: Configure build matrix
id: set-matrix
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const level = ${{ steps.set-level.outputs.check-level }};
console.log(`level: ${level}`);
const fast = ${{ steps.set-level.outputs.fast }};
console.log(`level: ${level}, fast: ${fast}`);
// use large runners where available (original repo)
let large = ${{ github.repository == 'leanprover/lean4' }};
const isPr = "${{ github.event_name }}" == "pull_request";
const isPushToMaster = "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == "master";
let matrix = [
/* TODO: to be updated to new LLVM
{
"name": "Linux LLVM",
"os": "ubuntu-latest",
"release": false,
"check-level": 2,
"enabled": level >= 2,
"test": true,
"shell": "nix develop .#oldGlibc -c bash -euxo pipefail {0}",
"llvm-url": "https://github.com/leanprover/lean-llvm/releases/download/19.1.2/lean-llvm-x86_64-linux-gnu.tar.zst",
"prepare-llvm": "../script/prepare-llvm-linux.sh lean-llvm*",
@@ -164,46 +171,51 @@ jobs:
{
// portable release build: use channel with older glibc (2.26)
"name": "Linux release",
"os": large && level < 2 ? "nscloud-ubuntu-22.04-amd64-4x16" : "ubuntu-latest",
// usually not a bottleneck so make exclusive to `fast-ci`
"os": large && fast ? "nscloud-ubuntu-22.04-amd64-8x16-with-cache" : "ubuntu-latest",
"release": true,
// Special handling for release jobs. We want:
// 1. To run it in PRs so developrs get PR toolchains (so secondary is sufficient)
// 1. To run it in PRs so developers get PR toolchains (so secondary without tests is sufficient)
// 2. To skip it in merge queues as it takes longer than the
// Linux lake build and adds little value in the merge queue
// 3. To run it in release (obviously)
"check-level": isPr ? 0 : 2,
"secondary": isPr,
// 4. To run it for pushes to master so that pushes to master have a Linux toolchain
// available as an artifact for Grove to use.
"enabled": isPr || level != 1 || isPushToMaster,
"test": level >= 1,
"secondary": level == 0,
"shell": "nix develop .#oldGlibc -c bash -euxo pipefail {0}",
"llvm-url": "https://github.com/leanprover/lean-llvm/releases/download/19.1.2/lean-llvm-x86_64-linux-gnu.tar.zst",
"prepare-llvm": "../script/prepare-llvm-linux.sh lean-llvm*",
"binary-check": "ldd -v",
// foreign code may be linked against more recent glibc
"CTEST_OPTIONS": "-E 'foreign'"
"CTEST_OPTIONS": "-E 'foreign'",
},
{
"name": "Linux Lake",
"os": large ? "nscloud-ubuntu-22.04-amd64-8x16" : "ubuntu-latest",
"check-level": 0,
"test": true,
"os": large ? "nscloud-ubuntu-22.04-amd64-8x16-with-cache" : "ubuntu-latest",
"enabled": true,
"check-rebootstrap": level >= 1,
"check-stage3": level >= 2,
"test": true,
// NOTE: `test-speedcenter` currently seems to be broken on `ubuntu-latest`
"test-speedcenter": large && level >= 2,
"CMAKE_OPTIONS": "-DUSE_LAKE=ON",
// We are not warning-free yet on all platforms, start here
"CMAKE_OPTIONS": "-DLEAN_EXTRA_CXX_FLAGS=-Werror",
},
{
"name": "Linux Reldebug",
"os": "ubuntu-latest",
"check-level": 2,
"enabled": level >= 2,
"test": true,
"CMAKE_PRESET": "reldebug",
// exclude seriously slow/stackoverflowing tests
"CTEST_OPTIONS": "-E 'interactivetest|leanpkgtest|laketest|benchtest|bv_bitblast_stress|3807'"
},
// TODO: suddenly started failing in CI
/*{
"name": "Linux fsanitize",
"os": "ubuntu-latest",
"check-level": 2,
"enabled": level >= 2,
"test": true,
// turn off custom allocator & symbolic functions to make LSAN do its magic
"CMAKE_PRESET": "sanitize",
// exclude seriously slow/problematic tests (laketests crash)
@@ -211,19 +223,21 @@ jobs:
},*/
{
"name": "macOS",
"os": "macos-13",
"os": "macos-15-intel",
"release": true,
"check-level": 2,
"test": false, // Tier 2 platform
"enabled": level >= 2,
"shell": "bash -euxo pipefail {0}",
"llvm-url": "https://github.com/leanprover/lean-llvm/releases/download/19.1.2/lean-llvm-x86_64-apple-darwin.tar.zst",
"prepare-llvm": "../script/prepare-llvm-macos.sh lean-llvm*",
"binary-check": "otool -L",
"tar": "gtar" // https://github.com/actions/runner-images/issues/2619
"tar": "gtar", // https://github.com/actions/runner-images/issues/2619
"CTEST_OPTIONS": "-E 'leanlaketest_hello'", // started failing from unpack
},
{
"name": "macOS aarch64",
// standard GH runner only comes with 7GB so use large runner if possible
"os": large ? "nscloud-macos-sonoma-arm64-6x14" : "macos-14",
// standard GH runner only comes with 7GB so use large runner if possible when running tests
"os": large && (fast || level >= 1) ? "nscloud-macos-sequoia-arm64-6x14" : "macos-15",
"CMAKE_OPTIONS": "-DLEAN_INSTALL_SUFFIX=-darwin_aarch64",
"release": true,
"shell": "bash -euxo pipefail {0}",
@@ -231,32 +245,33 @@ jobs:
"prepare-llvm": "../script/prepare-llvm-macos.sh lean-llvm*",
"binary-check": "otool -L",
"tar": "gtar", // https://github.com/actions/runner-images/issues/2619
// See above for release job levels
"check-level": isPr ? 0 : 2,
"secondary": isPr,
// See "Linux release" for release job levels; Grove is not a concern here
"enabled": isPr || level != 1,
"test": level >= 1,
"secondary": level == 0,
},
{
"name": "Windows",
"os": "windows-2022",
"os": large && (fast || level == 2) ? "namespace-profile-windows-amd64-4x16" : "windows-2022",
"release": true,
"check-level": 2,
"enabled": level >= 2,
"test": true,
"shell": "msys2 {0}",
"CMAKE_OPTIONS": "-G \"Unix Makefiles\"",
// for reasons unknown, interactivetests are flaky on Windows
"CTEST_OPTIONS": "--repeat until-pass:2",
"llvm-url": "https://github.com/leanprover/lean-llvm/releases/download/19.1.2/lean-llvm-x86_64-w64-windows-gnu.tar.zst",
"prepare-llvm": "../script/prepare-llvm-mingw.sh lean-llvm*",
"binary-check": "ldd"
"binary-check": "ldd",
},
{
"name": "Linux aarch64",
"os": "nscloud-ubuntu-22.04-arm64-4x16",
"CMAKE_OPTIONS": "-DLEAN_INSTALL_SUFFIX=-linux_aarch64",
"release": true,
"check-level": 2,
"enabled": level >= 2,
"test": true,
"shell": "nix develop .#oldGlibcAArch -c bash -euxo pipefail {0}",
"llvm-url": "https://github.com/leanprover/lean-llvm/releases/download/19.1.2/lean-llvm-aarch64-linux-gnu.tar.zst",
"prepare-llvm": "../script/prepare-llvm-linux.sh lean-llvm*"
"prepare-llvm": "../script/prepare-llvm-linux.sh lean-llvm*",
},
// Started running out of memory building expensive modules, a 2GB heap is just not that much even before fragmentation
//{
@@ -266,7 +281,7 @@ jobs:
// "CMAKE_OPTIONS": "-DSTAGE0_USE_GMP=OFF -DSTAGE0_LEAN_EXTRA_CXX_FLAGS='-m32' -DSTAGE0_LEANC_OPTS='-m32' -DSTAGE0_MMAP=OFF -DUSE_GMP=OFF -DLEAN_EXTRA_CXX_FLAGS='-m32' -DLEANC_OPTS='-m32' -DMMAP=OFF -DLEAN_INSTALL_SUFFIX=-linux_x86 -DCMAKE_LIBRARY_PATH=/usr/lib/i386-linux-gnu/ -DSTAGE0_CMAKE_LIBRARY_PATH=/usr/lib/i386-linux-gnu/ -DPKG_CONFIG_EXECUTABLE=/usr/bin/i386-linux-gnu-pkg-config",
// "cmultilib": true,
// "release": true,
// "check-level": 2,
// "enabled": level >= 2,
// "cross": true,
// "shell": "bash -euxo pipefail {0}"
//}
@@ -278,15 +293,21 @@ jobs:
// "wasm": true,
// "cmultilib": true,
// "release": true,
// "check-level": 2,
// "enabled": level >= 2,
// "cross": true,
// "shell": "bash -euxo pipefail {0}",
// // Just a few selected tests because wasm is slow
// "CTEST_OPTIONS": "-R \"leantest_1007\\.lean|leantest_Format\\.lean|leanruntest\\_1037.lean|leanruntest_ac_rfl\\.lean|leanruntest_tempfile.lean\\.|leanruntest_libuv\\.lean\""
// }
];
for (const job of matrix) {
if (job["prepare-llvm"]) {
// `USE_LAKE` is not compatible with `prepare-llvm` currently
job["CMAKE_OPTIONS"] = (job["CMAKE_OPTIONS"] ? job["CMAKE_OPTIONS"] + " " : "") + "-DUSE_LAKE=OFF";
}
}
console.log(`matrix:\n${JSON.stringify(matrix, null, 2)}`);
matrix = matrix.filter((job) => level >= job["check-level"]);
matrix = matrix.filter((job) => job["enabled"]);
core.setOutput('matrix', matrix.filter((job) => !job["secondary"]));
core.setOutput('matrix-secondary', matrix.filter((job) => job["secondary"]));
@@ -296,7 +317,6 @@ jobs:
uses: ./.github/workflows/build-template.yml
with:
config: ${{needs.configure.outputs.matrix}}
check-level: ${{ needs.configure.outputs.check-level }}
nightly: ${{ needs.configure.outputs.nightly }}
LEAN_VERSION_MAJOR: ${{ needs.configure.outputs.LEAN_VERSION_MAJOR }}
LEAN_VERSION_MINOR: ${{ needs.configure.outputs.LEAN_VERSION_MINOR }}
@@ -312,7 +332,6 @@ jobs:
uses: ./.github/workflows/build-template.yml
with:
config: ${{needs.configure.outputs.matrix-secondary}}
check-level: ${{ needs.configure.outputs.check-level }}
nightly: ${{ needs.configure.outputs.nightly }}
LEAN_VERSION_MAJOR: ${{ needs.configure.outputs.LEAN_VERSION_MAJOR }}
LEAN_VERSION_MINOR: ${{ needs.configure.outputs.LEAN_VERSION_MINOR }}
@@ -343,7 +362,7 @@ jobs:
content: |
A build of `${{ github.ref_name }}`, triggered by event `${{ github.event_name }}`, [failed](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}).
- if: contains(needs.*.result, 'failure')
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
core.setFailed('Some jobs failed')
@@ -356,11 +375,11 @@ jobs:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v5
with:
path: artifacts
- name: Release
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631
uses: softprops/action-gh-release@6cbd405e2c4e67a21c47fa9e383d020e4e28b836
with:
files: artifacts/*/*
fail_on_unmatched_files: true
@@ -381,12 +400,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
# needed for tagging
fetch-depth: 0
# Doesn't seem to be working when additionally fetching from lean4-nightly
#filter: tree:0
token: ${{ secrets.PUSH_NIGHTLY_TOKEN }}
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v5
with:
path: artifacts
- name: Prepare Nightly Release
@@ -404,7 +425,7 @@ jobs:
echo -e "\n*Full commit log*\n" >> diff.md
git log --oneline "$last_tag"..HEAD | sed 's/^/* /' >> diff.md
- name: Release Nightly
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631
uses: softprops/action-gh-release@6cbd405e2c4e67a21c47fa9e383d020e4e28b836
with:
body_path: diff.md
prerelease: true
@@ -421,6 +442,6 @@ jobs:
GITHUB_TOKEN: ${{ secrets.RELEASE_INDEX_TOKEN }}
- name: Update toolchain on mathlib4's nightly-testing branch
run: |
gh workflow -R leanprover-community/mathlib4 run nightly_bump_toolchain.yml
gh workflow -R leanprover-community/mathlib4-nightly-testing run nightly_bump_toolchain.yml
env:
GITHUB_TOKEN: ${{ secrets.MATHLIB4_BOT }}

View File

@@ -6,7 +6,7 @@ jobs:
check-lean-files:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Verify .lean files start with a copyright header.
run: |

161
.github/workflows/grove.yml vendored Normal file
View File

@@ -0,0 +1,161 @@
name: Grove
on:
workflow_run: # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run
workflows: [CI]
types: [completed]
permissions:
pull-requests: write
jobs:
grove-build:
runs-on: ubuntu-latest
if: github.event.workflow_run.conclusion == 'success' && github.repository == 'leanprover/lean4'
steps:
- name: Retrieve information about the original workflow
uses: potiuk/get-workflow-origin@v1_1 # https://github.com/marketplace/actions/get-workflow-origin
# This action is deprecated and archived, but it seems hard to find a
# better solution for getting the PR number
# see https://github.com/orgs/community/discussions/25220 for some discussion
id: workflow-info
with:
token: ${{ secrets.GITHUB_TOKEN }}
sourceRunId: ${{ github.event.workflow_run.id }}
- name: Check if should run
id: should-run
run: |
# Check if it's a push to master (no PR number and target branch is master)
if [ -z "${{ steps.workflow-info.outputs.pullRequestNumber }}" ]; then
if [ "${{ github.event.workflow_run.head_branch }}" = "master" ]; then
echo "Push to master detected. Running Grove."
echo "should-run=true" >> "$GITHUB_OUTPUT"
else
echo "Push to non-master branch, skipping"
echo "should-run=false" >> "$GITHUB_OUTPUT"
fi
else
# Check if it's a PR with grove label
PR_LABELS='${{ steps.workflow-info.outputs.pullRequestLabels }}'
if echo "$PR_LABELS" | grep -q '"grove"'; then
echo "PR with grove label detected. Running Grove."
echo "should-run=true" >> "$GITHUB_OUTPUT"
else
echo "PR without grove label, skipping"
echo "should-run=false" >> "$GITHUB_OUTPUT"
fi
fi
- name: Fetch upstream invalidated facts
if: ${{ steps.should-run.outputs.should-run == 'true' && steps.workflow-info.outputs.pullRequestNumber != '' }}
id: fetch-upstream
uses: TwoFx/grove-action/fetch-upstream@v0.4
with:
artifact-name: grove-invalidated-facts
base-ref: master
- name: Download toolchain for this commit
if: ${{ steps.should-run.outputs.should-run == 'true' }}
id: download-toolchain
uses: dawidd6/action-download-artifact@v11
with:
commit: ${{ steps.workflow-info.outputs.sourceHeadSha }}
workflow: ci.yml
path: artifacts
name: "build-Linux release"
name_is_regexp: true
- name: Unpack toolchain
if: ${{ steps.should-run.outputs.should-run == 'true' }}
id: unpack-toolchain
run: |
cd artifacts
# Find the tar.zst file
TAR_FILE=$(find . -name "lean-*.tar.zst" -type f | head -1)
if [ -z "$TAR_FILE" ]; then
echo "Error: No lean-*.tar.zst file found"
exit 1
fi
echo "Found archive: $TAR_FILE"
# Extract the archive
tar --zstd -xf "$TAR_FILE"
# Find the extracted directory name
LEAN_DIR=$(find . -maxdepth 1 -name "lean-*" -type d | head -1)
if [ -z "$LEAN_DIR" ]; then
echo "Error: No lean-* directory found after extraction"
exit 1
fi
echo "Extracted directory: $LEAN_DIR"
echo "lean-dir=$LEAN_DIR" >> "$GITHUB_OUTPUT"
- name: Build
if: ${{ steps.should-run.outputs.should-run == 'true' }}
id: build
uses: TwoFx/grove-action/build@v0.4
with:
project-path: doc/std/grove
script-name: grove-stdlib
invalidated-facts-artifact-name: grove-invalidated-facts
comment-artifact-name: grove-comment
toolchain-id: lean4
toolchain-path: artifacts/${{ steps.unpack-toolchain.outputs.lean-dir }}
project-ref: ${{ steps.workflow-info.outputs.sourceHeadSha }}
# deploy-alias computes a URL component for the PR preview. This
# is so we can have a stable name to use for feedback on draft
# material.
- id: deploy-alias
if: ${{ steps.should-run.outputs.should-run == 'true' }}
uses: actions/github-script@v8
name: Compute Alias
with:
result-encoding: string
script: |
if (process.env.PR) {
return `pr-${process.env.PR}`
} else {
return 'deploy-preview-main';
}
env:
PR: ${{ steps.workflow-info.outputs.pullRequestNumber }}
- name: Deploy to Netlify
if: ${{ steps.should-run.outputs.should-run == 'true' }}
id: deploy-draft
uses: nwtgck/actions-netlify@v3.0
with:
publish-dir: ${{ steps.build.outputs.out-path }}
production-deploy: false
github-token: ${{ secrets.GITHUB_TOKEN }}
alias: ${{ steps.deploy-alias.outputs.result }}
enable-commit-comment: false
enable-pull-request-comment: false
fails-without-credentials: true
enable-github-deployment: false
enable-commit-status: false
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: "1cacfa39-a11c-467c-99e7-2e01d7b4089e"
# actions-netlify cannot add deploy links to a PR because it assumes a
# pull_request context, not a workflow_run context, see
# https://github.com/nwtgck/actions-netlify/issues/545
# We work around by using a comment to post the latest link
- name: "Comment on PR with preview links"
uses: marocchino/sticky-pull-request-comment@v2
if: ${{ steps.should-run.outputs.should-run == 'true' && steps.workflow-info.outputs.pullRequestNumber != '' }}
with:
number: ${{ env.PR_NUMBER }}
header: preview-comment
recreate: true
message: |
[Grove](${{ steps.deploy-draft.outputs.deploy-url }}) for revision ${{ steps.workflow-info.outputs.sourceHeadSha }}.
${{ steps.build.outputs.comment-text }}
env:
PR_NUMBER: ${{ steps.workflow-info.outputs.pullRequestNumber }}
PR_HEADSHA: ${{ steps.workflow-info.outputs.sourceHeadSha }}

View File

@@ -17,7 +17,7 @@ jobs:
steps:
- name: Add label based on comment
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |

View File

@@ -11,7 +11,7 @@ jobs:
steps:
- name: Check PR body
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const { title, body, labels, draft } = context.payload.pull_request;

View File

@@ -34,7 +34,7 @@ jobs:
- name: Download artifact from the previous workflow.
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
id: download-artifact
uses: dawidd6/action-download-artifact@v10 # https://github.com/marketplace/actions/download-workflow-artifact
uses: dawidd6/action-download-artifact@v11 # https://github.com/marketplace/actions/download-workflow-artifact
with:
run_id: ${{ github.event.workflow_run.id }}
path: artifacts
@@ -48,17 +48,17 @@ jobs:
git -C lean4.git remote add origin https://github.com/${{ github.repository_owner }}/lean4.git
git -C lean4.git fetch -n origin master
git -C lean4.git fetch -n origin "${{ steps.workflow-info.outputs.sourceHeadSha }}"
# Create both the original tag and the SHA-suffixed tag
SHORT_SHA="${{ steps.workflow-info.outputs.sourceHeadSha }}"
SHORT_SHA="${SHORT_SHA:0:7}"
# Export the short SHA for use in subsequent steps
echo "SHORT_SHA=${SHORT_SHA}" >> "$GITHUB_ENV"
git -C lean4.git tag -f pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }} "${{ steps.workflow-info.outputs.sourceHeadSha }}"
git -C lean4.git tag -f pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}-"${SHORT_SHA}" "${{ steps.workflow-info.outputs.sourceHeadSha }}"
git -C lean4.git remote add pr-releases https://foo:'${{ secrets.PR_RELEASES_TOKEN }}'@github.com/${{ github.repository_owner }}/lean4-pr-releases.git
git -C lean4.git push -f pr-releases pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}
git -C lean4.git push -f pr-releases pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}-"${SHORT_SHA}"
@@ -71,7 +71,7 @@ jobs:
GH_TOKEN: ${{ secrets.PR_RELEASES_TOKEN }}
- name: Release (short format)
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631
uses: softprops/action-gh-release@6cbd405e2c4e67a21c47fa9e383d020e4e28b836
with:
name: Release for PR ${{ steps.workflow-info.outputs.pullRequestNumber }}
# There are coredumps files here as well, but all in deeper subdirectories.
@@ -86,7 +86,7 @@ jobs:
- name: Release (SHA-suffixed format)
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631
uses: softprops/action-gh-release@6cbd405e2c4e67a21c47fa9e383d020e4e28b836
with:
name: Release for PR ${{ steps.workflow-info.outputs.pullRequestNumber }} (${{ steps.workflow-info.outputs.sourceHeadSha }})
# There are coredumps files here as well, but all in deeper subdirectories.
@@ -101,7 +101,7 @@ jobs:
- name: Report release status (short format)
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
await github.rest.repos.createCommitStatus({
@@ -115,7 +115,7 @@ jobs:
- name: Report release status (SHA-suffixed format)
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
await github.rest.repos.createCommitStatus({
@@ -129,7 +129,7 @@ jobs:
- name: Add label
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
await github.rest.issues.addLabels({
@@ -151,10 +151,10 @@ jobs:
- name: 'Setup jq'
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: dcarbone/install-jq-action@v3.1.1
uses: dcarbone/install-jq-action@v3.2.0
# Check that the most recently nightly coincides with 'git merge-base HEAD master'
- name: Check merge-base and nightly-testing-YYYY-MM-DD
- name: Check merge-base and nightly-testing-YYYY-MM-DD for Mathlib/Batteries
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
id: ready
run: |
@@ -167,7 +167,7 @@ jobs:
echo "The merge base of this PR coincides with the nightly release"
BATTERIES_REMOTE_TAGS="$(git ls-remote https://github.com/leanprover-community/batteries.git nightly-testing-"$MOST_RECENT_NIGHTLY")"
MATHLIB_REMOTE_TAGS="$(git ls-remote https://github.com/leanprover-community/mathlib4.git nightly-testing-"$MOST_RECENT_NIGHTLY")"
MATHLIB_REMOTE_TAGS="$(git ls-remote https://github.com/leanprover-community/mathlib4-nightly-testing.git nightly-testing-"$MOST_RECENT_NIGHTLY")"
if [[ -n "$BATTERIES_REMOTE_TAGS" ]]; then
echo "... and Batteries has a 'nightly-testing-$MOST_RECENT_NIGHTLY' tag."
@@ -183,7 +183,6 @@ jobs:
echo "... but Batteries does not yet have a 'nightly-testing-$MOST_RECENT_NIGHTLY' tag."
MESSAGE="- ❗ Batteries CI can not be attempted yet, as the \`nightly-testing-$MOST_RECENT_NIGHTLY\` tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto \`nightly-with-mathlib\`, Batteries CI should run now."
fi
else
echo "The most recently nightly tag on this branch has SHA: $NIGHTLY_SHA"
echo "but 'git merge-base origin/master HEAD' reported: $MERGE_BASE_SHA"
@@ -201,7 +200,7 @@ jobs:
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/leanprover/lean4/issues/${{ steps.workflow-info.outputs.pullRequestNumber }}/labels" \
| jq -r '.[].name')"
if echo "$LABELS" | grep -q "^force-mathlib-ci$"; then
echo "force-mathlib-ci label detected, forcing CI despite issues"
MESSAGE="Forcing Mathlib CI because the \`force-mathlib-ci\` label is present, despite problem: $MESSAGE"
@@ -265,9 +264,111 @@ jobs:
echo "mathlib_ready=true" >> "$GITHUB_OUTPUT"
fi
- name: Check merge-base and nightly-testing-YYYY-MM-DD for reference manual
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
id: reference-manual-ready
run: |
echo "Most recent nightly release in your branch: $MOST_RECENT_NIGHTLY"
NIGHTLY_SHA=$(git -C lean4.git rev-parse "nightly-$MOST_RECENT_NIGHTLY^{commit}")
echo "SHA of most recent nightly release: $NIGHTLY_SHA"
MERGE_BASE_SHA=$(git -C lean4.git merge-base origin/master "${{ steps.workflow-info.outputs.sourceHeadSha }}")
echo "SHA of merge-base: $MERGE_BASE_SHA"
if [ "$NIGHTLY_SHA" = "$MERGE_BASE_SHA" ]; then
echo "The merge base of this PR coincides with the nightly release"
MANUAL_REMOTE_TAGS="$(git ls-remote https://github.com/leanprover/reference-manual.git nightly-testing-"$MOST_RECENT_NIGHTLY")"
if [[ -n "$MANUAL_REMOTE_TAGS" ]]; then
echo "... and the reference manual has a 'nightly-testing-$MOST_RECENT_NIGHTLY' tag."
MESSAGE=""
else
echo "... but the reference manual does not yet have a 'nightly-testing-$MOST_RECENT_NIGHTLY' tag."
MESSAGE="- ❗ Reference manual CI can not be attempted yet, as the \`nightly-testing-$MOST_RECENT_NIGHTLY\` tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto \`nightly-with-manual\`, reference manual CI should run now."
fi
else
echo "The most recently nightly tag on this branch has SHA: $NIGHTLY_SHA"
echo "but 'git merge-base origin/master HEAD' reported: $MERGE_BASE_SHA"
git -C lean4.git log -10 origin/master
git -C lean4.git fetch origin nightly-with-manual
NIGHTLY_WITH_MANUAL_SHA="$(git -C lean4.git rev-parse "origin/nightly-with-manual")"
MESSAGE="- ❗ Reference manual CI will not be attempted unless your PR branches off the \`nightly-with-manual\` branch. Try \`git rebase $MERGE_BASE_SHA --onto $NIGHTLY_WITH_MANUAL_SHA\`."
fi
if [[ -n "$MESSAGE" ]]; then
# Check if force-manual-ci label is present
LABELS="$(curl --retry 3 --location --silent \
-H "Authorization: token ${{ secrets.MANUAL_COMMENT_BOT }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/leanprover/lean4/issues/${{ steps.workflow-info.outputs.pullRequestNumber }}/labels" \
| jq -r '.[].name')"
if echo "$LABELS" | grep -q "^force-manual-ci$"; then
echo "force-manual-ci label detected, forcing CI despite issues"
MESSAGE="Forcing reference manual CI because the \`force-manual-ci\` label is present, despite problem: $MESSAGE"
FORCE_CI=true
else
MESSAGE="$MESSAGE You can force reference manual CI using the \`force-manual-ci\` label."
fi
echo "Checking existing messages"
# The code for updating comments is duplicated in the reference manual's
# scripts/lean-pr-testing-comments.sh
# so keep in sync
# Use GitHub API to check if a comment already exists
existing_comment="$(curl --retry 3 --location --silent \
-H "Authorization: token ${{ secrets.MANUAL_COMMENT_BOT }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/leanprover/lean4/issues/${{ steps.workflow-info.outputs.pullRequestNumber }}/comments" \
| jq 'first(.[] | select(.body | test("^- . Manual") or startswith("Reference manual CI status")) | select(.user.login == "leanprover-bot"))')"
existing_comment_id="$(echo "$existing_comment" | jq -r .id)"
existing_comment_body="$(echo "$existing_comment" | jq -r .body)"
if [[ "$existing_comment_body" != *"$MESSAGE"* ]]; then
MESSAGE="$MESSAGE ($(date "+%Y-%m-%d %H:%M:%S"))"
echo "Posting message to the comments: $MESSAGE"
# Append new result to the existing comment or post a new comment
# It's essential we use the MANUAL_COMMENT_BOT token here, so that reference manual CI can subsequently edit the comment.
if [ -z "$existing_comment_id" ]; then
INTRO="Reference manual CI status:"
# Post new comment with a bullet point
echo "Posting as new comment at leanprover/lean4/issues/${{ steps.workflow-info.outputs.pullRequestNumber }}/comments"
curl -L -s \
-X POST \
-H "Authorization: token ${{ secrets.MANUAL_COMMENT_BOT }}" \
-H "Accept: application/vnd.github.v3+json" \
-d "$(jq --null-input --arg intro "$INTRO" --arg val "$MESSAGE" '{"body":($intro + "\n" + $val)}')" \
"https://api.github.com/repos/leanprover/lean4/issues/${{ steps.workflow-info.outputs.pullRequestNumber }}/comments"
else
# Append new result to the existing comment
echo "Appending to existing comment at leanprover/lean4/issues/${{ steps.workflow-info.outputs.pullRequestNumber }}/comments"
curl -L -s \
-X PATCH \
-H "Authorization: token ${{ secrets.MANUAL_COMMENT_BOT }}" \
-H "Accept: application/vnd.github.v3+json" \
-d "$(jq --null-input --arg existing "$existing_comment_body" --arg message "$MESSAGE" '{"body":($existing + "\n" + $message)}')" \
"https://api.github.com/repos/leanprover/lean4/issues/comments/$existing_comment_id"
fi
else
echo "The message already exists in the comment body."
fi
if [[ "$FORCE_CI" == "true" ]]; then
echo "manual_ready=true" >> "$GITHUB_OUTPUT"
else
echo "manual_ready=false" >> "$GITHUB_OUTPUT"
fi
else
echo "manual_ready=true" >> "$GITHUB_OUTPUT"
fi
- name: Report mathlib base
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' && steps.ready.outputs.mathlib_ready == 'true' }}
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const description =
@@ -294,12 +395,13 @@ jobs:
# Checkout the Batteries repository with all branches
- name: Checkout Batteries repository
if: steps.workflow-info.outputs.pullRequestNumber != '' && steps.ready.outputs.mathlib_ready == 'true'
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: leanprover-community/batteries
token: ${{ secrets.MATHLIB4_BOT }}
ref: nightly-testing
fetch-depth: 0 # This ensures we check out all tags and branches.
filter: tree:0
- name: Check if tag exists
if: steps.workflow-info.outputs.pullRequestNumber != '' && steps.ready.outputs.mathlib_ready == 'true'
@@ -324,7 +426,7 @@ jobs:
git switch -c lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }} "$BASE"
echo "leanprover/lean4-pr-releases:pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}-${{ env.SHORT_SHA }}" > lean-toolchain
git add lean-toolchain
git commit -m "Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
git commit --allow-empty -m "Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
else
echo "Branch already exists, updating lean-toolchain."
git switch lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }}
@@ -333,7 +435,7 @@ jobs:
git merge "$BASE" --strategy-option ours --no-commit --allow-unrelated-histories
echo "leanprover/lean4-pr-releases:pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}-${{ env.SHORT_SHA }}" > lean-toolchain
git add lean-toolchain
git commit -m "Update lean-toolchain for https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
git commit --allow-empty -m "Update lean-toolchain for https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
fi
- name: Push changes
@@ -353,12 +455,13 @@ jobs:
# Checkout the mathlib4 repository with all branches
- name: Checkout mathlib4 repository
if: steps.workflow-info.outputs.pullRequestNumber != '' && steps.ready.outputs.mathlib_ready == 'true'
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: leanprover-community/mathlib4
repository: leanprover-community/mathlib4-nightly-testing
token: ${{ secrets.MATHLIB4_BOT }}
ref: nightly-testing
fetch-depth: 0 # This ensures we check out all tags and branches.
filter: tree:0
- name: install elan
run: |
@@ -393,7 +496,7 @@ jobs:
sed -i 's,require "leanprover-community" / "batteries" @ git ".\+",require "leanprover-community" / "batteries" @ git "lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }}",' lakefile.lean
lake update batteries
git add lakefile.lean lake-manifest.json
git commit -m "Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
git commit --allow-empty -m "Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
else
echo "Branch already exists, updating lean-toolchain and bumping Batteries."
git switch lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }}
@@ -404,10 +507,71 @@ jobs:
git add lean-toolchain
lake update batteries
git add lake-manifest.json
git commit -m "Update lean-toolchain for https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
git commit --allow-empty -m "Update lean-toolchain for https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
fi
- name: Push changes
if: steps.workflow-info.outputs.pullRequestNumber != '' && steps.ready.outputs.mathlib_ready == 'true'
run: |
git push origin lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }}
# We next automatically create a reference manual branch using this toolchain.
# Reference manual CI will be responsible for reporting back success or failure
# to the PR comments asynchronously (and thus transitively SubVerso/Verso).
- name: Cleanup workspace
if: steps.workflow-info.outputs.pullRequestNumber != '' && steps.reference-manual-ready.outputs.manual_ready == 'true'
run: |
sudo rm -rf ./*
# Checkout the reference manual repository with all branches
- name: Checkout mathlib4 repository
if: steps.workflow-info.outputs.pullRequestNumber != '' && steps.reference-manual-ready.outputs.manual_ready == 'true'
uses: actions/checkout@v5
with:
repository: leanprover/reference-manual
token: ${{ secrets.MANUAL_PR_BOT }}
ref: nightly-testing
fetch-depth: 0 # This ensures we check out all tags and branches.
filter: tree:0
- name: Check if tag in reference manual exists
if: steps.workflow-info.outputs.pullRequestNumber != '' && steps.reference-manual-ready.outputs.manual_ready == 'true'
id: check_manual_tag
run: |
git config user.name "leanprover-bot"
git config user.email "leanprover-bot@lean-fro.org"
if git ls-remote --heads --tags --exit-code origin "nightly-testing-${MOST_RECENT_NIGHTLY}" >/dev/null; then
BASE="nightly-testing-${MOST_RECENT_NIGHTLY}"
else
echo "Couldn't find a 'nightly-testing-${MOST_RECENT_NIGHTLY}' branch in the reference manual. Falling back to 'nightly-testing'."
BASE=nightly-testing
fi
echo "Using base tag: $BASE"
EXISTS="$(git ls-remote --heads origin lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }} | wc -l)"
echo "Branch exists: $EXISTS"
if [ "$EXISTS" = "0" ]; then
echo "Branch does not exist, creating it."
git switch -c lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }} "$BASE"
echo "leanprover/lean4-pr-releases:pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}-${{ env.SHORT_SHA }}" > lean-toolchain
git add lean-toolchain
git add lakefile.lean lake-manifest.json
git commit --allow-empty -m "Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
else
echo "Branch already exists, updating lean-toolchain."
git switch lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }}
# The reference manual's `nightly-testing` branch or `nightly-testing-YYYY-MM-DD` tag may have moved since this branch was created, so merge their changes.
# (This should no longer be possible once `nightly-testing-YYYY-MM-DD` is a tag, but it is still safe to merge.)
git merge "$BASE" --strategy-option ours --no-commit --allow-unrelated-histories
echo "leanprover/lean4-pr-releases:pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}-${{ env.SHORT_SHA }}" > lean-toolchain
git add lean-toolchain
git add lake-manifest.json
git commit --allow-empty -m "Update lean-toolchain for https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
fi
- name: Push changes
if: steps.workflow-info.outputs.pullRequestNumber != '' && steps.reference-manual-ready.outputs.manual_ready == 'true'
run: |
git push origin lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }}

View File

@@ -10,11 +10,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check PR title
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const msg = context.payload.pull_request? context.payload.pull_request.title : context.payload.merge_group.head_commit.message;
console.log(`Message: ${msg}`)
if (!/^(feat|fix|doc|style|refactor|test|chore|perf): .*[^.]($|\n\n)/.test(msg)) {
if (!/^(feat|fix|doc|style|refactor|test|chore|perf): (?![A-Z][a-z]).*[^.]($|\n\n)/.test(msg)) {
core.setFailed('PR title does not follow the Commit Convention (https://leanprover.github.io/lean4/doc/dev/commit_convention.html).');
}

View File

@@ -11,7 +11,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
- uses: actions/stale@v10
with:
days-before-stale: -1
days-before-pr-stale: 30

View File

@@ -18,12 +18,16 @@ concurrency:
jobs:
update-stage0:
runs-on: ubuntu-latest
runs-on: nscloud-ubuntu-22.04-amd64-8x16
env:
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_COMPRESS: true
CCACHE_MAXSIZE: 400M
steps:
# This action should push to an otherwise protected branch, so it
# uses a deploy key with write permissions, as suggested at
# https://stackoverflow.com/a/76135647/946226
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
ssh-key: ${{secrets.STAGE0_SSH_KEY}}
- run: echo "should_update_stage0=yes" >> "$GITHUB_ENV"
@@ -52,11 +56,32 @@ jobs:
run: |
echo "NPROC=$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || echo 4)" >> $GITHUB_ENV
shell: 'nix develop -c bash -euxo pipefail {0}'
- name: Restore Cache
if: env.should_update_stage0 == 'yes'
uses: actions/cache/restore@v4
with:
# NOTE: must be in sync with `restore-cache` in `build-template.yml`
path: |
.ccache
build/stage1/**/*.trace
build/stage1/**/*.olean*
build/stage1/**/*.ilean
build/stage1/**/*.ir
build/stage1/**/*.c
build/stage1/**/*.c.o*
key: Linux Lake-build-v4-${{ github.sha }}
# fall back to (latest) previous cache
restore-keys: |
Linux Lake-build-v4
- if: env.should_update_stage0 == 'yes'
run: cmake --preset release
# sync options with `Linux Lake` to ensure cache reuse
run: |
mkdir -p build
cmake --preset release -B build -DLEAN_EXTRA_MAKE_OPTS=-DwarningAsError=true
shell: 'nix develop -c bash -euxo pipefail {0}'
- if: env.should_update_stage0 == 'yes'
run: make -j$NPROC -C build/release update-stage0-commit
run: |
make -j$NPROC -C build update-stage0-commit
shell: 'nix develop -c bash -euxo pipefail {0}'
- if: env.should_update_stage0 == 'yes'
run: git show --stat

2
.gitignore vendored
View File

@@ -20,7 +20,6 @@ tasks.json
settings.json
.gdb_history
.vscode/*
!.vscode/settings.json
script/__pycache__
*.produced.out
CMakeSettings.json
@@ -31,3 +30,4 @@ fwOut.txt
wdErr.txt
wdIn.txt
wdOut.txt
downstream_releases/

View File

@@ -16,7 +16,7 @@ foreach(var ${vars})
list(APPEND STAGE1_ARGS "-D${CMAKE_MATCH_1}=${${var}}")
elseif("${currentHelpString}" MATCHES "No help, variable specified on the command line." OR "${currentHelpString}" STREQUAL "")
list(APPEND CL_ARGS "-D${var}=${${var}}")
if("${var}" MATCHES "USE_GMP|CHECK_OLEAN_VERSION")
if("${var}" MATCHES "USE_GMP|CHECK_OLEAN_VERSION|LEAN_VERSION_.*|LEAN_SPECIAL_VERSION_DESC")
# must forward options that generate incompatible .olean format
list(APPEND STAGE0_ARGS "-D${var}=${${var}}")
elseif("${var}" MATCHES "LLVM*|PKG_CONFIG|USE_LAKE|USE_MIMALLOC")
@@ -147,6 +147,10 @@ add_custom_target(test
COMMAND $(MAKE) -C stage1 test
DEPENDS stage1)
add_custom_target(clean-stdlib
COMMAND $(MAKE) -C stage1 clean-stdlib
DEPENDS stage1)
install(CODE "execute_process(COMMAND make -C stage1 install)")
add_custom_target(check-stage3

View File

@@ -7,9 +7,9 @@
/.github/ @kim-em
/RELEASES.md @kim-em
/src/kernel/ @leodemoura
/src/library/compiler/ @zwarich
/src/library/compiler/ @hargoniX
/src/lake/ @tydeu
/src/Lean/Compiler/ @leodemoura @zwarich
/src/Lean/Compiler/ @leodemoura @hargoniX
/src/Lean/Data/Lsp/ @mhuisi
/src/Lean/Elab/Deriving/ @kim-em
/src/Lean/Elab/Tactic/ @kim-em
@@ -45,3 +45,10 @@
/src/Std/Tactic/BVDecide/ @hargoniX
/src/Lean/Elab/Tactic/BVDecide/ @hargoniX
/src/Std/Sat/ @hargoniX
/src/Std/Do @sgraf812
/src/Std/Tactic/Do @sgraf812
/src/Lean/Elab/Tactic/Do @sgraf812
/src/Init/Data/Range/Polymorphic @datokrat
/src/Init/Data/Slice @datokrat
/src/Init/Data/Iterators @datokrat
/src/Std/Data/Iterators @datokrat

View File

@@ -2,19 +2,19 @@ This is the repository for **Lean 4**.
# About
- [Quickstart](https://lean-lang.org/documentation/setup/)
- [Quickstart](https://lean-lang.org/install/)
- [Homepage](https://lean-lang.org)
- [Theorem Proving Tutorial](https://lean-lang.org/theorem_proving_in_lean4/)
- [Functional Programming in Lean](https://lean-lang.org/functional_programming_in_lean/)
- [Documentation Overview](https://lean-lang.org/documentation/)
- [Documentation Overview](https://lean-lang.org/learn/)
- [Language Reference](https://lean-lang.org/doc/reference/latest/)
- [Release notes](RELEASES.md) starting at v4.0.0-m3
- [Examples](https://lean-lang.org/documentation/examples/)
- [Examples](https://lean-lang.org/examples/)
- [External Contribution Guidelines](CONTRIBUTING.md)
# Installation
See [Setting Up Lean](https://lean-lang.org/documentation/setup/).
See [Install Lean](https://lean-lang.org/install/).
# Contributing

View File

@@ -1,6 +1,6 @@
# Lean Build Bootstrapping
Since version 4, Lean is a partially bootstrapped program: most parts of the
Lean is a bootstrapped program: the
frontend and compiler are written in Lean itself and thus need to be built before
building Lean itself - which is needed to again build those parts. This cycle is
broken by using pre-built C files checked into the repository (which ultimately
@@ -73,6 +73,11 @@ update the archived C source code of the stage 0 compiler in `stage0/src`.
The github repository will automatically update stage0 on `master` once
`src/stdlib_flags.h` and `stage0/src/stdlib_flags.h` are out of sync.
NOTE: A full rebuild of stage 1 will only be triggered when the *committed* contents of `stage0/` are changed.
Thus if you change files in it manually instead of through `update-stage0-commit` (see below) or fetching updates from git, you either need to commit those changes first or run `make -C build/release clean-stdlib`.
The same is true for further stages except that a rebuild of them is retriggered on any committed change, not just to a specific directory.
Thus when debugging e.g. stage 2 failures, you can resume the build from these failures on but may want to explicitly call `clean-stdlib` to either observe changes from `.olean` files of modules that built successfully or to check that you did not break modules that built successfully at some prior point.
If you have write access to the lean4 repository, you can also manually
trigger that process, for example to be able to use new features in the compiler itself.
You can do that on <https://github.com/leanprover/lean4/actions/workflows/update-stage0.yml>
@@ -82,13 +87,13 @@ gh workflow run update-stage0.yml
```
Leaving stage0 updates to the CI automation is preferable, but should you need
to do it locally, you can use `make update-stage0-commit` in `build/release` to
update `stage0` from `stage1` or `make -C stageN update-stage0-commit` to
to do it locally, you can use `make -C build/release update-stage0-commit` to
update `stage0` from `stage1` or `make -C build/release/stageN update-stage0-commit` to
update from another stage. This command will automatically stage the updated files
and introduce a commit,so make sure to commit your work before that.
and introduce a commit, so make sure to commit your work before that.
If you rebased the branch (either onto a newer version of `master`, or fixing
up some commits prior to the stage0 update, recreate the stage0 update commits.
up some commits prior to the stage0 update), recreate the stage0 update commits.
The script `script/rebase-stage0.sh` can be used for that.
The CI should prevent PRs with changes to stage0 (besides `stdlib_flags.h`)

View File

@@ -52,7 +52,7 @@ In the case of `@[extern]` all *irrelevant* types are removed first; see next se
Similarly, the signed integer types `Int8`, ..., `Int64`, `ISize` are also represented by the unsigned C types `uint8_t`, ..., `uint64_t`, `size_t`, respectively, because they have a trivial structure.
* `Nat` and `Int` are represented by `lean_object *`.
Their runtime values is either a pointer to an opaque bignum object or, if the lowest bit of the "pointer" is 1 (`lean_is_scalar`), an encoded unboxed natural number or integer (`lean_box`/`lean_unbox`).
* A universe `Sort u`, type constructor `... → Sort u`, or proposition `p : Prop` is *irrelevant* and is either statically erased (see above) or represented as a `lean_object *` with the runtime value `lean_box(0)`
* A universe `Sort u`, type constructor `... → Sort u`, `Void α` or proposition `p : Prop` is *irrelevant* and is either statically erased (see above) or represented as a `lean_object *` with the runtime value `lean_box(0)`
* Any other type is represented by `lean_object *`.
Its runtime value is a pointer to an object of a subtype of `lean_object` (see the "Inductive types" section below) or the unboxed value `lean_box(cidx)` for the `cidx`th constructor of an inductive type if this constructor does not have any relevant parameters.
@@ -68,7 +68,7 @@ The memory order of the fields is derived from the types and order of the fields
* Fields of type `USize`
* Other scalar fields, in decreasing order by size
Within each group the fields are ordered in declaration order. **Warning**: Trivial wrapper types still count toward a field being treated as non-scalar for this purpose.
Within each group the fields are ordered in declaration order. Trivial wrapper types count as their underlying wrapped type for this purpose.
* To access fields of the first kind, use `lean_ctor_get(val, i)` to get the `i`th non-scalar field.
* To access `USize` fields, use `lean_ctor_get_usize(val, n+i)` to get the `i`th usize field and `n` is the total number of fields of the first kind.
@@ -80,32 +80,32 @@ structure S where
ptr_1 : Array Nat
usize_1 : USize
sc64_1 : UInt64
ptr_2 : { x : UInt64 // x > 0 } -- wrappers don't count as scalars
sc64_2 : Float -- `Float` is 64 bit
sc64_2 : { x : UInt64 // x > 0 } -- wrappers of scalars count as scalars
sc64_3 : Float -- `Float` is 64 bit
sc8_1 : Bool
sc16_1 : UInt16
sc8_2 : UInt8
sc64_3 : UInt64
sc64_4 : UInt64
usize_2 : USize
ptr_3 : Char -- trivial wrapper around `UInt32`
sc32_1 : UInt32
sc32_1 : Char -- trivial wrapper around `UInt32`
sc32_2 : UInt32
sc16_2 : UInt16
```
would get re-sorted into the following memory order:
* `S.ptr_1` - `lean_ctor_get(val, 0)`
* `S.ptr_2` - `lean_ctor_get(val, 1)`
* `S.ptr_3` - `lean_ctor_get(val, 2)`
* `S.usize_1` - `lean_ctor_get_usize(val, 3)`
* `S.usize_2` - `lean_ctor_get_usize(val, 4)`
* `S.sc64_1` - `lean_ctor_get_uint64(val, sizeof(void*)*5)`
* `S.sc64_2` - `lean_ctor_get_float(val, sizeof(void*)*5 + 8)`
* `S.sc64_3` - `lean_ctor_get_uint64(val, sizeof(void*)*5 + 16)`
* `S.sc32_1` - `lean_ctor_get_uint32(val, sizeof(void*)*5 + 24)`
* `S.sc16_1` - `lean_ctor_get_uint16(val, sizeof(void*)*5 + 28)`
* `S.sc16_2` - `lean_ctor_get_uint16(val, sizeof(void*)*5 + 30)`
* `S.sc8_1` - `lean_ctor_get_uint8(val, sizeof(void*)*5 + 32)`
* `S.sc8_2` - `lean_ctor_get_uint8(val, sizeof(void*)*5 + 33)`
* `S.usize_1` - `lean_ctor_get_usize(val, 1)`
* `S.usize_2` - `lean_ctor_get_usize(val, 2)`
* `S.sc64_1` - `lean_ctor_get_uint64(val, sizeof(void*)*3)`
* `S.sc64_2` - `lean_ctor_get_uint64(val, sizeof(void*)*3 + 8)`
* `S.sc64_3` - `lean_ctor_get_float(val, sizeof(void*)*3 + 16)`
* `S.sc64_4` - `lean_ctor_get_uint64(val, sizeof(void*)*3 + 24)`
* `S.sc32_1` - `lean_ctor_get_uint32(val, sizeof(void*)*3 + 32)`
* `S.sc32_2` - `lean_ctor_get_uint32(val, sizeof(void*)*3 + 36)`
* `S.sc16_1` - `lean_ctor_get_uint16(val, sizeof(void*)*3 + 40)`
* `S.sc16_2` - `lean_ctor_get_uint16(val, sizeof(void*)*3 + 42)`
* `S.sc8_1` - `lean_ctor_get_uint8(val, sizeof(void*)*3 + 44)`
* `S.sc8_2` - `lean_ctor_get_uint8(val, sizeof(void*)*3 + 45)`
### Borrowing
@@ -131,21 +131,28 @@ Thus `[init]` functions are run iff their module is imported, regardless of whet
The initializer for module `A.B` is called `initialize_A_B` and will automatically initialize any imported modules.
Module initializers are idempotent (when run with the same `builtin` flag), but not thread-safe.
**Important for process-related functionality**: If your application needs to use process-related functions from libuv, such as `Std.Internal.IO.Process.getProcessTitle` and `Std.Internal.IO.Process.setProcessTitle`, you must call `lean_setup_args(argc, argv)` (which returns a potentially modified `argv` that must be used in place of the original) **before** calling `lean_initialize()` or `lean_initialize_runtime_module()`. This sets up process handling capabilities correctly, which is essential for certain system-level operations that Lean's runtime may depend on.
Together with initialization of the Lean runtime, you should execute code like the following exactly once before accessing any Lean declarations:
```c
void lean_initialize_runtime_module();
void lean_initialize();
lean_object * initialize_A_B(uint8_t builtin, lean_object *);
lean_object * initialize_C(uint8_t builtin, lean_object *);
char ** lean_setup_args(int argc, char ** argv);
lean_object * initialize_A_B(uint8_t builtin);
lean_object * initialize_C(uint8_t builtin);
...
argv = lean_setup_args(argc, argv); // if using process-related functionality
lean_initialize_runtime_module();
//lean_initialize(); // necessary (and replaces `lean_initialize_runtime_module`) if you (indirectly) access the `Lean` package
lean_object * res;
// use same default as for Lean executables
uint8_t builtin = 1;
res = initialize_A_B(builtin, lean_io_mk_world());
res = initialize_A_B(builtin);
if (lean_io_result_is_ok(res)) {
lean_dec_ref(res);
} else {
@@ -153,7 +160,7 @@ if (lean_io_result_is_ok(res)) {
lean_dec(res);
return ...; // do not access Lean declarations if initialization failed
}
res = initialize_C(builtin, lean_io_mk_world());
res = initialize_C(builtin);
if (lean_io_result_is_ok(res)) {
...

View File

@@ -8,8 +8,8 @@ You should not edit the `stage0` directory except using the commands described i
## Development Setup
You can use any of the [supported editors](../setup.md) for editing the Lean source code.
If you set up `elan` as below, opening `src/` as a *workspace folder* should ensure that stage 0 (i.e. the stage that first compiles `src/`) will be used for files in that directory.
You can use any of the [supported editors](https://lean-lang.org/install/manual/) for editing the Lean source code.
Please see below for specific instructions for VS Code.
### Dev setup using elan
@@ -68,6 +68,10 @@ code lean.code-workspace
```
on the command line.
You can use the `Refresh File Dependencies` command as in other projects to rebuild modules from inside VS Code but be aware that this does not trigger any non-Lake build targets.
In particular, after updating `stage0/` (or fetching an update to it), you will want to invoke `make` directly to rebuild `stage0/bin/lean` as described in [building Lean](../make/index.md).
You should then run the `Restart Server` command to update all open files and the server watchdog process as well.
### `ccache`
Lean's build process uses [`ccache`](https://ccache.dev/) if it is
@@ -85,5 +89,29 @@ such that changing files in `Init` doesn't force a full rebuild of `Lean`.
You can test a Lean PR against Mathlib and Batteries by rebasing your PR
on to `nightly-with-mathlib` branch. (It is fine to force push after rebasing.)
CI will generate a branch of Mathlib and Batteries called `lean-pr-testing-NNNN`
that uses the toolchain for your PR, and will report back to the Lean PR with results from Mathlib CI.
on the `leanprover-community/mathlib4-nightly-testing` fork of Mathlib.
This branch uses the toolchain for your PR, and will report back to the Lean PR with results from Mathlib CI.
See https://leanprover-community.github.io/contribute/tags_and_branches.html for more details.
### Testing against the Lean Language Reference
You can test a Lean PR against the reference manual by rebasing your PR
on to `nightly-with-manual` branch. (It is fine to force push after rebasing.)
CI will generate a branch of the reference manual called `lean-pr-testing-NNNN`
in `leanprover/reference-manual`. This branch uses the toolchain for your PR,
and will report back to the Lean PR with results from Mathlib CI.
### Avoiding rebuilds for downstream projects
If you want to test changes to Lean on downstream projects and would like to avoid rebuilding modules you have already built/fetched using the project's configured Lean toolchain, you can often do so as long as your build of Lean is close enough to that Lean toolchain (compatible .olean format including structure of all relevant environment extensions).
To override the toolchain without rebuilding for a single command, for example `lake build` or `lake lean`, you can use the prefix
```
LEAN_GITHASH=$(lean --githash) lake +lean4 ...
```
Alternatively, use
```
export LEAN_GITHASH=$(lean --githash)
export ELAN_TOOLCHAIN=lean4
```
to persist these changes for the lifetime of the current shell, which will affect any processes spawned from it such as VS Code started via `code .`.
If you use a setup where you cannot directly start your editor from the command line, such as VS Code Remote, you might want to consider using [direnv](https://direnv.net/) together with an editor extension for it instead so that you can put the lines above into `.envrc`.

View File

@@ -59,7 +59,7 @@ All these tests are included by [src/shell/CMakeLists.txt](https://github.com/le
open Foo in
theorem tst2 (h : a ≤ b) : a + 2 ≤ b + 2 :=
Bla.
--^ textDocument/completion
--^ completion
```
In this example, the test driver [`test_single.sh`](https://github.com/leanprover/lean4/tree/master/tests/lean/interactive/test_single.sh) will simulate an
auto-completion request at `Bla.`. The expected output is stored in

View File

@@ -282,7 +282,7 @@ theorem BinTree.find_insert_of_ne (b : BinTree β) (ne : k ≠ k') (v : β)
let t, h := b; simp
induction t with simp
| leaf =>
intros le
intro le
exact Nat.lt_of_le_of_ne le ne
| node left key value right ihl ihr =>
let .node hl hr bl br := h

View File

@@ -94,10 +94,8 @@ theorem List.palindrome_of_eq_reverse (h : as.reverse = as) : Palindrome as := b
next => exact Palindrome.nil
next a => exact Palindrome.single a
next a b as ih =>
have : a = b := by simp_all
subst this
have : as.reverse = as := by simp_all
exact Palindrome.sandwich a (ih this)
obtain rfl, h, - := by simpa using h
exact Palindrome.sandwich b (ih h)
/-!
We now define a function that returns `true` iff `as` is a palindrome.

View File

@@ -1,6 +1,6 @@
These are instructions to set up a working development environment for those who wish to make changes to Lean itself. It is part of the [Development Guide](../dev/index.md).
We strongly suggest that new users instead follow the [Quickstart](../quickstart.md) to get started using Lean, since this sets up an environment that can automatically manage multiple Lean toolchain versions, which is necessary when working within the Lean ecosystem.
We strongly suggest that new users instead follow the [Installation Instructions](https://lean-lang.org/install/) to get started using Lean, since this sets up an environment that can automatically manage multiple Lean toolchain versions, which is necessary when working within the Lean ecosystem.
Requirements
------------
@@ -44,12 +44,12 @@ Useful CMake Configuration Settings
Pass these along with the `cmake --preset release` command.
There are also two alternative presets that combine some of these options you can use instead of `release`: `debug` and `sandebug` (sanitize + debug).
* `-D CMAKE_BUILD_TYPE=`\
* `-DCMAKE_BUILD_TYPE=`\
Select the build type. Valid values are `RELEASE` (default), `DEBUG`,
`RELWITHDEBINFO`, and `MINSIZEREL`.
* `-D CMAKE_C_COMPILER=`\
`-D CMAKE_CXX_COMPILER=`\
* `-DCMAKE_C_COMPILER=`\
`-DCMAKE_CXX_COMPILER=`\
Select the C/C++ compilers to use. Official Lean releases currently use Clang;
see also `.github/workflows/ci.yml` for the CI config.

View File

@@ -1,4 +1,4 @@
# Install Packages on OS X 14.5
# Install Packages on OS X
We assume that you are using [homebrew][homebrew] as a package manager.
@@ -6,23 +6,23 @@ We assume that you are using [homebrew][homebrew] as a package manager.
## Compilers
You need a C++11-compatible compiler to build Lean. As of November
2014, you have three options:
You need a C++14-compatible compiler to build Lean. As of July
2025, you have three options:
- clang++-3.5 (shipped with OSX, Apple LLVM version 6.0)
- gcc-4.9.1 (homebrew)
- clang++-3.5 (homebrew)
- clang++ shipped with OSX (at time of writing v17.0.0)
- clang++ via homebrew (at time of writing, v20.1.8)
- gcc via homebrew (at time of writing, v15.1.0)
We recommend to use Apple's clang++ because it is pre-shipped with OS
X and requires no further installation.
To install gcc-4.9.1 via homebrew, please execute:
To install gcc via homebrew, please execute:
```bash
brew install gcc
```
To install clang++-3.5 via homebrew, please execute:
To install clang via homebrew, please execute:
```bash
brew install llvm
brew install llvm lld
```
To use compilers other than the default one (Apple's clang++), you
need to use `-DCMAKE_CXX_COMPILER` option to specify the compiler

4
doc/std/grove/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/.lake
!lake-manifest.json
metadata.json
invalidated.json

View File

@@ -0,0 +1,22 @@
import Grove.Framework
import GroveStdlib.Generated.«associative-query-operations»
import GroveStdlib.Generated.«associative-creation-operations»
import GroveStdlib.Generated.«associative-modification-operations»
import GroveStdlib.Generated.«associative-create-then-query»
import GroveStdlib.Generated.«associative-all-operations-covered»
/-
This file is autogenerated by grove. You can manually edit it, for example to resolve merge
conflicts, but be careful.
-/
open Grove.Framework Widget
namespace GroveStdlib.Generated
def restoreState : RestoreStateM Unit := do
«associative-query-operations».restoreState
«associative-creation-operations».restoreState
«associative-modification-operations».restoreState
«associative-create-then-query».restoreState
«associative-all-operations-covered».restoreState

View File

@@ -0,0 +1,34 @@
import Grove.Framework
/-
This file is autogenerated by grove. You can manually edit it, for example to resolve merge
conflicts, but be careful.
-/
open Grove.Framework Widget
namespace GroveStdlib.Generated.«associative-all-operations-covered»
def «all-covered» : Assertion.Fact where
widgetId := "associative-all-operations-covered"
factId := "all-covered"
assertionId := "all-covered"
state := {
assertionId := "all-covered"
description := "All operations should be covered"
passed := false
message := "There were 19697 operations that were not covered."
}
metadata := {
status := .bad
comment := "Still missing some!"
}
def table : Assertion.Data where
widgetId := "associative-all-operations-covered"
facts := #[
«all-covered»,
]
def restoreState : RestoreStateM Unit := do
addAssertion table

View File

@@ -0,0 +1,357 @@
import Grove.Framework
/-
This file is autogenerated by grove. You can manually edit it, for example to resolve merge
conflicts, but be careful.
-/
open Grove.Framework Widget
namespace GroveStdlib.Generated.«associative-create-then-query»
def «2cb3c441-9663-4ce7-9527-0f40fc29925a:::01f88623-fa5f-4380-9772-b30f2fec5c94:::Std.DHashMap::Std.DHashMap.Raw::Std.ExtDHashMap::Std.DTreeMap::Std.DTreeMap.Raw::Std.ExtDTreeMap» : Table.Fact .subexpression .subexpression .declaration where
widgetId := "associative-create-then-query"
factId := "2cb3c441-9663-4ce7-9527-0f40fc29925a:::01f88623-fa5f-4380-9772-b30f2fec5c94:::Std.DHashMap::Std.DHashMap.Raw::Std.ExtDHashMap::Std.DTreeMap::Std.DTreeMap.Raw::Std.ExtDTreeMap"
rowAssociationId := "2cb3c441-9663-4ce7-9527-0f40fc29925a"
columnAssociationId := "01f88623-fa5f-4380-9772-b30f2fec5c94"
selectedLayers := #["Std.DHashMap", "Std.DHashMap.Raw", "Std.ExtDHashMap", "Std.DTreeMap", "Std.DTreeMap.Raw", "Std.ExtDTreeMap", ]
layerStates := #[
{
layerIdentifier := "Std.DHashMap"
rowState :=
some "Std.DHashMap.emptyWithCapacity", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.emptyWithCapacity,
renderedStatement := "Std.DHashMap.emptyWithCapacity.{u, v} {α : Type u} {β : α → Type v} [BEq α] [Hashable α]\n (capacity : Nat := 8) : Std.DHashMap α β",
isDeprecated := false })
columnState :=
some "Std.DHashMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.isEmpty,
renderedStatement := "Std.DHashMap.isEmpty.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n (m : Std.DHashMap α β) : Bool",
isDeprecated := false })
selectedCellStates := #[
]
},
{
layerIdentifier := "Std.DHashMap.Raw"
rowState :=
some "Std.DHashMap.Raw.emptyWithCapacity", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.Raw.emptyWithCapacity,
renderedStatement := "Std.DHashMap.Raw.emptyWithCapacity.{u, v} {α : Type u} {β : α → Type v} (capacity : Nat := 8) :\n Std.DHashMap.Raw α β",
isDeprecated := false })
columnState :=
some "Std.DHashMap.Raw.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.Raw.isEmpty,
renderedStatement := "Std.DHashMap.Raw.isEmpty.{u, v} {α : Type u} {β : α → Type v} (m : Std.DHashMap.Raw α β) : Bool",
isDeprecated := false })
selectedCellStates := #[
]
},
{
layerIdentifier := "Std.ExtDHashMap"
rowState :=
some "Std.ExtDHashMap.emptyWithCapacity", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDHashMap.emptyWithCapacity,
renderedStatement := "Std.ExtDHashMap.emptyWithCapacity.{u, v} {α : Type u} {β : α → Type v} [BEq α] [Hashable α]\n (capacity : Nat := 8) : Std.ExtDHashMap α β",
isDeprecated := false })
columnState :=
some "Std.ExtDHashMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDHashMap.isEmpty,
renderedStatement := "Std.ExtDHashMap.isEmpty.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n [EquivBEq α] [LawfulHashable α] (m : Std.ExtDHashMap α β) : Bool",
isDeprecated := false })
selectedCellStates := #[
]
},
{
layerIdentifier := "Std.DTreeMap"
rowState :=
some "Std.DTreeMap.empty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.empty,
renderedStatement := "Std.DTreeMap.empty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} :\n Std.DTreeMap α β cmp",
isDeprecated := false })
columnState :=
some "Std.DTreeMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.isEmpty,
renderedStatement := "Std.DTreeMap.isEmpty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.DTreeMap α β cmp) : Bool",
isDeprecated := false })
selectedCellStates := #[
]
},
{
layerIdentifier := "Std.DTreeMap.Raw"
rowState :=
some "Std.DTreeMap.Raw.empty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.Raw.empty,
renderedStatement := "Std.DTreeMap.Raw.empty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} :\n Std.DTreeMap.Raw α β cmp",
isDeprecated := false })
columnState :=
some "Std.DTreeMap.Raw.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.Raw.isEmpty,
renderedStatement := "Std.DTreeMap.Raw.isEmpty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.DTreeMap.Raw α β cmp) : Bool",
isDeprecated := false })
selectedCellStates := #[
]
},
{
layerIdentifier := "Std.ExtDTreeMap"
rowState :=
some "Std.ExtDTreeMap.empty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDTreeMap.empty,
renderedStatement := "Std.ExtDTreeMap.empty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} :\n Std.ExtDTreeMap α β cmp",
isDeprecated := false })
columnState :=
some "Std.ExtDTreeMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDTreeMap.isEmpty,
renderedStatement := "Std.ExtDTreeMap.isEmpty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.ExtDTreeMap α β cmp) : Bool",
isDeprecated := false })
selectedCellStates := #[
]
},
]
metadata := {
status := .done
comment := "Not necessary for `ExtDHashMap` because of simp lemma turning into varno"
}
def «5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d:::01f88623-fa5f-4380-9772-b30f2fec5c94:::Std.DHashMap::Std.DHashMap.Raw::Std.ExtDHashMap::Std.DTreeMap::Std.DTreeMap.Raw::Std.ExtDTreeMap» : Table.Fact .subexpression .subexpression .declaration where
widgetId := "associative-create-then-query"
factId := "5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d:::01f88623-fa5f-4380-9772-b30f2fec5c94:::Std.DHashMap::Std.DHashMap.Raw::Std.ExtDHashMap::Std.DTreeMap::Std.DTreeMap.Raw::Std.ExtDTreeMap"
rowAssociationId := "5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d"
columnAssociationId := "01f88623-fa5f-4380-9772-b30f2fec5c94"
selectedLayers := #["Std.DHashMap", "Std.DHashMap.Raw", "Std.ExtDHashMap", "Std.DTreeMap", "Std.DTreeMap.Raw", "Std.ExtDTreeMap", ]
layerStates := #[
{
layerIdentifier := "Std.DHashMap"
rowState :=
some "app (EmptyCollection.emptyCollection) (Std.DHashMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.DHashMap*)", displayShort := "" }
columnState :=
some "Std.DHashMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.isEmpty,
renderedStatement := "Std.DHashMap.isEmpty.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n (m : Std.DHashMap α β) : Bool",
isDeprecated := false })
selectedCellStates := #[
"Std.DHashMap.isEmpty_empty", Grove.Framework.Declaration.thm
{ name := `Std.DHashMap.isEmpty_empty,
renderedStatement := "Std.DHashMap.isEmpty_empty.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α} :\n ∅.isEmpty = true",
isSimp := true,
isDeprecated := false }
,
]
},
{
layerIdentifier := "Std.DHashMap.Raw"
rowState :=
some "app (EmptyCollection.emptyCollection) (Std.DHashMap.Raw*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.DHashMap.Raw*)", displayShort := "" }
columnState :=
some "Std.DHashMap.Raw.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.Raw.isEmpty,
renderedStatement := "Std.DHashMap.Raw.isEmpty.{u, v} {α : Type u} {β : α → Type v} (m : Std.DHashMap.Raw α β) : Bool",
isDeprecated := false })
selectedCellStates := #[
"Std.DHashMap.Raw.isEmpty_emptyc", Grove.Framework.Declaration.thm
{ name := `Std.DHashMap.Raw.isEmpty_emptyc,
renderedStatement := "Std.DHashMap.Raw.isEmpty_emptyc.{u_1, u_2} {α : Type u_1} {β : α → Type u_2} [BEq α] [Hashable α] :\n ∅.isEmpty = true",
isSimp := false,
isDeprecated := true }
,
]
},
{
layerIdentifier := "Std.ExtDHashMap"
rowState :=
some "app (EmptyCollection.emptyCollection) (Std.ExtDHashMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.ExtDHashMap*)", displayShort := "" }
columnState :=
some "Std.ExtDHashMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDHashMap.isEmpty,
renderedStatement := "Std.ExtDHashMap.isEmpty.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n [EquivBEq α] [LawfulHashable α] (m : Std.ExtDHashMap α β) : Bool",
isDeprecated := false })
selectedCellStates := #[
]
},
{
layerIdentifier := "Std.DTreeMap"
rowState :=
some "app (EmptyCollection.emptyCollection) (Std.DTreeMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.DTreeMap*)", displayShort := "" }
columnState :=
some "Std.DTreeMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.isEmpty,
renderedStatement := "Std.DTreeMap.isEmpty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.DTreeMap α β cmp) : Bool",
isDeprecated := false })
selectedCellStates := #[
"Std.DTreeMap.isEmpty_emptyc", Grove.Framework.Declaration.thm
{ name := `Std.DTreeMap.isEmpty_emptyc,
renderedStatement := "Std.DTreeMap.isEmpty_emptyc.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} :\n ∅.isEmpty = true",
isSimp := true,
isDeprecated := false }
,
]
},
{
layerIdentifier := "Std.DTreeMap.Raw"
rowState :=
some "app (EmptyCollection.emptyCollection) (Std.DTreeMap.Raw*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.DTreeMap.Raw*)", displayShort := "" }
columnState :=
some "Std.DTreeMap.Raw.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.Raw.isEmpty,
renderedStatement := "Std.DTreeMap.Raw.isEmpty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.DTreeMap.Raw α β cmp) : Bool",
isDeprecated := false })
selectedCellStates := #[
"Std.DTreeMap.Raw.isEmpty_emptyc", Grove.Framework.Declaration.thm
{ name := `Std.DTreeMap.Raw.isEmpty_emptyc,
renderedStatement := "Std.DTreeMap.Raw.isEmpty_emptyc.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} :\n ∅.isEmpty = true",
isSimp := true,
isDeprecated := false }
,
]
},
{
layerIdentifier := "Std.ExtDTreeMap"
rowState :=
some "app (EmptyCollection.emptyCollection) (Std.ExtDTreeMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.ExtDTreeMap*)", displayShort := "" }
columnState :=
some "Std.ExtDTreeMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDTreeMap.isEmpty,
renderedStatement := "Std.ExtDTreeMap.isEmpty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.ExtDTreeMap α β cmp) : Bool",
isDeprecated := false })
selectedCellStates := #[
"Std.ExtDTreeMap.isEmpty_empty", Grove.Framework.Declaration.thm
{ name := `Std.ExtDTreeMap.isEmpty_empty,
renderedStatement := "Std.ExtDTreeMap.isEmpty_empty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} :\n ∅.isEmpty = true",
isSimp := true,
isDeprecated := false }
,
]
},
]
metadata := {
status := .bad
comment := "Missing for `ExtDHashMap`"
}
def table : Table.Data .subexpression .subexpression .declaration where
widgetId := "associative-create-then-query"
selectedRowAssociations := #["2cb3c441-9663-4ce7-9527-0f40fc29925a", "7743a485-024d-43b6-bd5f-ebd3182eb94d", "5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d", ]
selectedColumnAssociations := #["01f88623-fa5f-4380-9772-b30f2fec5c94", "f084f852-af71-45b6-8ab3-d251a8144f72", ]
selectedLayers := #["Std.DHashMap", "Std.DHashMap.Raw", "Std.ExtDHashMap", "Std.DTreeMap", "Std.DTreeMap.Raw", "Std.ExtDTreeMap", ]
selectedCellOptions := #[
{
layerIdentifier := "Std.DHashMap"
rowValue := "2cb3c441-9663-4ce7-9527-0f40fc29925a"
columnValue := "01f88623-fa5f-4380-9772-b30f2fec5c94"
selectedCellOptions := #["Std.DHashMap.isEmpty_emptyWithCapacity", ]
},
{
layerIdentifier := "Std.DHashMap.Raw"
rowValue := "2cb3c441-9663-4ce7-9527-0f40fc29925a"
columnValue := "01f88623-fa5f-4380-9772-b30f2fec5c94"
selectedCellOptions := #["Std.DHashMap.Raw.isEmpty_emptyWithCapacity", ]
},
{
layerIdentifier := "Std.DHashMap"
rowValue := "5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d"
columnValue := "01f88623-fa5f-4380-9772-b30f2fec5c94"
selectedCellOptions := #["Std.DHashMap.isEmpty_empty", ]
},
{
layerIdentifier := "Std.DHashMap.Raw"
rowValue := "5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d"
columnValue := "01f88623-fa5f-4380-9772-b30f2fec5c94"
selectedCellOptions := #["Std.DHashMap.Raw.isEmpty_emptyc", ]
},
{
layerIdentifier := "Std.DTreeMap"
rowValue := "5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d"
columnValue := "01f88623-fa5f-4380-9772-b30f2fec5c94"
selectedCellOptions := #["Std.DTreeMap.isEmpty_emptyc", ]
},
{
layerIdentifier := "Std.DTreeMap.Raw"
rowValue := "5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d"
columnValue := "01f88623-fa5f-4380-9772-b30f2fec5c94"
selectedCellOptions := #["Std.DTreeMap.Raw.isEmpty_emptyc", ]
},
{
layerIdentifier := "Std.ExtDTreeMap"
rowValue := "5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d"
columnValue := "01f88623-fa5f-4380-9772-b30f2fec5c94"
selectedCellOptions := #["Std.ExtDTreeMap.isEmpty_empty", ]
},
]
facts := #[
«2cb3c441-9663-4ce7-9527-0f40fc29925a:::01f88623-fa5f-4380-9772-b30f2fec5c94:::Std.DHashMap::Std.DHashMap.Raw::Std.ExtDHashMap::Std.DTreeMap::Std.DTreeMap.Raw::Std.ExtDTreeMap»,
«5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d:::01f88623-fa5f-4380-9772-b30f2fec5c94:::Std.DHashMap::Std.DHashMap.Raw::Std.ExtDHashMap::Std.DTreeMap::Std.DTreeMap.Raw::Std.ExtDTreeMap»,
]
def restoreState : RestoreStateM Unit := do
addTable table

View File

@@ -0,0 +1,216 @@
import Grove.Framework
/-
This file is autogenerated by grove. You can manually edit it, for example to resolve merge
conflicts, but be careful.
-/
open Grove.Framework Widget
namespace GroveStdlib.Generated.«associative-creation-operations»
def «2cb3c441-9663-4ce7-9527-0f40fc29925a» : AssociationTable.Fact .subexpression where
widgetId := "associative-creation-operations"
factId := "2cb3c441-9663-4ce7-9527-0f40fc29925a"
rowId := "2cb3c441-9663-4ce7-9527-0f40fc29925a"
rowState := #["Std.DHashMap", "Std.DHashMap.emptyWithCapacity", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.emptyWithCapacity,
renderedStatement := "Std.DHashMap.emptyWithCapacity.{u, v} {α : Type u} {β : α → Type v} [BEq α] [Hashable α]\n (capacity : Nat := 8) : Std.DHashMap α β",
isDeprecated := false }),"Std.DHashMap.Raw", "Std.DHashMap.Raw.emptyWithCapacity", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.Raw.emptyWithCapacity,
renderedStatement := "Std.DHashMap.Raw.emptyWithCapacity.{u, v} {α : Type u} {β : α → Type v} (capacity : Nat := 8) :\n Std.DHashMap.Raw α β",
isDeprecated := false }),"Std.ExtDHashMap", "Std.ExtDHashMap.emptyWithCapacity", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDHashMap.emptyWithCapacity,
renderedStatement := "Std.ExtDHashMap.emptyWithCapacity.{u, v} {α : Type u} {β : α → Type v} [BEq α] [Hashable α]\n (capacity : Nat := 8) : Std.ExtDHashMap α β",
isDeprecated := false }),"Std.DTreeMap", "Std.DTreeMap.empty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.empty,
renderedStatement := "Std.DTreeMap.empty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} :\n Std.DTreeMap α β cmp",
isDeprecated := false }),"Std.DTreeMap.Raw", "Std.DTreeMap.Raw.empty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.Raw.empty,
renderedStatement := "Std.DTreeMap.Raw.empty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} :\n Std.DTreeMap.Raw α β cmp",
isDeprecated := false }),"Std.ExtDTreeMap", "Std.ExtDTreeMap.empty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDTreeMap.empty,
renderedStatement := "Std.ExtDTreeMap.empty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} :\n Std.ExtDTreeMap α β cmp",
isDeprecated := false }),"Std.HashMap", "Std.HashMap.emptyWithCapacity", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashMap.emptyWithCapacity,
renderedStatement := "Std.HashMap.emptyWithCapacity.{u, v} {α : Type u} {β : Type v} [BEq α] [Hashable α]\n (capacity : Nat := 8) : Std.HashMap α β",
isDeprecated := false }),"Std.HashMap.Raw", "Std.HashMap.Raw.emptyWithCapacity", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashMap.Raw.emptyWithCapacity,
renderedStatement := "Std.HashMap.Raw.emptyWithCapacity.{u, v} {α : Type u} {β : Type v} (capacity : Nat := 8) :\n Std.HashMap.Raw α β",
isDeprecated := false }),"Std.ExtHashMap", "Std.ExtHashMap.emptyWithCapacity", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtHashMap.emptyWithCapacity,
renderedStatement := "Std.ExtHashMap.emptyWithCapacity.{u, v} {α : Type u} {β : Type v} [BEq α] [Hashable α]\n (capacity : Nat := 8) : Std.ExtHashMap α β",
isDeprecated := false }),"Std.TreeMap", "Std.TreeMap.empty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.empty,
renderedStatement := "Std.TreeMap.empty.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering} : Std.TreeMap α β cmp",
isDeprecated := false }),"Std.TreeMap.Raw", "Std.TreeMap.Raw.empty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.Raw.empty,
renderedStatement := "Std.TreeMap.Raw.empty.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering} :\n Std.TreeMap.Raw α β cmp",
isDeprecated := false }),"Std.ExtTreeMap", "Std.ExtTreeMap.empty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeMap.empty,
renderedStatement := "Std.ExtTreeMap.empty.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering} :\n Std.ExtTreeMap α β cmp",
isDeprecated := false }),"Std.HashSet", "Std.HashSet.emptyWithCapacity", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.emptyWithCapacity,
renderedStatement := "Std.HashSet.emptyWithCapacity.{u} {α : Type u} [BEq α] [Hashable α] (capacity : Nat := 8) :\n Std.HashSet α",
isDeprecated := false }),"Std.HashSet.Raw", "Std.HashSet.Raw.emptyWithCapacity", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.Raw.emptyWithCapacity,
renderedStatement := "Std.HashSet.Raw.emptyWithCapacity.{u} {α : Type u} (capacity : Nat := 8) : Std.HashSet.Raw α",
isDeprecated := false }),"Std.ExtHashSet", "Std.ExtHashSet.emptyWithCapacity", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtHashSet.emptyWithCapacity,
renderedStatement := "Std.ExtHashSet.emptyWithCapacity.{u} {α : Type u} [BEq α] [Hashable α] (capacity : Nat := 8) :\n Std.ExtHashSet α",
isDeprecated := false }),"Std.TreeSet", "Std.TreeSet.empty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.empty,
renderedStatement := "Std.TreeSet.empty.{u} {α : Type u} {cmp : αα → Ordering} : Std.TreeSet α cmp",
isDeprecated := false }),"Std.TreeSet.Raw", "Std.TreeSet.Raw.empty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.Raw.empty,
renderedStatement := "Std.TreeSet.Raw.empty.{u} {α : Type u} {cmp : αα → Ordering} : Std.TreeSet.Raw α cmp",
isDeprecated := false }),"Std.ExtTreeSet", "Std.ExtTreeSet.empty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeSet.empty,
renderedStatement := "Std.ExtTreeSet.empty.{u} {α : Type u} {cmp : αα → Ordering} : Std.ExtTreeSet α cmp",
isDeprecated := false }),]
metadata := {
status := .done
comment := ""
}
def «7743a485-024d-43b6-bd5f-ebd3182eb94d» : AssociationTable.Fact .subexpression where
widgetId := "associative-creation-operations"
factId := "7743a485-024d-43b6-bd5f-ebd3182eb94d"
rowId := "7743a485-024d-43b6-bd5f-ebd3182eb94d"
rowState := #["Std.DHashMap", "Std.DHashMap.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.ofList,
renderedStatement := "Std.DHashMap.ofList.{u, v} {α : Type u} {β : α → Type v} [BEq α] [Hashable α]\n (l : List ((a : α) × β a)) : Std.DHashMap α β",
isDeprecated := false }),"Std.DHashMap.Raw", "Std.DHashMap.Raw.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.Raw.ofList,
renderedStatement := "Std.DHashMap.Raw.ofList.{u, v} {α : Type u} {β : α → Type v} [BEq α] [Hashable α]\n (l : List ((a : α) × β a)) : Std.DHashMap.Raw α β",
isDeprecated := false }),"Std.ExtDHashMap", "Std.ExtDHashMap.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDHashMap.ofList,
renderedStatement := "Std.ExtDHashMap.ofList.{u, v} {α : Type u} {β : α → Type v} [BEq α] [Hashable α]\n (l : List ((a : α) × β a)) : Std.ExtDHashMap α β",
isDeprecated := false }),"Std.DTreeMap", "Std.DTreeMap.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.ofList,
renderedStatement := "Std.DTreeMap.ofList.{u, v} {α : Type u} {β : α → Type v} (l : List ((a : α) × β a))\n (cmp : αα → Ordering := by exact compare) : Std.DTreeMap α β cmp",
isDeprecated := false }),"Std.DTreeMap.Raw", "Std.DTreeMap.Raw.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.Raw.ofList,
renderedStatement := "Std.DTreeMap.Raw.ofList.{u, v} {α : Type u} {β : α → Type v} (l : List ((a : α) × β a))\n (cmp : αα → Ordering := by exact compare) : Std.DTreeMap.Raw α β cmp",
isDeprecated := false }),"Std.ExtDTreeMap", "Std.ExtDTreeMap.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDTreeMap.ofList,
renderedStatement := "Std.ExtDTreeMap.ofList.{u, v} {α : Type u} {β : α → Type v} (l : List ((a : α) × β a))\n (cmp : αα → Ordering := by exact compare) : Std.ExtDTreeMap α β cmp",
isDeprecated := false }),"Std.HashMap", "Std.HashMap.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashMap.ofList,
renderedStatement := "Std.HashMap.ofList.{u, v} {α : Type u} {β : Type v} [BEq α] [Hashable α] (l : List (α × β)) :\n Std.HashMap α β",
isDeprecated := false }),"Std.HashMap.Raw", "Std.HashMap.Raw.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashMap.Raw.ofList,
renderedStatement := "Std.HashMap.Raw.ofList.{u, v} {α : Type u} {β : Type v} [BEq α] [Hashable α] (l : List (α × β)) :\n Std.HashMap.Raw α β",
isDeprecated := false }),"Std.ExtHashMap", "Std.ExtHashMap.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtHashMap.ofList,
renderedStatement := "Std.ExtHashMap.ofList.{u, v} {α : Type u} {β : Type v} [BEq α] [Hashable α] (l : List (α × β)) :\n Std.ExtHashMap α β",
isDeprecated := false }),"Std.TreeMap", "Std.TreeMap.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.ofList,
renderedStatement := "Std.TreeMap.ofList.{u, v} {α : Type u} {β : Type v} (l : List (α × β))\n (cmp : αα → Ordering := by exact compare) : Std.TreeMap α β cmp",
isDeprecated := false }),"Std.TreeMap.Raw", "Std.TreeMap.Raw.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.Raw.ofList,
renderedStatement := "Std.TreeMap.Raw.ofList.{u, v} {α : Type u} {β : Type v} (l : List (α × β))\n (cmp : αα → Ordering := by exact compare) : Std.TreeMap.Raw α β cmp",
isDeprecated := false }),"Std.ExtTreeMap", "Std.ExtTreeMap.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeMap.ofList,
renderedStatement := "Std.ExtTreeMap.ofList.{u, v} {α : Type u} {β : Type v} (l : List (α × β))\n (cmp : αα → Ordering := by exact compare) : Std.ExtTreeMap α β cmp",
isDeprecated := false }),"Std.HashSet", "Std.HashSet.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.ofList,
renderedStatement := "Std.HashSet.ofList.{u} {α : Type u} [BEq α] [Hashable α] (l : List α) : Std.HashSet α",
isDeprecated := false }),"Std.HashSet.Raw", "Std.HashSet.Raw.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.Raw.ofList,
renderedStatement := "Std.HashSet.Raw.ofList.{u} {α : Type u} [BEq α] [Hashable α] (l : List α) : Std.HashSet.Raw α",
isDeprecated := false }),"Std.ExtHashSet", "Std.ExtHashSet.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtHashSet.ofList,
renderedStatement := "Std.ExtHashSet.ofList.{u} {α : Type u} [BEq α] [Hashable α] (l : List α) : Std.ExtHashSet α",
isDeprecated := false }),"Std.TreeSet", "Std.TreeSet.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.ofList,
renderedStatement := "Std.TreeSet.ofList.{u} {α : Type u} (l : List α) (cmp : αα → Ordering := by exact compare) :\n Std.TreeSet α cmp",
isDeprecated := false }),"Std.TreeSet.Raw", "Std.TreeSet.Raw.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.Raw.ofList,
renderedStatement := "Std.TreeSet.Raw.ofList.{u} {α : Type u} (l : List α) (cmp : αα → Ordering := by exact compare) :\n Std.TreeSet.Raw α cmp",
isDeprecated := false }),"Std.ExtTreeSet", "Std.ExtTreeSet.ofList", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeSet.ofList,
renderedStatement := "Std.ExtTreeSet.ofList.{u} {α : Type u} (l : List α) (cmp : αα → Ordering := by exact compare) :\n Std.ExtTreeSet α cmp",
isDeprecated := false }),]
metadata := {
status := .done
comment := ""
}
def «5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d» : AssociationTable.Fact .subexpression where
widgetId := "associative-creation-operations"
factId := "5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d"
rowId := "5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d"
rowState := #["Std.DHashMap", "app (EmptyCollection.emptyCollection) (Std.DHashMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.DHashMap*)", displayShort := "" },"Std.DHashMap.Raw", "app (EmptyCollection.emptyCollection) (Std.DHashMap.Raw*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.DHashMap.Raw*)", displayShort := "" },"Std.ExtDHashMap", "app (EmptyCollection.emptyCollection) (Std.ExtDHashMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.ExtDHashMap*)", displayShort := "" },"Std.DTreeMap", "app (EmptyCollection.emptyCollection) (Std.DTreeMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.DTreeMap*)", displayShort := "" },"Std.DTreeMap.Raw", "app (EmptyCollection.emptyCollection) (Std.DTreeMap.Raw*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.DTreeMap.Raw*)", displayShort := "" },"Std.ExtDTreeMap", "app (EmptyCollection.emptyCollection) (Std.ExtDTreeMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.ExtDTreeMap*)", displayShort := "" },"Std.HashMap", "app (EmptyCollection.emptyCollection) (Std.HashMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.HashMap*)", displayShort := "" },"Std.HashMap.Raw", "app (EmptyCollection.emptyCollection) (Std.HashMap.Raw*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.HashMap.Raw*)", displayShort := "" },"Std.ExtHashMap", "app (EmptyCollection.emptyCollection) (Std.ExtHashMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.ExtHashMap*)", displayShort := "" },"Std.TreeMap", "app (EmptyCollection.emptyCollection) (Std.TreeMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.TreeMap*)", displayShort := "" },"Std.TreeMap.Raw", "app (EmptyCollection.emptyCollection) (Std.TreeMap.Raw*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.TreeMap.Raw*)", displayShort := "" },"Std.ExtTreeMap", "app (EmptyCollection.emptyCollection) (Std.ExtTreeMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.ExtTreeMap*)", displayShort := "" },"Std.HashSet", "app (EmptyCollection.emptyCollection) (Std.HashSet*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.HashSet*)", displayShort := "" },"Std.HashSet.Raw", "app (EmptyCollection.emptyCollection) (Std.HashSet.Raw*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.HashSet.Raw*)", displayShort := "" },"Std.ExtHashSet", "app (EmptyCollection.emptyCollection) (Std.ExtHashSet*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.ExtHashSet*)", displayShort := "" },"Std.TreeSet", "app (EmptyCollection.emptyCollection) (Std.TreeSet*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.TreeSet*)", displayShort := "" },"Std.TreeSet.Raw", "app (EmptyCollection.emptyCollection) (Std.TreeSet.Raw*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.TreeSet.Raw*)", displayShort := "" },"Std.ExtTreeSet", "app (EmptyCollection.emptyCollection) (Std.ExtTreeSet*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (EmptyCollection.emptyCollection) (Std.ExtTreeSet*)", displayShort := "" },]
metadata := {
status := .done
comment := ""
}
def table : AssociationTable.Data .subexpression where
widgetId := "associative-creation-operations"
rows := #[
"2cb3c441-9663-4ce7-9527-0f40fc29925a", "empty", #["Std.DHashMap", "Std.DHashMap.emptyWithCapacity","Std.DHashMap.Raw", "Std.DHashMap.Raw.emptyWithCapacity","Std.ExtDHashMap", "Std.ExtDHashMap.emptyWithCapacity","Std.DTreeMap", "Std.DTreeMap.empty","Std.DTreeMap.Raw", "Std.DTreeMap.Raw.empty","Std.ExtDTreeMap", "Std.ExtDTreeMap.empty","Std.HashMap", "Std.HashMap.emptyWithCapacity","Std.HashMap.Raw", "Std.HashMap.Raw.emptyWithCapacity","Std.ExtHashMap", "Std.ExtHashMap.emptyWithCapacity","Std.TreeMap", "Std.TreeMap.empty","Std.TreeMap.Raw", "Std.TreeMap.Raw.empty","Std.ExtTreeMap", "Std.ExtTreeMap.empty","Std.HashSet", "Std.HashSet.emptyWithCapacity","Std.HashSet.Raw", "Std.HashSet.Raw.emptyWithCapacity","Std.ExtHashSet", "Std.ExtHashSet.emptyWithCapacity","Std.TreeSet", "Std.TreeSet.empty","Std.TreeSet.Raw", "Std.TreeSet.Raw.empty","Std.ExtTreeSet", "Std.ExtTreeSet.empty",],
"7743a485-024d-43b6-bd5f-ebd3182eb94d", "ofList", #["Std.DHashMap", "Std.DHashMap.ofList","Std.DHashMap.Raw", "Std.DHashMap.Raw.ofList","Std.ExtDHashMap", "Std.ExtDHashMap.ofList","Std.DTreeMap", "Std.DTreeMap.ofList","Std.DTreeMap.Raw", "Std.DTreeMap.Raw.ofList","Std.ExtDTreeMap", "Std.ExtDTreeMap.ofList","Std.HashMap", "Std.HashMap.ofList","Std.HashMap.Raw", "Std.HashMap.Raw.ofList","Std.ExtHashMap", "Std.ExtHashMap.ofList","Std.TreeMap", "Std.TreeMap.ofList","Std.TreeMap.Raw", "Std.TreeMap.Raw.ofList","Std.ExtTreeMap", "Std.ExtTreeMap.ofList","Std.HashSet", "Std.HashSet.ofList","Std.HashSet.Raw", "Std.HashSet.Raw.ofList","Std.ExtHashSet", "Std.ExtHashSet.ofList","Std.TreeSet", "Std.TreeSet.ofList","Std.TreeSet.Raw", "Std.TreeSet.Raw.ofList","Std.ExtTreeSet", "Std.ExtTreeSet.ofList",],
"5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d", "emptyCollection", #["Std.DHashMap", "app (EmptyCollection.emptyCollection) (Std.DHashMap*)","Std.DHashMap.Raw", "app (EmptyCollection.emptyCollection) (Std.DHashMap.Raw*)","Std.ExtDHashMap", "app (EmptyCollection.emptyCollection) (Std.ExtDHashMap*)","Std.DTreeMap", "app (EmptyCollection.emptyCollection) (Std.DTreeMap*)","Std.DTreeMap.Raw", "app (EmptyCollection.emptyCollection) (Std.DTreeMap.Raw*)","Std.ExtDTreeMap", "app (EmptyCollection.emptyCollection) (Std.ExtDTreeMap*)","Std.HashMap", "app (EmptyCollection.emptyCollection) (Std.HashMap*)","Std.HashMap.Raw", "app (EmptyCollection.emptyCollection) (Std.HashMap.Raw*)","Std.ExtHashMap", "app (EmptyCollection.emptyCollection) (Std.ExtHashMap*)","Std.TreeMap", "app (EmptyCollection.emptyCollection) (Std.TreeMap*)","Std.TreeMap.Raw", "app (EmptyCollection.emptyCollection) (Std.TreeMap.Raw*)","Std.ExtTreeMap", "app (EmptyCollection.emptyCollection) (Std.ExtTreeMap*)","Std.HashSet", "app (EmptyCollection.emptyCollection) (Std.HashSet*)","Std.HashSet.Raw", "app (EmptyCollection.emptyCollection) (Std.HashSet.Raw*)","Std.ExtHashSet", "app (EmptyCollection.emptyCollection) (Std.ExtHashSet*)","Std.TreeSet", "app (EmptyCollection.emptyCollection) (Std.TreeSet*)","Std.TreeSet.Raw", "app (EmptyCollection.emptyCollection) (Std.TreeSet.Raw*)","Std.ExtTreeSet", "app (EmptyCollection.emptyCollection) (Std.ExtTreeSet*)",],
]
facts := #[
«2cb3c441-9663-4ce7-9527-0f40fc29925a»,
«7743a485-024d-43b6-bd5f-ebd3182eb94d»,
«5ceaa26a-d2cb-4df3-9ac8-b5c11db2ae9d»,
]
def restoreState : RestoreStateM Unit := do
addAssociationTable table

View File

@@ -0,0 +1,21 @@
import Grove.Framework
/-
This file is autogenerated by grove. You can manually edit it, for example to resolve merge
conflicts, but be careful.
-/
open Grove.Framework Widget
namespace GroveStdlib.Generated.«associative-modification-operations»
def table : AssociationTable.Data .subexpression where
widgetId := "associative-modification-operations"
rows := #[
]
facts := #[
]
def restoreState : RestoreStateM Unit := do
addAssociationTable table

View File

@@ -0,0 +1,445 @@
import Grove.Framework
/-
This file is autogenerated by grove. You can manually edit it, for example to resolve merge
conflicts, but be careful.
-/
open Grove.Framework Widget
namespace GroveStdlib.Generated.«associative-query-operations»
def «01f88623-fa5f-4380-9772-b30f2fec5c94» : AssociationTable.Fact .subexpression where
widgetId := "associative-query-operations"
factId := "01f88623-fa5f-4380-9772-b30f2fec5c94"
rowId := "01f88623-fa5f-4380-9772-b30f2fec5c94"
rowState := #["Std.DHashMap", "Std.DHashMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.isEmpty,
renderedStatement := "Std.DHashMap.isEmpty.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n (m : Std.DHashMap α β) : Bool",
isDeprecated := false }),"Std.DHashMap.Raw", "Std.DHashMap.Raw.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.Raw.isEmpty,
renderedStatement := "Std.DHashMap.Raw.isEmpty.{u, v} {α : Type u} {β : α → Type v} (m : Std.DHashMap.Raw α β) : Bool",
isDeprecated := false }),"Std.ExtDHashMap", "Std.ExtDHashMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDHashMap.isEmpty,
renderedStatement := "Std.ExtDHashMap.isEmpty.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n [EquivBEq α] [LawfulHashable α] (m : Std.ExtDHashMap α β) : Bool",
isDeprecated := false }),"Std.DTreeMap", "Std.DTreeMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.isEmpty,
renderedStatement := "Std.DTreeMap.isEmpty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.DTreeMap α β cmp) : Bool",
isDeprecated := false }),"Std.DTreeMap.Raw", "Std.DTreeMap.Raw.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.Raw.isEmpty,
renderedStatement := "Std.DTreeMap.Raw.isEmpty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.DTreeMap.Raw α β cmp) : Bool",
isDeprecated := false }),"Std.ExtDTreeMap", "Std.ExtDTreeMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDTreeMap.isEmpty,
renderedStatement := "Std.ExtDTreeMap.isEmpty.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.ExtDTreeMap α β cmp) : Bool",
isDeprecated := false }),"Std.HashMap", "Std.HashMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashMap.isEmpty,
renderedStatement := "Std.HashMap.isEmpty.{u, v} {α : Type u} {β : Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n (m : Std.HashMap α β) : Bool",
isDeprecated := false }),"Std.HashMap.Raw", "Std.HashMap.Raw.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashMap.Raw.isEmpty,
renderedStatement := "Std.HashMap.Raw.isEmpty.{u, v} {α : Type u} {β : Type v} (m : Std.HashMap.Raw α β) : Bool",
isDeprecated := false }),"Std.ExtHashMap", "Std.ExtHashMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtHashMap.isEmpty,
renderedStatement := "Std.ExtHashMap.isEmpty.{u, v} {α : Type u} {β : Type v} {x✝ : BEq α} {x✝¹ : Hashable α} [EquivBEq α]\n [LawfulHashable α] (m : Std.ExtHashMap α β) : Bool",
isDeprecated := false }),"Std.TreeMap", "Std.TreeMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.isEmpty,
renderedStatement := "Std.TreeMap.isEmpty.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering}\n (t : Std.TreeMap α β cmp) : Bool",
isDeprecated := false }),"Std.TreeMap.Raw", "Std.TreeMap.Raw.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.Raw.isEmpty,
renderedStatement := "Std.TreeMap.Raw.isEmpty.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering}\n (t : Std.TreeMap.Raw α β cmp) : Bool",
isDeprecated := false }),"Std.ExtTreeMap", "Std.ExtTreeMap.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeMap.isEmpty,
renderedStatement := "Std.ExtTreeMap.isEmpty.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering}\n (t : Std.ExtTreeMap α β cmp) : Bool",
isDeprecated := false }),"Std.HashSet", "Std.HashSet.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.isEmpty,
renderedStatement := "Std.HashSet.isEmpty.{u} {α : Type u} {x✝ : BEq α} {x✝¹ : Hashable α} (m : Std.HashSet α) : Bool",
isDeprecated := false }),"Std.HashSet.Raw", "Std.HashSet.Raw.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.Raw.isEmpty,
renderedStatement := "Std.HashSet.Raw.isEmpty.{u} {α : Type u} (m : Std.HashSet.Raw α) : Bool",
isDeprecated := false }),"Std.ExtHashSet", "Std.ExtHashSet.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtHashSet.isEmpty,
renderedStatement := "Std.ExtHashSet.isEmpty.{u} {α : Type u} {x✝ : BEq α} {x✝¹ : Hashable α} [EquivBEq α]\n [LawfulHashable α] (m : Std.ExtHashSet α) : Bool",
isDeprecated := false }),"Std.TreeSet", "Std.TreeSet.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.isEmpty,
renderedStatement := "Std.TreeSet.isEmpty.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.TreeSet α cmp) : Bool",
isDeprecated := false }),"Std.TreeSet.Raw", "Std.TreeSet.Raw.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.Raw.isEmpty,
renderedStatement := "Std.TreeSet.Raw.isEmpty.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.TreeSet.Raw α cmp) : Bool",
isDeprecated := false }),"Std.ExtTreeSet", "Std.ExtTreeSet.isEmpty", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeSet.isEmpty,
renderedStatement := "Std.ExtTreeSet.isEmpty.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.ExtTreeSet α cmp) : Bool",
isDeprecated := false }),]
metadata := {
status := .done
comment := ""
}
def «f084f852-af71-45b6-8ab3-d251a8144f72» : AssociationTable.Fact .subexpression where
widgetId := "associative-query-operations"
factId := "f084f852-af71-45b6-8ab3-d251a8144f72"
rowId := "f084f852-af71-45b6-8ab3-d251a8144f72"
rowState := #["Std.DHashMap", "Std.DHashMap.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.size,
renderedStatement := "Std.DHashMap.size.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n (m : Std.DHashMap α β) : Nat",
isDeprecated := false }),"Std.DHashMap.Raw", "Std.DHashMap.Raw.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.Raw.size,
renderedStatement := "Std.DHashMap.Raw.size.{u, v} {α : Type u} {β : α → Type v} (self : Std.DHashMap.Raw α β) : Nat",
isDeprecated := false }),"Std.ExtDHashMap", "Std.ExtDHashMap.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDHashMap.size,
renderedStatement := "Std.ExtDHashMap.size.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n [EquivBEq α] [LawfulHashable α] (m : Std.ExtDHashMap α β) : Nat",
isDeprecated := false }),"Std.DTreeMap", "Std.DTreeMap.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.size,
renderedStatement := "Std.DTreeMap.size.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.DTreeMap α β cmp) : Nat",
isDeprecated := false }),"Std.DTreeMap.Raw", "Std.DTreeMap.Raw.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.Raw.size,
renderedStatement := "Std.DTreeMap.Raw.size.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.DTreeMap.Raw α β cmp) : Nat",
isDeprecated := false }),"Std.ExtDTreeMap", "Std.ExtDTreeMap.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDTreeMap.size,
renderedStatement := "Std.ExtDTreeMap.size.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.ExtDTreeMap α β cmp) : Nat",
isDeprecated := false }),"Std.HashMap", "Std.HashMap.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashMap.size,
renderedStatement := "Std.HashMap.size.{u, v} {α : Type u} {β : Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n (m : Std.HashMap α β) : Nat",
isDeprecated := false }),"Std.HashMap.Raw", "Std.HashMap.Raw.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashMap.Raw.size,
renderedStatement := "Std.HashMap.Raw.size.{u, v} {α : Type u} {β : Type v} (m : Std.HashMap.Raw α β) : Nat",
isDeprecated := false }),"Std.ExtHashMap", "Std.ExtHashMap.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtHashMap.size,
renderedStatement := "Std.ExtHashMap.size.{u, v} {α : Type u} {β : Type v} {x✝ : BEq α} {x✝¹ : Hashable α} [EquivBEq α]\n [LawfulHashable α] (m : Std.ExtHashMap α β) : Nat",
isDeprecated := false }),"Std.TreeMap", "Std.TreeMap.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.size,
renderedStatement := "Std.TreeMap.size.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering}\n (t : Std.TreeMap α β cmp) : Nat",
isDeprecated := false }),"Std.TreeMap.Raw", "Std.TreeMap.Raw.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.Raw.size,
renderedStatement := "Std.TreeMap.Raw.size.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering}\n (t : Std.TreeMap.Raw α β cmp) : Nat",
isDeprecated := false }),"Std.ExtTreeMap", "Std.ExtTreeMap.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeMap.size,
renderedStatement := "Std.ExtTreeMap.size.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering}\n (t : Std.ExtTreeMap α β cmp) : Nat",
isDeprecated := false }),"Std.HashSet", "Std.HashSet.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.size,
renderedStatement := "Std.HashSet.size.{u} {α : Type u} {x✝ : BEq α} {x✝¹ : Hashable α} (m : Std.HashSet α) : Nat",
isDeprecated := false }),"Std.HashSet.Raw", "Std.HashSet.Raw.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.Raw.size,
renderedStatement := "Std.HashSet.Raw.size.{u} {α : Type u} (m : Std.HashSet.Raw α) : Nat",
isDeprecated := false }),"Std.ExtHashSet", "Std.ExtHashSet.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtHashSet.size,
renderedStatement := "Std.ExtHashSet.size.{u} {α : Type u} {x✝ : BEq α} {x✝¹ : Hashable α} [EquivBEq α] [LawfulHashable α]\n (m : Std.ExtHashSet α) : Nat",
isDeprecated := false }),"Std.TreeSet", "Std.TreeSet.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.size,
renderedStatement := "Std.TreeSet.size.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.TreeSet α cmp) : Nat",
isDeprecated := false }),"Std.TreeSet.Raw", "Std.TreeSet.Raw.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.Raw.size,
renderedStatement := "Std.TreeSet.Raw.size.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.TreeSet.Raw α cmp) : Nat",
isDeprecated := false }),"Std.ExtTreeSet", "Std.ExtTreeSet.size", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeSet.size,
renderedStatement := "Std.ExtTreeSet.size.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.ExtTreeSet α cmp) : Nat",
isDeprecated := false }),]
metadata := {
status := .done
comment := ""
}
def «f4e6fa70-5aed-439d-aaad-5f4ced65bf7b» : AssociationTable.Fact .subexpression where
widgetId := "associative-query-operations"
factId := "f4e6fa70-5aed-439d-aaad-5f4ced65bf7b"
rowId := "f4e6fa70-5aed-439d-aaad-5f4ced65bf7b"
rowState := #["Std.DTreeMap", "Std.DTreeMap.any", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.any,
renderedStatement := "Std.DTreeMap.any.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.DTreeMap α β cmp) (p : (a : α) → β a → Bool) : Bool",
isDeprecated := false }),"Std.DTreeMap.Raw", "Std.DTreeMap.Raw.any", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.Raw.any,
renderedStatement := "Std.DTreeMap.Raw.any.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.DTreeMap.Raw α β cmp) (p : (a : α) → β a → Bool) : Bool",
isDeprecated := false }),"Std.ExtDTreeMap", "Std.ExtDTreeMap.any", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDTreeMap.any,
renderedStatement := "Std.ExtDTreeMap.any.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} [Std.TransCmp cmp]\n (t : Std.ExtDTreeMap α β cmp) (p : (a : α) → β a → Bool) : Bool",
isDeprecated := false }),"Std.TreeMap", "Std.TreeMap.any", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.any,
renderedStatement := "Std.TreeMap.any.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering} (t : Std.TreeMap α β cmp)\n (p : α → β → Bool) : Bool",
isDeprecated := false }),"Std.TreeMap.Raw", "Std.TreeMap.Raw.any", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.Raw.any,
renderedStatement := "Std.TreeMap.Raw.any.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering}\n (t : Std.TreeMap.Raw α β cmp) (p : α → β → Bool) : Bool",
isDeprecated := false }),"Std.ExtTreeMap", "Std.ExtTreeMap.any", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeMap.any,
renderedStatement := "Std.ExtTreeMap.any.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering} [Std.TransCmp cmp]\n (t : Std.ExtTreeMap α β cmp) (p : α → β → Bool) : Bool",
isDeprecated := false }),"Std.HashSet", "Std.HashSet.any", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.any,
renderedStatement := "Std.HashSet.any.{u} {α : Type u} {x✝ : BEq α} {x✝¹ : Hashable α} (m : Std.HashSet α)\n (p : α → Bool) : Bool",
isDeprecated := false }),"Std.HashSet.Raw", "Std.HashSet.Raw.any", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.Raw.any,
renderedStatement := "Std.HashSet.Raw.any.{u} {α : Type u} (m : Std.HashSet.Raw α) (p : α → Bool) : Bool",
isDeprecated := false }),"Std.TreeSet", "Std.TreeSet.any", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.any,
renderedStatement := "Std.TreeSet.any.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.TreeSet α cmp) (p : α → Bool) :\n Bool",
isDeprecated := false }),"Std.TreeSet.Raw", "Std.TreeSet.Raw.any", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.Raw.any,
renderedStatement := "Std.TreeSet.Raw.any.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.TreeSet.Raw α cmp)\n (p : α → Bool) : Bool",
isDeprecated := false }),"Std.ExtTreeSet", "Std.ExtTreeSet.any", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeSet.any,
renderedStatement := "Std.ExtTreeSet.any.{u} {α : Type u} {cmp : αα → Ordering} [Std.TransCmp cmp]\n (t : Std.ExtTreeSet α cmp) (p : α → Bool) : Bool",
isDeprecated := false }),]
metadata := {
status := .bad
comment := "Missing for some containers"
}
def «c1d181f6-3204-4956-946f-e81619f9feb4» : AssociationTable.Fact .subexpression where
widgetId := "associative-query-operations"
factId := "c1d181f6-3204-4956-946f-e81619f9feb4"
rowId := "c1d181f6-3204-4956-946f-e81619f9feb4"
rowState := #["Std.DTreeMap", "Std.DTreeMap.all", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.all,
renderedStatement := "Std.DTreeMap.all.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.DTreeMap α β cmp) (p : (a : α) → β a → Bool) : Bool",
isDeprecated := false }),"Std.DTreeMap.Raw", "Std.DTreeMap.Raw.all", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.Raw.all,
renderedStatement := "Std.DTreeMap.Raw.all.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n (t : Std.DTreeMap.Raw α β cmp) (p : (a : α) → β a → Bool) : Bool",
isDeprecated := false }),"Std.ExtDTreeMap", "Std.ExtDTreeMap.all", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDTreeMap.all,
renderedStatement := "Std.ExtDTreeMap.all.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} [Std.TransCmp cmp]\n (t : Std.ExtDTreeMap α β cmp) (p : (a : α) → β a → Bool) : Bool",
isDeprecated := false }),"Std.TreeMap", "Std.TreeMap.all", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.all,
renderedStatement := "Std.TreeMap.all.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering} (t : Std.TreeMap α β cmp)\n (p : α → β → Bool) : Bool",
isDeprecated := false }),"Std.TreeMap.Raw", "Std.TreeMap.Raw.all", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.Raw.all,
renderedStatement := "Std.TreeMap.Raw.all.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering}\n (t : Std.TreeMap.Raw α β cmp) (p : α → β → Bool) : Bool",
isDeprecated := false }),"Std.ExtTreeMap", "Std.ExtTreeMap.all", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeMap.all,
renderedStatement := "Std.ExtTreeMap.all.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering} [Std.TransCmp cmp]\n (t : Std.ExtTreeMap α β cmp) (p : α → β → Bool) : Bool",
isDeprecated := false }),"Std.HashSet", "Std.HashSet.all", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.all,
renderedStatement := "Std.HashSet.all.{u} {α : Type u} {x✝ : BEq α} {x✝¹ : Hashable α} (m : Std.HashSet α)\n (p : α → Bool) : Bool",
isDeprecated := false }),"Std.HashSet.Raw", "Std.HashSet.Raw.all", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.Raw.all,
renderedStatement := "Std.HashSet.Raw.all.{u} {α : Type u} (m : Std.HashSet.Raw α) (p : α → Bool) : Bool",
isDeprecated := false }),"Std.TreeSet", "Std.TreeSet.all", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.all,
renderedStatement := "Std.TreeSet.all.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.TreeSet α cmp) (p : α → Bool) :\n Bool",
isDeprecated := false }),"Std.TreeSet.Raw", "Std.TreeSet.Raw.all", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.Raw.all,
renderedStatement := "Std.TreeSet.Raw.all.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.TreeSet.Raw α cmp)\n (p : α → Bool) : Bool",
isDeprecated := false }),"Std.ExtTreeSet", "Std.ExtTreeSet.all", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeSet.all,
renderedStatement := "Std.ExtTreeSet.all.{u} {α : Type u} {cmp : αα → Ordering} [Std.TransCmp cmp]\n (t : Std.ExtTreeSet α cmp) (p : α → Bool) : Bool",
isDeprecated := false }),]
metadata := {
status := .bad
comment := "Missing for some containers"
}
def «efe57f41-7db7-4303-b3a6-5216a70c43ce» : AssociationTable.Fact .subexpression where
widgetId := "associative-query-operations"
factId := "efe57f41-7db7-4303-b3a6-5216a70c43ce"
rowId := "efe57f41-7db7-4303-b3a6-5216a70c43ce"
rowState := #["Std.DHashMap", "Std.DHashMap.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.getD,
renderedStatement := "Std.DHashMap.getD.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α} [LawfulBEq α]\n (m : Std.DHashMap α β) (a : α) (fallback : β a) : β a",
isDeprecated := false }),"Std.DHashMap.Raw", "Std.DHashMap.Raw.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.Raw.getD,
renderedStatement := "Std.DHashMap.Raw.getD.{u, v} {α : Type u} {β : α → Type v} [BEq α] [Hashable α] [LawfulBEq α]\n (m : Std.DHashMap.Raw α β) (a : α) (fallback : β a) : β a",
isDeprecated := false }),"Std.ExtDHashMap", "Std.ExtDHashMap.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDHashMap.getD,
renderedStatement := "Std.ExtDHashMap.getD.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n [LawfulBEq α] (m : Std.ExtDHashMap α β) (a : α) (fallback : β a) : β a",
isDeprecated := false }),"Std.DTreeMap", "Std.DTreeMap.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.getD,
renderedStatement := "Std.DTreeMap.getD.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n [Std.LawfulEqCmp cmp] (t : Std.DTreeMap α β cmp) (a : α) (fallback : β a) : β a",
isDeprecated := false }),"Std.DTreeMap.Raw", "Std.DTreeMap.Raw.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.Raw.getD,
renderedStatement := "Std.DTreeMap.Raw.getD.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n [Std.LawfulEqCmp cmp] (t : Std.DTreeMap.Raw α β cmp) (a : α) (fallback : β a) : β a",
isDeprecated := false }),"Std.ExtDTreeMap", "Std.ExtDTreeMap.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDTreeMap.getD,
renderedStatement := "Std.ExtDTreeMap.getD.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n [Std.TransCmp cmp] [Std.LawfulEqCmp cmp] (t : Std.ExtDTreeMap α β cmp) (a : α) (fallback : β a) :\n β a",
isDeprecated := false }),"Std.HashMap", "Std.HashMap.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashMap.getD,
renderedStatement := "Std.HashMap.getD.{u, v} {α : Type u} {β : Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n (m : Std.HashMap α β) (a : α) (fallback : β) : β",
isDeprecated := false }),"Std.HashMap.Raw", "Std.HashMap.Raw.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashMap.Raw.getD,
renderedStatement := "Std.HashMap.Raw.getD.{u, v} {α : Type u} {β : Type v} [BEq α] [Hashable α] (m : Std.HashMap.Raw α β)\n (a : α) (fallback : β) : β",
isDeprecated := false }),"Std.ExtHashMap", "Std.ExtHashMap.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtHashMap.getD,
renderedStatement := "Std.ExtHashMap.getD.{u, v} {α : Type u} {β : Type v} {x✝ : BEq α} {x✝¹ : Hashable α} [EquivBEq α]\n [LawfulHashable α] (m : Std.ExtHashMap α β) (a : α) (fallback : β) : β",
isDeprecated := false }),"Std.TreeMap", "Std.TreeMap.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.getD,
renderedStatement := "Std.TreeMap.getD.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering} (t : Std.TreeMap α β cmp)\n (a : α) (fallback : β) : β",
isDeprecated := false }),"Std.TreeMap.Raw", "Std.TreeMap.Raw.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeMap.Raw.getD,
renderedStatement := "Std.TreeMap.Raw.getD.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering}\n (t : Std.TreeMap.Raw α β cmp) (a : α) (fallback : β) : β",
isDeprecated := false }),"Std.ExtTreeMap", "Std.ExtTreeMap.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeMap.getD,
renderedStatement := "Std.ExtTreeMap.getD.{u, v} {α : Type u} {β : Type v} {cmp : αα → Ordering} [Std.TransCmp cmp]\n (t : Std.ExtTreeMap α β cmp) (a : α) (fallback : β) : β",
isDeprecated := false }),"Std.HashSet", "Std.HashSet.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.getD,
renderedStatement := "Std.HashSet.getD.{u} {α : Type u} [BEq α] [Hashable α] (m : Std.HashSet α) (a fallback : α) : α",
isDeprecated := false }),"Std.HashSet.Raw", "Std.HashSet.Raw.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.Raw.getD,
renderedStatement := "Std.HashSet.Raw.getD.{u} {α : Type u} [BEq α] [Hashable α] (m : Std.HashSet.Raw α)\n (a fallback : α) : α",
isDeprecated := false }),"Std.ExtHashSet", "Std.ExtHashSet.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtHashSet.getD,
renderedStatement := "Std.ExtHashSet.getD.{u} {α : Type u} {x✝ : BEq α} {x✝¹ : Hashable α} [EquivBEq α] [LawfulHashable α]\n (m : Std.ExtHashSet α) (a fallback : α) : α",
isDeprecated := false }),"Std.TreeSet", "Std.TreeSet.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.getD,
renderedStatement := "Std.TreeSet.getD.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.TreeSet α cmp)\n (a fallback : α) : α",
isDeprecated := false }),"Std.TreeSet.Raw", "Std.TreeSet.Raw.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.Raw.getD,
renderedStatement := "Std.TreeSet.Raw.getD.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.TreeSet.Raw α cmp)\n (a fallback : α) : α",
isDeprecated := false }),"Std.ExtTreeSet", "Std.ExtTreeSet.getD", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeSet.getD,
renderedStatement := "Std.ExtTreeSet.getD.{u} {α : Type u} {cmp : αα → Ordering} [Std.TransCmp cmp]\n (t : Std.ExtTreeSet α cmp) (a fallback : α) : α",
isDeprecated := false }),]
metadata := {
status := .done
comment := ""
}
def «e23b1119-3b57-433e-a68d-68fd70b9943d» : AssociationTable.Fact .subexpression where
widgetId := "associative-query-operations"
factId := "e23b1119-3b57-433e-a68d-68fd70b9943d"
rowId := "e23b1119-3b57-433e-a68d-68fd70b9943d"
rowState := #["Std.DHashMap", "Std.DHashMap.get", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.get,
renderedStatement := "Std.DHashMap.get.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α} [LawfulBEq α]\n (m : Std.DHashMap α β) (a : α) (h : a ∈ m) : β a",
isDeprecated := false }),"Std.DHashMap.Raw", "Std.DHashMap.Raw.Const.get", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DHashMap.Raw.Const.get,
renderedStatement := "Std.DHashMap.Raw.Const.get.{u, v} {α : Type u} {β : Type v} [BEq α] [Hashable α]\n (m : Std.DHashMap.Raw α fun x => β) (a : α) (h : a ∈ m) : β",
isDeprecated := false }),"Std.ExtDHashMap", "Std.ExtDHashMap.get", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDHashMap.get,
renderedStatement := "Std.ExtDHashMap.get.{u, v} {α : Type u} {β : α → Type v} {x✝ : BEq α} {x✝¹ : Hashable α}\n [LawfulBEq α] (m : Std.ExtDHashMap α β) (a : α) (h : a ∈ m) : β a",
isDeprecated := false }),"Std.DTreeMap", "Std.DTreeMap.get", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.get,
renderedStatement := "Std.DTreeMap.get.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} [Std.LawfulEqCmp cmp]\n (t : Std.DTreeMap α β cmp) (a : α) (h : a ∈ t) : β a",
isDeprecated := false }),"Std.DTreeMap.Raw", "Std.DTreeMap.Raw.get", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.DTreeMap.Raw.get,
renderedStatement := "Std.DTreeMap.Raw.get.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering}\n [Std.LawfulEqCmp cmp] (t : Std.DTreeMap.Raw α β cmp) (a : α) (h : a ∈ t) : β a",
isDeprecated := false }),"Std.ExtDTreeMap", "Std.ExtDTreeMap.get", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtDTreeMap.get,
renderedStatement := "Std.ExtDTreeMap.get.{u, v} {α : Type u} {β : α → Type v} {cmp : αα → Ordering} [Std.TransCmp cmp]\n [Std.LawfulEqCmp cmp] (t : Std.ExtDTreeMap α β cmp) (a : α) (h : a ∈ t) : β a",
isDeprecated := false }),"Std.HashMap", "app (GetElem.getElem) (Std.HashMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (GetElem.getElem) (Std.HashMap*)", displayShort := "Std.HashMap[·]" },"Std.HashMap.Raw", "app (GetElem.getElem) (Std.HashMap.Raw*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (GetElem.getElem) (Std.HashMap.Raw*)", displayShort := "Std.HashMap.Raw[·]" },"Std.ExtHashMap", "app (GetElem.getElem) (Std.ExtHashMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (GetElem.getElem) (Std.ExtHashMap*)", displayShort := "Std.ExtHashMap[·]" },"Std.TreeMap", "app (GetElem.getElem) (Std.TreeMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (GetElem.getElem) (Std.TreeMap*)", displayShort := "Std.TreeMap[·]" },"Std.TreeMap.Raw", "app (GetElem.getElem) (Std.TreeMap.Raw*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (GetElem.getElem) (Std.TreeMap.Raw*)", displayShort := "Std.TreeMap.Raw[·]" },"Std.ExtTreeMap", "app (GetElem.getElem) (Std.ExtTreeMap*)", Grove.Framework.Subexpression.State.predicate
{ key := "app (GetElem.getElem) (Std.ExtTreeMap*)", displayShort := "Std.ExtTreeMap[·]" },"Std.HashSet", "Std.HashSet.get", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.get,
renderedStatement := "Std.HashSet.get.{u} {α : Type u} [BEq α] [Hashable α] (m : Std.HashSet α) (a : α) (h : a ∈ m) : α",
isDeprecated := false }),"Std.HashSet.Raw", "Std.HashSet.Raw.get", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.HashSet.Raw.get,
renderedStatement := "Std.HashSet.Raw.get.{u} {α : Type u} [BEq α] [Hashable α] (m : Std.HashSet.Raw α) (a : α)\n (h : a ∈ m) : α",
isDeprecated := false }),"Std.ExtHashSet", "Std.ExtHashSet.get", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtHashSet.get,
renderedStatement := "Std.ExtHashSet.get.{u} {α : Type u} {x✝ : BEq α} {x✝¹ : Hashable α} [EquivBEq α] [LawfulHashable α]\n (m : Std.ExtHashSet α) (a : α) (h : a ∈ m) : α",
isDeprecated := false }),"Std.TreeSet", "Std.TreeSet.get", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.get,
renderedStatement := "Std.TreeSet.get.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.TreeSet α cmp) (a : α)\n (h : a ∈ t) : α",
isDeprecated := false }),"Std.TreeSet.Raw", "Std.TreeSet.Raw.get", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.TreeSet.Raw.get,
renderedStatement := "Std.TreeSet.Raw.get.{u} {α : Type u} {cmp : αα → Ordering} (t : Std.TreeSet.Raw α cmp) (a : α)\n (h : a ∈ t) : α",
isDeprecated := false }),"Std.ExtTreeSet", "Std.ExtTreeSet.get", Grove.Framework.Subexpression.State.declaration
(Grove.Framework.Declaration.def
{ name := `Std.ExtTreeSet.get,
renderedStatement := "Std.ExtTreeSet.get.{u} {α : Type u} {cmp : αα → Ordering} [Std.TransCmp cmp]\n (t : Std.ExtTreeSet α cmp) (a : α) (h : a ∈ t) : α",
isDeprecated := false }),]
metadata := {
status := .bad
comment := "Should *Set have GetElem?"
}
def table : AssociationTable.Data .subexpression where
widgetId := "associative-query-operations"
rows := #[
"01f88623-fa5f-4380-9772-b30f2fec5c94", "isEmpty", #["Std.DHashMap", "Std.DHashMap.isEmpty","Std.DHashMap.Raw", "Std.DHashMap.Raw.isEmpty","Std.ExtDHashMap", "Std.ExtDHashMap.isEmpty","Std.DTreeMap", "Std.DTreeMap.isEmpty","Std.DTreeMap.Raw", "Std.DTreeMap.Raw.isEmpty","Std.ExtDTreeMap", "Std.ExtDTreeMap.isEmpty","Std.HashMap", "Std.HashMap.isEmpty","Std.HashMap.Raw", "Std.HashMap.Raw.isEmpty","Std.ExtHashMap", "Std.ExtHashMap.isEmpty","Std.TreeMap", "Std.TreeMap.isEmpty","Std.TreeMap.Raw", "Std.TreeMap.Raw.isEmpty","Std.ExtTreeMap", "Std.ExtTreeMap.isEmpty","Std.HashSet", "Std.HashSet.isEmpty","Std.HashSet.Raw", "Std.HashSet.Raw.isEmpty","Std.ExtHashSet", "Std.ExtHashSet.isEmpty","Std.TreeSet", "Std.TreeSet.isEmpty","Std.TreeSet.Raw", "Std.TreeSet.Raw.isEmpty","Std.ExtTreeSet", "Std.ExtTreeSet.isEmpty",],
"f084f852-af71-45b6-8ab3-d251a8144f72", "size", #["Std.DHashMap", "Std.DHashMap.size","Std.DHashMap.Raw", "Std.DHashMap.Raw.size","Std.ExtDHashMap", "Std.ExtDHashMap.size","Std.DTreeMap", "Std.DTreeMap.size","Std.DTreeMap.Raw", "Std.DTreeMap.Raw.size","Std.ExtDTreeMap", "Std.ExtDTreeMap.size","Std.HashMap", "Std.HashMap.size","Std.HashMap.Raw", "Std.HashMap.Raw.size","Std.ExtHashMap", "Std.ExtHashMap.size","Std.TreeMap", "Std.TreeMap.size","Std.TreeMap.Raw", "Std.TreeMap.Raw.size","Std.ExtTreeMap", "Std.ExtTreeMap.size","Std.HashSet", "Std.HashSet.size","Std.HashSet.Raw", "Std.HashSet.Raw.size","Std.ExtHashSet", "Std.ExtHashSet.size","Std.TreeSet", "Std.TreeSet.size","Std.TreeSet.Raw", "Std.TreeSet.Raw.size","Std.ExtTreeSet", "Std.ExtTreeSet.size",],
"f4e6fa70-5aed-439d-aaad-5f4ced65bf7b", "any", #["Std.DTreeMap", "Std.DTreeMap.any","Std.DTreeMap.Raw", "Std.DTreeMap.Raw.any","Std.ExtDTreeMap", "Std.ExtDTreeMap.any","Std.TreeMap", "Std.TreeMap.any","Std.TreeMap.Raw", "Std.TreeMap.Raw.any","Std.ExtTreeMap", "Std.ExtTreeMap.any","Std.HashSet", "Std.HashSet.any","Std.HashSet.Raw", "Std.HashSet.Raw.any","Std.TreeSet", "Std.TreeSet.any","Std.TreeSet.Raw", "Std.TreeSet.Raw.any","Std.ExtTreeSet", "Std.ExtTreeSet.any",],
"c1d181f6-3204-4956-946f-e81619f9feb4", "all", #["Std.DTreeMap", "Std.DTreeMap.all","Std.DTreeMap.Raw", "Std.DTreeMap.Raw.all","Std.ExtDTreeMap", "Std.ExtDTreeMap.all","Std.TreeMap", "Std.TreeMap.all","Std.TreeMap.Raw", "Std.TreeMap.Raw.all","Std.ExtTreeMap", "Std.ExtTreeMap.all","Std.HashSet", "Std.HashSet.all","Std.HashSet.Raw", "Std.HashSet.Raw.all","Std.TreeSet", "Std.TreeSet.all","Std.TreeSet.Raw", "Std.TreeSet.Raw.all","Std.ExtTreeSet", "Std.ExtTreeSet.all",],
"efe57f41-7db7-4303-b3a6-5216a70c43ce", "getD", #["Std.DHashMap", "Std.DHashMap.getD","Std.DHashMap.Raw", "Std.DHashMap.Raw.getD","Std.ExtDHashMap", "Std.ExtDHashMap.getD","Std.DTreeMap", "Std.DTreeMap.getD","Std.DTreeMap.Raw", "Std.DTreeMap.Raw.getD","Std.ExtDTreeMap", "Std.ExtDTreeMap.getD","Std.HashMap", "Std.HashMap.getD","Std.HashMap.Raw", "Std.HashMap.Raw.getD","Std.ExtHashMap", "Std.ExtHashMap.getD","Std.TreeMap", "Std.TreeMap.getD","Std.TreeMap.Raw", "Std.TreeMap.Raw.getD","Std.ExtTreeMap", "Std.ExtTreeMap.getD","Std.HashSet", "Std.HashSet.getD","Std.HashSet.Raw", "Std.HashSet.Raw.getD","Std.ExtHashSet", "Std.ExtHashSet.getD","Std.TreeSet", "Std.TreeSet.getD","Std.TreeSet.Raw", "Std.TreeSet.Raw.getD","Std.ExtTreeSet", "Std.ExtTreeSet.getD",],
"e23b1119-3b57-433e-a68d-68fd70b9943d", "getElem", #["Std.DHashMap", "Std.DHashMap.get","Std.DHashMap.Raw", "Std.DHashMap.Raw.Const.get","Std.ExtDHashMap", "Std.ExtDHashMap.get","Std.DTreeMap", "Std.DTreeMap.get","Std.DTreeMap.Raw", "Std.DTreeMap.Raw.get","Std.ExtDTreeMap", "Std.ExtDTreeMap.get","Std.HashMap", "app (GetElem.getElem) (Std.HashMap*)","Std.HashMap.Raw", "app (GetElem.getElem) (Std.HashMap.Raw*)","Std.ExtHashMap", "app (GetElem.getElem) (Std.ExtHashMap*)","Std.TreeMap", "app (GetElem.getElem) (Std.TreeMap*)","Std.TreeMap.Raw", "app (GetElem.getElem) (Std.TreeMap.Raw*)","Std.ExtTreeMap", "app (GetElem.getElem) (Std.ExtTreeMap*)","Std.HashSet", "Std.HashSet.get","Std.HashSet.Raw", "Std.HashSet.Raw.get","Std.ExtHashSet", "Std.ExtHashSet.get","Std.TreeSet", "Std.TreeSet.get","Std.TreeSet.Raw", "Std.TreeSet.Raw.get","Std.ExtTreeSet", "Std.ExtTreeSet.get",],
]
facts := #[
«01f88623-fa5f-4380-9772-b30f2fec5c94»,
«f084f852-af71-45b6-8ab3-d251a8144f72»,
«f4e6fa70-5aed-439d-aaad-5f4ced65bf7b»,
«c1d181f6-3204-4956-946f-e81619f9feb4»,
«efe57f41-7db7-4303-b3a6-5216a70c43ce»,
«e23b1119-3b57-433e-a68d-68fd70b9943d»,
]
def restoreState : RestoreStateM Unit := do
addAssociationTable table

View File

@@ -0,0 +1,31 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import GroveStdlib.Std.CoreTypesAndOperations
import GroveStdlib.Std.LanguageConstructs
import GroveStdlib.Std.Libraries
import GroveStdlib.Std.OperatingSystemAbstractions
open Grove.Framework Widget
namespace GroveStdlib
namespace Std
def introduction : Node :=
.text "Welcome to the interactive Lean standard library outline!"
end Std
def std : Node :=
.section "stdlib" "The Lean standard library" #[
Std.introduction,
Std.coreTypesAndOperations,
Std.languageConstructs,
Std.libraries,
Std.operatingSystemAbstractions
]
end GroveStdlib

View File

@@ -0,0 +1,28 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
import GroveStdlib.Std.CoreTypesAndOperations.BasicTypes
import GroveStdlib.Std.CoreTypesAndOperations.Containers
import GroveStdlib.Std.CoreTypesAndOperations.Numbers
import GroveStdlib.Std.CoreTypesAndOperations.StringsAndFormatting
open Grove.Framework Widget
namespace GroveStdlib.Std
namespace CoreTypesAndOperations
end CoreTypesAndOperations
def coreTypesAndOperations : Node :=
.section "core-types-and-operations" "Core types and operations" #[
CoreTypesAndOperations.basicTypes,
CoreTypesAndOperations.containers,
CoreTypesAndOperations.numbers,
CoreTypesAndOperations.stringsAndFormatting
]
end GroveStdlib.Std

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.CoreTypesAndOperations
namespace BasicTypes
end BasicTypes
def basicTypes : Node :=
.section "basic-types" "Basic types" #[]
end GroveStdlib.Std.CoreTypesAndOperations

View File

@@ -0,0 +1,110 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.CoreTypesAndOperations
namespace Containers
namespace SequentialContainers
end SequentialContainers
def sequentialContainers : Node :=
.section "sequential-containers" "Sequential containers" #[]
namespace AssociativeContainers
def associativeContainers : List Lean.Name :=
[`Std.DHashMap, `Std.DHashMap.Raw, `Std.ExtDHashMap, `Std.DTreeMap, `Std.DTreeMap.Raw, `Std.ExtDTreeMap, `Std.HashMap,
`Std.HashMap.Raw, `Std.ExtHashMap, `Std.TreeMap, `Std.TreeMap.Raw, `Std.ExtTreeMap, `Std.HashSet, `Std.HashSet.Raw, `Std.ExtHashSet,
`Std.TreeSet, `Std.TreeSet.Raw, `Std.ExtTreeSet]
def associativeQueryOperations : AssociationTable .subexpression associativeContainers where
id := "associative-query-operations"
title := "Associative query operations"
description := "Operations that take as input an associative container and return a 'single' piece of information (e.g., `GetElem` or `isEmpty`, but not `toList`)."
dataSources n :=
(DataSource.definitionsInNamespace n)
|>.map Subexpression.declaration
|>.or (DataSource.getElem n)
def associativeCreationOperations : AssociationTable .subexpression associativeContainers where
id := "associative-creation-operations"
title := "Associative creation operations"
description := "Operations that create a new associative container"
dataSources n :=
(DataSource.definitionsInNamespace n)
|>.map Subexpression.declaration
|>.or (DataSource.emptyCollection n)
def associativeModificationOperations : AssociationTable .subexpression associativeContainers where
id := "associative-modification-operations"
title := "Associative modification operations"
description := "Operations that both accept and return an associative container"
dataSources n :=
(DataSource.definitionsInNamespace n)
|>.map Subexpression.declaration
def associativeCreateThenQuery : Table .subexpression .subexpression .declaration associativeContainers where
id := "associative-create-then-query"
title := "Associative create then query"
description := "Lemmas that say what happens when creating a new associative container and then immediately querying from it"
rowsFrom := .table associativeCreationOperations
columnsFrom := .table associativeQueryOperations
cellData := .classic _ { relevantNamespaces := associativeContainers }
def allOperationsCovered : Assertion where
widgetId := "associative-all-operations-covered"
title := "All operations on associative containers covered"
description := "All operations on an associative container should appear in at least one of the tables"
check := do
let allValuesArray : Array String #[associativeQueryOperations, associativeCreationOperations, associativeModificationOperations].flatMapM valuesInAssociationTable
let allValues : Std.HashSet String := Std.HashSet.ofArray allValuesArray
let env Lean.getEnv
let mut numBad := 0
for (n, _) in env.constants do
if associativeContainers.any (fun namesp => namesp.isPrefixOf n) then
if !n.toString allValues then
numBad := numBad + 1
return #[{
assertionId := "all-covered"
description := "All operations should be covered"
passed := numBad == 0
message := if numBad = 0 then "All operations were covered" else s!"There were {numBad} operations that were not covered."
}]
end AssociativeContainers
open AssociativeContainers in
def associativeContainers : Node :=
.section "associative-containers" "Associative containers" #[
.associationTable associativeQueryOperations,
.associationTable associativeCreationOperations,
.associationTable associativeModificationOperations,
.table associativeCreateThenQuery,
.assertion allOperationsCovered
]
namespace PersistentDataStructures
end PersistentDataStructures
def persistentDataStructures : Node :=
.section "persistent-data-structures" "Persistent data structures" #[]
end Containers
def containers : Node :=
.section "containers" "Containers" #[
Containers.sequentialContainers,
Containers.associativeContainers,
Containers.persistentDataStructures
]
end GroveStdlib.Std.CoreTypesAndOperations

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.CoreTypesAndOperations
namespace Numbers
end Numbers
def numbers : Node :=
.section "numbers" "Numbers" #[]
end GroveStdlib.Std.CoreTypesAndOperations

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.CoreTypesAndOperations
namespace StringsAndFormatting
end StringsAndFormatting
def stringsAndFormatting : Node :=
.section "strings-and-formatting" "Strings and formatting" #[]
end GroveStdlib.Std.CoreTypesAndOperations

View File

@@ -0,0 +1,26 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
import GroveStdlib.Std.LanguageConstructs.ComparisonOrderingHashing
import GroveStdlib.Std.LanguageConstructs.Monads
import GroveStdlib.Std.LanguageConstructs.RangesAndIterators
open Grove.Framework Widget
namespace GroveStdlib.Std
namespace LanguageConstructs
end LanguageConstructs
def languageConstructs : Node :=
.section "language-constructs" "Language constructs" #[
LanguageConstructs.comparisonOrderingHashing,
LanguageConstructs.monads,
LanguageConstructs.rangesAndIterators
]
end GroveStdlib.Std

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.LanguageConstructs
namespace ComparisonOrderingHashing
end ComparisonOrderingHashing
def comparisonOrderingHashing : Node :=
.section "comparison-ordering-hashing" "Comparison, ordering, hashing" #[]
end GroveStdlib.Std.LanguageConstructs

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.LanguageConstructs
namespace Monads
end Monads
def monads : Node :=
.section "monads" "Monads" #[]
end GroveStdlib.Std.LanguageConstructs

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.LanguageConstructs
namespace RangesAndIterators
end RangesAndIterators
def rangesAndIterators : Node :=
.section "ranges-and-iterators" "Ranges and iterators" #[]
end GroveStdlib.Std.LanguageConstructs

View File

@@ -0,0 +1,24 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
import GroveStdlib.Std.Libraries.DateAndTime
import GroveStdlib.Std.Libraries.RandomNumbers
open Grove.Framework Widget
namespace GroveStdlib.Std
namespace Libraries
end Libraries
def libraries : Node :=
.section "libraries" "Libraries" #[
Libraries.dateAndTime,
Libraries.randomNumbers
]
end GroveStdlib.Std

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.Libraries
namespace DateAndTime
end DateAndTime
def dateAndTime : Node :=
.section "date-and-time" "Date and time" #[]
end GroveStdlib.Std.Libraries

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.Libraries
namespace RandomNumbers
end RandomNumbers
def randomNumbers : Node :=
.section "random-numbers" "Random numbers" #[]
end GroveStdlib.Std.Libraries

View File

@@ -0,0 +1,30 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
import GroveStdlib.Std.OperatingSystemAbstractions.AsynchronousIO
import GroveStdlib.Std.OperatingSystemAbstractions.BasicIO
import GroveStdlib.Std.OperatingSystemAbstractions.ConcurrencyAndParallelism
import GroveStdlib.Std.OperatingSystemAbstractions.EnvironmentFileSystemProcesses
import GroveStdlib.Std.OperatingSystemAbstractions.Locales
open Grove.Framework Widget
namespace GroveStdlib.Std
namespace OperatingSystemAbstractions
end OperatingSystemAbstractions
def operatingSystemAbstractions : Node :=
.section "operating-system-abstractions" "Operating system abstractions" #[
OperatingSystemAbstractions.asynchronousIO,
OperatingSystemAbstractions.basicIO,
OperatingSystemAbstractions.concurrencyAndParallelism,
OperatingSystemAbstractions.environmentFileSystemProcesses,
OperatingSystemAbstractions.locales
]
end GroveStdlib.Std

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.OperatingSystemAbstractions
namespace AsynchronousIO
end AsynchronousIO
def asynchronousIO : Node :=
.section "asynchronous-io" "Asynchronous I/O" #[]
end GroveStdlib.Std.OperatingSystemAbstractions

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.OperatingSystemAbstractions
namespace BasicIO
end BasicIO
def basicIO : Node :=
.section "basic-io" "Basic I/O" #[]
end GroveStdlib.Std.OperatingSystemAbstractions

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.OperatingSystemAbstractions
namespace ConcurrencyAndParallelism
end ConcurrencyAndParallelism
def concurrencyAndParallelism : Node :=
.section "concurrency-and-parallelism" "Concurrency and parallelism" #[]
end GroveStdlib.Std.OperatingSystemAbstractions

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.OperatingSystemAbstractions
namespace EnvironmentFileSystemProcesses
end EnvironmentFileSystemProcesses
def environmentFileSystemProcesses : Node :=
.section "environment-filesystem-processes" "Environment, file system, processes" #[]
end GroveStdlib.Std.OperatingSystemAbstractions

View File

@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import Grove.Framework
open Grove.Framework Widget
namespace GroveStdlib.Std.OperatingSystemAbstractions
namespace Locales
end Locales
def locales : Node :=
.section "locales" "Locales" #[]
end GroveStdlib.Std.OperatingSystemAbstractions

18
doc/std/grove/Main.lean Normal file
View File

@@ -0,0 +1,18 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
import GroveStdlib.Std
import GroveStdlib.Generated
def config : Grove.Framework.Project.Configuration where
projectNamespace := `GroveStdlib
def project : Grove.Framework.Project where
config := config
rootNode := GroveStdlib.std
restoreState := GroveStdlib.Generated.restoreState
def main (args : List String) : IO UInt32 :=
Grove.Framework.main project #[`Init, `Std, `Lean] args

3
doc/std/grove/README.md Normal file
View File

@@ -0,0 +1,3 @@
# Standard library QA
This directory contains the [Grove](github.com/TwoFX/grove) data files for the standard library.

12
doc/std/grove/grove-local.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/sh
lake exe grove-stdlib --full metadata.json
cd .lake/packages/grove/frontend
npm install
cp ../../../../metadata.json public/metadata.json
if [ -f "../../../../invalidated.json" ]; then
cp ../../../../invalidated.json public/invalidated.json
GROVE_DATA_LOCATION=public/metadata.json GROVE_UPSTREAM_INVALIDATED_FACTS_LOCATION=public/invalidated.json npm run dev
else
GROVE_DATA_LOCATION=public/metadata.json npm run dev
fi

View File

@@ -0,0 +1,25 @@
{"version": "1.1.0",
"packagesDir": ".lake/packages",
"packages":
[{"url": "https://github.com/TwoFx/grove.git",
"type": "git",
"subDir": "backend",
"scope": "",
"rev": "3e8aabdea58c11813c5d3b7eeb187ded44ee9a34",
"name": "grove",
"manifestFile": "lake-manifest.json",
"inputRev": "master",
"inherited": false,
"configFile": "lakefile.toml"},
{"url": "https://github.com/leanprover/lean4-cli",
"type": "git",
"subDir": null,
"scope": "leanprover",
"rev": "1604206fcd0462da9a241beeac0e2df471647435",
"name": "Cli",
"manifestFile": "lake-manifest.json",
"inputRev": "main",
"inherited": true,
"configFile": "lakefile.toml"}],
"name": "grovestdlib",
"lakeDir": ".lake"}

View File

@@ -0,0 +1,18 @@
name = "grovestdlib"
version = "0.1.0"
defaultTargets = ["grove-stdlib"]
[[require]]
name = "grove"
git = "https://github.com/TwoFx/grove.git"
rev = "master"
subDir = "backend"
[[lean_lib]]
name = "GroveStdlib"
root = "GroveStdlib"
[[lean_exe]]
name = "grove-stdlib"
supportInterpreter = true
root = "Main"

View File

@@ -0,0 +1 @@
lean4

View File

@@ -0,0 +1,3 @@
#!/bin/sh
lake exe grove-stdlib --invalidated invalidated.json

View File

@@ -18,14 +18,15 @@
# An old nixpkgs for creating releases with an old glibc
pkgsDist-old-aarch = import inputs.nixpkgs-old { localSystem.config = "aarch64-unknown-linux-gnu"; };
lean-packages = pkgs.callPackage (./nix/packages.nix) { src = ./.; };
llvmPackages = pkgs.llvmPackages_15;
devShellWithDist = pkgsDist: pkgs.mkShell.override {
stdenv = pkgs.overrideCC pkgs.stdenv lean-packages.llvmPackages.clang;
stdenv = pkgs.overrideCC pkgs.stdenv llvmPackages.clang;
} ({
buildInputs = with pkgs; [
cmake gmp libuv ccache pkg-config
lean-packages.llvmPackages.llvm # llvm-symbolizer for asan/lsan
llvmPackages.bintools # wrapped lld
llvmPackages.llvm # llvm-symbolizer for asan/lsan
gdb
tree # for CI
];
@@ -60,12 +61,6 @@
GDB = pkgsDist.gdb;
});
in {
packages.${system} = {
# to be removed when Nix CI is not needed anymore
inherit (lean-packages) cacheRoots test update-stage0-commit ciShell;
deprecated = lean-packages;
};
devShells.${system} = {
# The default development shell for working on lean itself
default = devShellWithDist pkgs;

View File

@@ -8,9 +8,15 @@
},
{
"path": "tests"
},
{
"path": "script"
}
],
"settings": {
// Open terminal at root, not current workspace folder
// (there is not way to directly refer to the root folder included as `.` above)
"terminal.integrated.cwd": "${workspaceFolder:src}/..",
"files.insertFinalNewline": true,
"files.trimTrailingWhitespace": true,
"cmake.buildDirectory": "${workspaceFolder}/build/release",
@@ -37,6 +43,15 @@
"isDefault": true
}
},
{
"label": "build-old",
"type": "shell",
"command": "make -C build/release -j$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || echo 4) LAKE_EXTRA_ARGS=--old",
"problemMatcher": [],
"group": {
"kind": "build"
}
},
{
"label": "test",
"type": "shell",

View File

@@ -1,7 +0,0 @@
set -eo pipefail
for pkg in $buildInputs; do
export PATH=$PATH:$pkg/bin
done
: ${outputs:=out}

View File

@@ -1,208 +0,0 @@
{ src, debug ? false, stage0debug ? false, extraCMakeFlags ? [],
stdenv, lib, cmake, pkg-config, gmp, libuv, cadical, git, gnumake, bash, buildLeanPackage, writeShellScriptBin, runCommand, symlinkJoin, lndir, perl, gnused, darwin, llvmPackages, linkFarmFromDrvs,
... } @ args:
with builtins;
lib.warn "The Nix-based build is deprecated" rec {
inherit stdenv;
sourceByRegex = p: rs: lib.sourceByRegex p (map (r: "(/src/)?${r}") rs);
buildCMake = args: stdenv.mkDerivation ({
nativeBuildInputs = [ cmake pkg-config ];
buildInputs = [ gmp libuv llvmPackages.llvm ];
# https://github.com/NixOS/nixpkgs/issues/60919
hardeningDisable = [ "all" ];
dontStrip = (args.debug or debug);
postConfigure = ''
patchShebangs .
'';
} // args // {
src = args.realSrc or (sourceByRegex args.src [ "[a-z].*" "CMakeLists\.txt" ]);
cmakeFlags = ["-DSMALL_ALLOCATOR=ON" "-DUSE_MIMALLOC=OFF"] ++ (args.cmakeFlags or [ "-DSTAGE=1" "-DPREV_STAGE=./faux-prev-stage" "-DUSE_GITHASH=OFF" "-DCADICAL=${cadical}/bin/cadical" ]) ++ (args.extraCMakeFlags or extraCMakeFlags) ++ lib.optional (args.debug or debug) [ "-DCMAKE_BUILD_TYPE=Debug" ];
preConfigure = args.preConfigure or "" + ''
# ignore absence of submodule
sed -i 's!lake/Lake.lean!!' CMakeLists.txt
'';
});
lean-bin-tools-unwrapped = buildCMake {
name = "lean-bin-tools";
outputs = [ "out" "leanc_src" ];
realSrc = sourceByRegex (src + "/src") [ "CMakeLists\.txt" "[a-z].*" ".*\.in" "Leanc\.lean" ];
dontBuild = true;
installPhase = ''
mkdir $out $leanc_src
mv bin/ include/ share/ $out/
mv leanc.sh $out/bin/leanc
mv leanc/Leanc.lean $leanc_src/
substituteInPlace $out/bin/leanc --replace '$root' "$out" --replace " sed " " ${gnused}/bin/sed "
substituteInPlace $out/bin/leanmake --replace "make" "${gnumake}/bin/make"
substituteInPlace $out/share/lean/lean.mk --replace "/usr/bin/env bash" "${bash}/bin/bash"
'';
};
leancpp = buildCMake {
name = "leancpp";
src = src + "/src";
buildFlags = [ "leancpp" "leanrt" "leanrt_initial-exec" "leanshell" "leanmain" ];
installPhase = ''
mkdir -p $out
mv lib/ $out/
mv runtime/libleanrt_initial-exec.a $out/lib
'';
};
stage0 = args.stage0 or (buildCMake {
name = "lean-stage0";
realSrc = src + "/stage0/src";
debug = stage0debug;
cmakeFlags = [ "-DSTAGE=0" ];
extraCMakeFlags = [];
preConfigure = ''
ln -s ${src + "/stage0/stdlib"} ../stdlib
'';
installPhase = ''
mkdir -p $out/bin $out/lib/lean
mv bin/lean $out/bin/
mv lib/lean/*.{so,dylib} $out/lib/lean
'';
meta.mainProgram = "lean";
});
stage = { stage, prevStage, self }:
let
desc = "stage${toString stage}";
build = args: buildLeanPackage.override {
lean = prevStage;
leanc = lean-bin-tools-unwrapped;
# use same stage for retrieving dependencies
lean-leanDeps = stage0;
lean-final = self;
} ({
src = src + "/src";
roots = [ { mod = args.name; glob = "andSubmodules"; } ];
fullSrc = src;
srcPath = "$PWD/src:$PWD/src/lake";
inherit debug;
leanFlags = [ "-DwarningAsError=true" ];
} // args);
Init' = build { name = "Init"; deps = []; };
Std' = build { name = "Std"; deps = [ Init' ]; };
Lean' = build { name = "Lean"; deps = [ Std' ]; };
attachSharedLib = sharedLib: pkg: pkg // {
inherit sharedLib;
mods = mapAttrs (_: m: m // { inherit sharedLib; propagatedLoadDynlibs = []; }) pkg.mods;
};
in (all: all // all.lean) rec {
inherit (Lean) emacs-dev emacs-package vscode-dev vscode-package;
Init = attachSharedLib leanshared Init';
Std = attachSharedLib leanshared Std' // { allExternalDeps = [ Init ]; };
Lean = attachSharedLib leanshared Lean' // { allExternalDeps = [ Std ]; };
Lake = build {
name = "Lake";
sharedLibName = "Lake_shared";
src = src + "/src/lake";
deps = [ Init Lean ];
};
Lake-Main = build {
name = "LakeMain";
roots = [{ glob = "one"; mod = "LakeMain"; }];
executableName = "lake";
deps = [ Lake ];
linkFlags = lib.optional stdenv.isLinux "-rdynamic";
src = src + "/src/lake";
};
stdlib = [ Init Std Lean Lake ];
modDepsFiles = symlinkJoin { name = "modDepsFiles"; paths = map (l: l.modDepsFile) (stdlib ++ [ Leanc ]); };
depRoots = symlinkJoin { name = "depRoots"; paths = map (l: l.depRoots) stdlib; };
iTree = symlinkJoin { name = "ileans"; paths = map (l: l.iTree) stdlib; };
Leanc = build { name = "Leanc"; src = lean-bin-tools-unwrapped.leanc_src; deps = stdlib; roots = [ "Leanc" ]; };
stdlibLinkFlags = "${lib.concatMapStringsSep " " (l: "-L${l.staticLib}") stdlib} -L${leancpp}/lib/lean";
libInit_shared = runCommand "libInit_shared" { buildInputs = [ stdenv.cc ]; libName = "libInit_shared${stdenv.hostPlatform.extensions.sharedLibrary}"; } ''
mkdir $out
touch empty.c
${stdenv.cc}/bin/cc -shared -o $out/$libName empty.c
'';
leanshared_1 = runCommand "leanshared_1" { buildInputs = [ stdenv.cc ]; libName = "leanshared_1${stdenv.hostPlatform.extensions.sharedLibrary}"; } ''
mkdir $out
touch empty.c
${stdenv.cc}/bin/cc -shared -o $out/$libName empty.c
'';
leanshared = runCommand "leanshared" { buildInputs = [ stdenv.cc ]; libName = "libleanshared${stdenv.hostPlatform.extensions.sharedLibrary}"; } ''
mkdir $out
LEAN_CC=${stdenv.cc}/bin/cc ${lean-bin-tools-unwrapped}/bin/leanc -shared ${lib.optionalString stdenv.isLinux "-Wl,-Bsymbolic"} \
-Wl,--whole-archive ${leancpp}/lib/temp/libleanshell.a -lInit -lStd -lLean -lleancpp ${leancpp}/lib/libleanrt_initial-exec.a -Wl,--no-whole-archive -lstdc++ \
-lm ${stdlibLinkFlags} \
$(${llvmPackages.libllvm.dev}/bin/llvm-config --ldflags --libs) \
-o $out/$libName
'';
mods = foldl' (mods: pkg: mods // pkg.mods) {} stdlib;
print-paths = Lean.makePrintPathsFor [] mods;
leanc = writeShellScriptBin "leanc" ''
LEAN_CC=${stdenv.cc}/bin/cc ${Leanc.executable}/bin/leanc -I${lean-bin-tools-unwrapped}/include ${stdlibLinkFlags} -L${libInit_shared} -L${leanshared_1} -L${leanshared} -L${Lake.sharedLib} "$@"
'';
lean = runCommand "lean" { buildInputs = lib.optional stdenv.isDarwin darwin.cctools; } ''
mkdir -p $out/bin
${leanc}/bin/leanc ${leancpp}/lib/temp/libleanmain.a ${libInit_shared}/* ${leanshared_1}/* ${leanshared}/* -o $out/bin/lean
'';
# derivation following the directory layout of the "basic" setup, mostly useful for running tests
lean-all = stdenv.mkDerivation {
name = "lean-${desc}";
buildCommand = ''
mkdir -p $out/bin $out/lib/lean
ln -sf ${leancpp}/lib/lean/* ${lib.concatMapStringsSep " " (l: "${l.modRoot}/* ${l.staticLib}/*") (lib.reverseList stdlib)} ${libInit_shared}/* ${leanshared_1}/* ${leanshared}/* ${Lake.sharedLib}/* $out/lib/lean/
# put everything in a single final derivation so `IO.appDir` references work
cp ${lean}/bin/lean ${leanc}/bin/leanc ${Lake-Main.executable}/bin/lake $out/bin
# NOTE: `lndir` will not override existing `bin/leanc`
${lndir}/bin/lndir -silent ${lean-bin-tools-unwrapped} $out
'';
meta.mainProgram = "lean";
};
cacheRoots = linkFarmFromDrvs "cacheRoots" ([
stage0 lean leanc lean-all iTree modDepsFiles depRoots Leanc.src
] ++ map (lib: lib.oTree) stdlib);
test = buildCMake {
name = "lean-test-${desc}";
realSrc = lib.sourceByRegex src [ "src.*" "tests.*" ];
buildInputs = [ gmp libuv perl git cadical ];
preConfigure = ''
cd src
'';
extraCMakeFlags = [ "-DLLVM=OFF" ];
postConfigure = ''
patchShebangs ../../tests ../lake
rm -r bin lib include share
ln -sf ${lean-all}/* .
'';
buildPhase = ''
ctest --output-junit test-results.xml --output-on-failure -E 'leancomptest_(doc_example|foreign)|leanlaketest_reverse-ffi|leanruntest_timeIO' -j$NIX_BUILD_CORES
'';
installPhase = ''
mkdir $out
mv test-results.xml $out
'';
};
update-stage0 =
let cTree = symlinkJoin { name = "cs"; paths = map (lib: lib.cTree) (stdlib ++ [Lake-Main]); }; in
writeShellScriptBin "update-stage0" ''
CSRCS=${cTree} CP_C_PARAMS="--dereference --no-preserve=all" ${src + "/script/lib/update-stage0"}
'';
update-stage0-commit = writeShellScriptBin "update-stage0-commit" ''
set -euo pipefail
${update-stage0}/bin/update-stage0
git commit -m "chore: update stage0"
'';
link-ilean = writeShellScriptBin "link-ilean" ''
dest=''${1:-src}
rm -rf $dest/build/lib || true
mkdir -p $dest/build/lib
ln -s ${iTree}/* $dest/build/lib
'';
benchmarks =
let
entries = attrNames (readDir (src + "/tests/bench"));
leanFiles = map (n: elemAt n 0) (filter (n: n != null) (map (match "(.*)\.lean") entries));
in lib.genAttrs leanFiles (n: (buildLeanPackage {
name = n;
src = filterSource (e: _: baseNameOf e == "${n}.lean") (src + "/tests/bench");
}).executable);
};
stage1 = stage { stage = 1; prevStage = stage0; self = stage1; };
stage2 = stage { stage = 2; prevStage = stage1; self = stage2; };
stage3 = stage { stage = 3; prevStage = stage2; self = stage3; };
}

View File

@@ -1,247 +0,0 @@
{ lean, lean-leanDeps ? lean, lean-final ? lean, leanc,
stdenv, lib, coreutils, gnused, writeShellScriptBin, bash, substituteAll, symlinkJoin, linkFarmFromDrvs,
runCommand, darwin, mkShell, ... }:
let lean-final' = lean-final; in
lib.makeOverridable (
{ name, src, fullSrc ? src, srcPrefix ? "", srcPath ? "$PWD/${srcPrefix}",
# Lean dependencies. Each entry should be an output of buildLeanPackage.
deps ? [ lean.Init lean.Std lean.Lean ],
# Static library dependencies. Each derivation `static` should contain a static library in the directory `${static}`.
staticLibDeps ? [],
# Whether to wrap static library inputs in a -Wl,--start-group [...] -Wl,--end-group to ensure dependencies are resolved.
groupStaticLibs ? false,
# Shared library dependencies included at interpretation with --load-dynlib and linked to. Each derivation `shared` should contain a
# shared library at the path `${shared}/${shared.libName or shared.name}` and a name to link to like `-l${shared.linkName or shared.name}`.
# These libs are also linked to in packages that depend on this one.
nativeSharedLibs ? [],
# Lean modules to include.
# A set of Lean modules names as strings (`"Foo.Bar"`) or attrsets (`{ name = "Foo.Bar"; glob = "one" | "submodules" | "andSubmodules"; }`);
# see Lake README for glob meanings. Dependencies of selected modules are always included.
roots ? [ name ],
# Output from `lean --deps-json` on package source files. Persist the corresponding output attribute to a file and pass it back in here to avoid IFD.
# Must be refreshed on any change in `import`s or set of source file names.
modDepsFile ? null,
# Whether to compile each module into a native shared library that is loaded whenever the module is imported in order to accelerate evaluation
precompileModules ? false,
# Whether to compile the package into a native shared library that is loaded whenever *any* of the package's modules is imported into another package.
# If `precompileModules` is also `true`, the latter only affects imports within the current package.
precompilePackage ? precompileModules,
# Lean plugin dependencies. Each derivation `plugin` should contain a plugin library at path `${plugin}/${plugin.name}`.
pluginDeps ? [],
# `overrideAttrs` for `buildMod`
overrideBuildModAttrs ? null,
debug ? false, leanFlags ? [], leancFlags ? [], linkFlags ? [], executableName ? lib.toLower name, libName ? name, sharedLibName ? libName,
srcTarget ? "..#stage0", srcArgs ? "(\${args[*]})", lean-final ? lean-final' }@args:
with builtins; let
# "Init.Core" ~> "Init/Core"
modToPath = mod: replaceStrings ["."] ["/"] mod;
modToAbsPath = mod: "${src}/${modToPath mod}";
# sanitize file name before copying to store, except when already in store
copyToStoreSafe = base: suffix: if lib.isDerivation base then base + suffix else
builtins.path { name = lib.strings.sanitizeDerivationName (baseNameOf suffix); path = base + suffix; };
modToLean = mod: copyToStoreSafe src "/${modToPath mod}.lean";
bareStdenv = ./bareStdenv;
mkBareDerivation = args: derivation (args // {
name = lib.strings.sanitizeDerivationName args.name;
stdenv = bareStdenv;
inherit (stdenv) system;
buildInputs = (args.buildInputs or []) ++ [ coreutils ];
builder = stdenv.shell;
args = [ "-c" ''
source $stdenv/setup
set -u
${args.buildCommand}
'' ];
}) // { overrideAttrs = f: mkBareDerivation (lib.fix (lib.extends f (_: args))); };
runBareCommand = name: args: buildCommand: mkBareDerivation (args // { inherit name buildCommand; });
runBareCommandLocal = name: args: buildCommand: runBareCommand name (args // {
preferLocalBuild = true;
allowSubstitutes = false;
}) buildCommand;
mkSharedLib = name: args: runBareCommand "${name}-dynlib" {
buildInputs = [ stdenv.cc ] ++ lib.optional stdenv.isDarwin darwin.cctools;
libName = "${name}${stdenv.hostPlatform.extensions.sharedLibrary}";
} ''
mkdir -p $out
${leanc}/bin/leanc -shared ${args} -o $out/$libName
'';
depRoot = name: deps: mkBareDerivation {
name = "${name}-depRoot";
inherit deps;
depRoots = map (drv: drv.LEAN_PATH) deps;
passAsFile = [ "deps" "depRoots" ];
buildCommand = ''
mkdir -p $out
for i in $(cat $depRootsPath); do
cp -dru --no-preserve=mode $i/. $out
done
for i in $(cat $depsPath); do
cp -drsu --no-preserve=mode $i/. $out
done
'';
};
srcRoot = src;
# A flattened list of Lean-module dependencies (`deps`)
allExternalDeps = lib.unique (lib.foldr (dep: allExternalDeps: allExternalDeps ++ [ dep ] ++ dep.allExternalDeps) [] deps);
allNativeSharedLibs =
lib.unique (lib.flatten (nativeSharedLibs ++ (map (dep: dep.allNativeSharedLibs or []) allExternalDeps)));
# A flattened list of all static library dependencies: this and every dep module's explicitly provided `staticLibDeps`,
# plus every dep module itself: `dep.staticLib`
allStaticLibDeps =
lib.unique (lib.flatten (staticLibDeps ++ (map (dep: [dep.staticLib] ++ dep.staticLibDeps or []) allExternalDeps)));
pathOfSharedLib = dep: dep.libPath or "${dep}/${dep.libName or dep.name}";
leanPluginFlags = lib.concatStringsSep " " (map (dep: "--plugin=${pathOfSharedLib dep}") pluginDeps);
loadDynlibsOfDeps = deps: lib.unique (concatMap (d: d.propagatedLoadDynlibs) deps);
# submodules "Init" = ["Init.List.Basic", "Init.Core", ...]
submodules = mod: let
dir = readDir (modToAbsPath mod);
f = p: t:
if t == "directory" then
submodules "${mod}.${p}"
else
let m = builtins.match "(.*)\.lean" p;
in lib.optional (m != null) "${mod}.${head m}";
in concatLists (lib.mapAttrsToList f dir);
# conservatively approximate list of source files matched by glob
expandGlobAllApprox = g:
if typeOf g == "string" then
# we can't know the required files without parsing dependencies (which is what we want this
# function for), so we approximate to the entire package.
let root = (head (split "\\." g));
in lib.optional (pathExists (src + "/${modToPath root}.lean")) root ++ lib.optionals (pathExists (modToAbsPath root)) (submodules root)
else if g.glob == "one" then expandGlobAllApprox g.mod
else if g.glob == "submodules" then submodules g.mod
else if g.glob == "andSubmodules" then [g.mod] ++ submodules g.mod
else throw "unknown glob kind '${g}'";
# list of modules that could potentially be involved in the build
candidateMods = lib.unique (concatMap expandGlobAllApprox roots);
candidateFiles = map modToLean candidateMods;
modDepsFile = args.modDepsFile or mkBareDerivation {
name = "${name}-deps.json";
candidateFiles = lib.concatStringsSep " " candidateFiles;
passAsFile = [ "candidateFiles" ];
buildCommand = ''
mkdir $out
${lean-leanDeps}/bin/lean --deps-json --stdin < $candidateFilesPath > $out/$name
'';
};
modDeps = fromJSON (
# the only possible references to store paths in the JSON should be inside errors, so no chance of missed dependencies from this
unsafeDiscardStringContext (readFile "${modDepsFile}/${modDepsFile.name}"));
# map from module name to list of imports
modDepsMap = listToAttrs (lib.zipListsWith lib.nameValuePair candidateMods modDeps.imports);
maybeOverrideAttrs = f: x: if f != null then x.overrideAttrs f else x;
# build module (.olean and .c) given derivations of all (immediate) dependencies
# TODO: make `rec` parts override-compatible?
buildMod = mod: deps: maybeOverrideAttrs overrideBuildModAttrs (mkBareDerivation rec {
name = "${mod}";
LEAN_PATH = depRoot mod deps;
LEAN_ABORT_ON_PANIC = "1";
relpath = modToPath mod;
buildInputs = [ lean ];
leanPath = relpath + ".lean";
# should be either single .lean file or directory directly containing .lean file plus dependencies
src = copyToStoreSafe srcRoot ("/" + leanPath);
outputs = [ "out" "ilean" "c" ];
oleanPath = relpath + ".olean";
ileanPath = relpath + ".ilean";
cPath = relpath + ".c";
inherit leanFlags leanPluginFlags;
leanLoadDynlibFlags = map (p: "--load-dynlib=${pathOfSharedLib p}") (loadDynlibsOfDeps deps);
buildCommand = ''
dir=$(dirname $relpath)
mkdir -p $dir $out/$dir $ilean/$dir $c/$dir
if [ -d $src ]; then cp -r $src/. .; else cp $src $leanPath; fi
lean -o $out/$oleanPath -i $out/$ileanPath -c $c/$cPath $leanPath $leanFlags $leanPluginFlags $leanLoadDynlibFlags
'';
}) // {
inherit deps;
propagatedLoadDynlibs = loadDynlibsOfDeps deps;
};
compileMod = mod: drv: mkBareDerivation {
name = "${mod}-cc";
buildInputs = [ leanc stdenv.cc ];
hardeningDisable = [ "all" ];
oPath = drv.relpath + ".o";
inherit leancFlags;
buildCommand = ''
mkdir -p $out/$(dirname ${drv.relpath})
# make local "copy" so `drv`'s Nix store path doesn't end up in ccache's hash
ln -s ${drv.c}/${drv.cPath} src.c
# on the other hand, a debug build is pretty fast anyway, so preserve the path for gdb
leanc -c -o $out/$oPath $leancFlags -fPIC ${if debug then "${drv.c}/${drv.cPath} -g" else "src.c -O3 -DNDEBUG -DLEAN_EXPORTING"}
'';
};
mkMod = mod: deps:
let drv = buildMod mod deps;
obj = compileMod mod drv;
# this attribute will only be used if any dependent module is precompiled
sharedLib = mkSharedLib mod "${obj}/${obj.oPath} ${lib.concatStringsSep " " (map (d: pathOfSharedLib d.sharedLib) deps)}";
in drv // {
inherit obj sharedLib;
} // lib.optionalAttrs precompileModules {
propagatedLoadDynlibs = [sharedLib];
};
externalModMap = lib.foldr (dep: depMap: depMap // dep.mods) {} allExternalDeps;
# map from module name to derivation
modCandidates = mapAttrs (mod: header:
let
deps = if header.errors == []
then map (m: m.module) header.result.imports
else abort "errors while parsing imports of ${mod}:\n${lib.concatStringsSep "\n" header.errors}";
in mkMod mod (map (dep: if modDepsMap ? ${dep} then modCandidates.${dep} else externalModMap.${dep}) deps)) modDepsMap;
expandGlob = g:
if typeOf g == "string" then [g]
else if g.glob == "one" then [g.mod]
else if g.glob == "submodules" then submodules g.mod
else if g.glob == "andSubmodules" then [g.mod] ++ submodules g.mod
else throw "unknown glob kind '${g}'";
# subset of `modCandidates` that is transitively reachable from `roots`
mods' = listToAttrs (map (e: { name = e.key; value = modCandidates.${e.key}; }) (genericClosure {
startSet = map (m: { key = m; }) (concatMap expandGlob roots);
operator = e: if modDepsMap ? ${e.key} then map (m: { key = m.module; }) (filter (m: modCandidates ? ${m.module}) modDepsMap.${e.key}.result.imports) else [];
}));
allLinkFlags = lib.foldr (shared: acc: acc ++ [ "-L${shared}" "-l${shared.linkName or shared.name}" ]) linkFlags allNativeSharedLibs;
objects = mapAttrs (_: m: m.obj) mods';
bintools = if stdenv.isDarwin then darwin.cctools else stdenv.cc.bintools.bintools;
staticLib = runCommand "${name}-lib" { buildInputs = [ bintools ]; } ''
mkdir -p $out
ar Trcs $out/lib${libName}.a ${lib.concatStringsSep " " (map (drv: "${drv}/${drv.oPath}") (attrValues objects))};
'';
staticLibLinkWrapper = libs: if groupStaticLibs && !stdenv.isDarwin
then "-Wl,--start-group ${libs} -Wl,--end-group"
else "${libs}";
in rec {
inherit name lean deps staticLibDeps allNativeSharedLibs allLinkFlags allExternalDeps src objects staticLib modDepsFile;
mods = mapAttrs (_: m:
m //
# if neither precompilation option was set but a dependent module wants to be precompiled, default to precompiling this package whole
lib.optionalAttrs (precompilePackage || !precompileModules) { inherit sharedLib; } //
lib.optionalAttrs precompilePackage { propagatedLoadDynlibs = [sharedLib]; })
mods';
modRoot = depRoot name (attrValues mods);
depRoots = linkFarmFromDrvs "depRoots" (map (m: m.LEAN_PATH) (attrValues mods));
cTree = symlinkJoin { name = "${name}-cTree"; paths = map (mod: mod.c) (attrValues mods); };
oTree = symlinkJoin { name = "${name}-oTree"; paths = (attrValues objects); };
iTree = symlinkJoin { name = "${name}-iTree"; paths = map (mod: mod.ilean) (attrValues mods); };
sharedLib = mkSharedLib "lib${sharedLibName}" ''
${if stdenv.isDarwin then "-Wl,-force_load,${staticLib}/lib${libName}.a" else "-Wl,--whole-archive ${staticLib}/lib${libName}.a -Wl,--no-whole-archive"} \
${lib.concatStringsSep " " (map (d: "${d.sharedLib}/*") deps)}'';
executable = lib.makeOverridable ({ withSharedStdlib ? true }: let
objPaths = map (drv: "${drv}/${drv.oPath}") (attrValues objects) ++ lib.optional withSharedStdlib "${lean-final.leanshared}/*";
in runCommand executableName { buildInputs = [ stdenv.cc leanc ]; } ''
mkdir -p $out/bin
leanc ${staticLibLinkWrapper (lib.concatStringsSep " " (objPaths ++ map (d: "${d}/*.a") allStaticLibDeps))} \
-o $out/bin/${executableName} \
${lib.concatStringsSep " " allLinkFlags}
'') {};
})

View File

@@ -1,42 +0,0 @@
#!@bash@/bin/bash
set -euo pipefail
function pebkac() {
echo 'This is just a simple Nix adapter for `lake print-paths|serve`.'
exit 1
}
[[ $# -gt 0 ]] || pebkac
case $1 in
--version)
# minimum version for `lake serve` with fallback
echo 3.1.0
;;
print-paths)
shift
deps="$@"
root=.
# fall back to initial package if not in package
[[ ! -f "$root/flake.nix" ]] && root="@srcRoot@"
target="$root#print-paths"
args=()
# HACK: use stage 0 instead of 1 inside Lean's own `src/`
[[ -d Lean && -f ../flake.nix ]] && target="@srcTarget@print-paths" && args=@srcArgs@
for dep in $deps; do
target="$target.\"$dep\""
done
echo "Building dependencies..." >&2
# -v only has "built ...", but "-vv" is a bit too verbose
exec @nix@/bin/nix run "$target" ${args[*]} -v
;;
serve)
shift
[[ ${1:-} == "--" ]] && shift
# `link-ilean` puts them there
LEAN_PATH=${LEAN_PATH:+$LEAN_PATH:}$PWD/build/lib exec $(dirname $0)/lean --server "$@"
;;
*)
pebkac
;;
esac

View File

@@ -1,28 +0,0 @@
#!@bash@/bin/bash
set -euo pipefail
root="."
# find package root
while [[ "$root" != / ]]; do
[ -f "$root/flake.nix" ] && break
root="$(realpath "$root/..")"
done
# fall back to initial package if not in package
[[ ! -f "$root/flake.nix" ]] && root="@srcRoot@"
# use Lean w/ package unless in server mode (which has its own LEAN_PATH logic)
target="$root#lean-package"
for arg in "$@"; do
case $arg in
--server | --worker | -v | --version)
target="$root#lean"
;;
esac
done
args=(-- "$@")
# HACK: use stage 0 instead of 1 inside Lean's own `src/`
[[ -d Lean && -f ../flake.nix ]] && target="@srcTarget@" && args=@srcArgs@
LEAN_SYSROOT="$(dirname "$0")/.." exec @nix@/bin/nix ${LEAN_NIX_ARGS:-} run "$target" ${args[*]}

View File

@@ -1,52 +0,0 @@
{ src, pkgs, ... } @ args:
with pkgs;
let
# https://github.com/NixOS/nixpkgs/issues/130963
llvmPackages = if stdenv.isDarwin then llvmPackages_11 else llvmPackages_15;
cc = (ccacheWrapper.override rec {
cc = llvmPackages.clang;
extraConfig = ''
export CCACHE_DIR=/nix/var/cache/ccache
export CCACHE_UMASK=007
export CCACHE_BASE_DIR=$NIX_BUILD_TOP
# https://github.com/NixOS/nixpkgs/issues/109033
args=("$@")
for ((i=0; i<"''${#args[@]}"; i++)); do
case ''${args[i]} in
-frandom-seed=*) unset args[i]; break;;
esac
done
set -- "''${args[@]}"
[ -d $CCACHE_DIR ] || exec ${cc}/bin/$(basename "$0") "$@"
'';
}).overrideAttrs (old: {
# https://github.com/NixOS/nixpkgs/issues/119779
installPhase = builtins.replaceStrings ["use_response_file_by_default=1"] ["use_response_file_by_default=0"] old.installPhase;
});
stdenv' = if stdenv.isLinux then useGoldLinker stdenv else stdenv;
lean = callPackage (import ./bootstrap.nix) (args // {
stdenv = overrideCC stdenv' cc;
inherit src buildLeanPackage llvmPackages;
});
makeOverridableLeanPackage = f:
let newF = origArgs: f origArgs // {
overrideArgs = newArgs: makeOverridableLeanPackage f (origArgs // newArgs);
};
in lib.setFunctionArgs newF (lib.getFunctionArgs f) // {
override = args: makeOverridableLeanPackage (f.override args);
};
buildLeanPackage = makeOverridableLeanPackage (callPackage (import ./buildLeanPackage.nix) (args // {
inherit (lean) stdenv;
lean = lean.stage1;
inherit (lean.stage1) leanc;
}));
in {
inherit cc buildLeanPackage llvmPackages;
nixpkgs = pkgs;
ciShell = writeShellScriptBin "ciShell" ''
set -o pipefail
export PATH=${moreutils}/bin:$PATH
# prefix lines with cumulative and individual execution time
"$@" |& ts -i "(%.S)]" | ts -s "[%M:%S"
'';
} // lean.stage1

View File

@@ -1 +0,0 @@
#eval "Hello, world!"

View File

@@ -1,21 +0,0 @@
{
description = "My Lean package";
inputs.lean.url = "github:leanprover/lean4";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, lean, flake-utils }: flake-utils.lib.eachDefaultSystem (system:
let
leanPkgs = lean.packages.${system};
pkg = leanPkgs.buildLeanPackage {
name = "MyPackage"; # must match the name of the top-level .lean file
src = ./.;
};
in {
packages = pkg // {
inherit (leanPkgs) lean;
};
defaultPackage = pkg.modRoot;
});
}

View File

@@ -0,0 +1,132 @@
/-
Copyright (c) 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
import Lean
namespace Lean.Meta.Grind.Analyzer
/-!
A simple E-matching annotation analyzer.
For each theorem annotated as an E-matching candidate, it creates an artificial goal, executes `grind` and shows the
number of instances created.
For a theorem of the form `params -> type`, the artificial goal is of the form `params -> type -> False`.
-/
/--
`grind` configuration for the analyzer. We disable case-splits and lookahead,
increase the number of generations, and limit the number of instances generated.
-/
def config : Grind.Config := {
splits := 0
lookahead := false
mbtc := false
ematch := 20
instances := 100
gen := 10
}
structure Config where
/-- Minimum number of instantiations to trigger summary report -/
min : Nat := 10
/-- Minimum number of instantiations to trigger detailed report -/
detailed : Nat := 50
def mkParams : MetaM Params := do
let params Grind.mkParams config
let ematch getEMatchTheorems
let casesTypes Grind.getCasesTypes
return { params with ematch, casesTypes }
/-- Returns the total number of generated instances. -/
private def sum (cs : PHashMap Origin Nat) : Nat := Id.run do
let mut r := 0
for (_, c) in cs do
r := r + c
return r
private def thmsToMessageData (thms : PHashMap Origin Nat) : MetaM MessageData := do
let data := thms.toArray.filterMap fun (origin, c) =>
match origin with
| .decl declName => some (declName, c)
| _ => none
let data := data.qsort fun (d₁, c₁) (d₂, c₂) => if c₁ == c₂ then Name.lt d₁ d₂ else c₁ > c₂
let data data.mapM fun (declName, counter) =>
return .trace { cls := `thm } m!"{.ofConst (← mkConstWithLevelParams declName)} ↦ {counter}" #[]
return .trace { cls := `thm } "instances" data
/--
Analyzes theorem `declName`. That is, creates the artificial goal based on `declName` type,
and invokes `grind` on it.
-/
def analyzeEMatchTheorem (declName : Name) (c : Config) : MetaM Unit := do
let info getConstInfo declName
let mvarId forallTelescope info.type fun _ type => do
withLocalDeclD `h type fun _ => do
return ( mkFreshExprMVar (mkConst ``False)).mvarId!
let result Grind.main mvarId ( mkParams) (pure ())
let thms := result.counters.thm
let s := sum thms
if s > c.min then
IO.println s!"{declName} : {s}"
if s > c.detailed then
logInfo m!"{declName}\n{← thmsToMessageData thms}"
-- Not sure why this is failing: `down_pure` perhaps has an unnecessary universe parameter?
run_meta analyzeEMatchTheorem ``Std.Do.SPred.down_pure {}
/-- Analyzes all theorems in the standard library marked as E-matching theorems. -/
def analyzeEMatchTheorems (c : Config := {}) : MetaM Unit := do
let origins := ( getEMatchTheorems).getOrigins
let decls := origins.filterMap fun | .decl declName => some declName | _ => none
for declName in decls.mergeSort Name.lt do
try
analyzeEMatchTheorem declName c
catch e =>
logError m!"{declName} failed with {e.toMessageData}"
logInfo m!"Finished analyzing {decls.length} theorems"
/-- Macro for analyzing E-match theorems with unlimited heartbeats -/
macro "#analyzeEMatchTheorems" : command => `(
set_option maxHeartbeats 0 in
run_meta analyzeEMatchTheorems
)
#analyzeEMatchTheorems
-- -- We can analyze specific theorems using commands such as
set_option trace.grind.ematch.instance true
-- 1. grind immediately sees `(#[] : Array α) = ([] : List α).toArray` but probably this should be hidden.
-- 2. `Vector.toArray_empty` keys on `Array.mk []` rather than `#v[].toArray`
-- I guess we could add `(#[].extract _ _).extract _ _` as a stop pattern.
run_meta analyzeEMatchTheorem ``Array.extract_empty {}
-- Neither `Option.bind_some` nor `Option.bind_fun_some` fire, because the terms appear inside
-- lambdas. So we get crazy things like:
-- `fun x => ((some x).bind some).bind fun x => (some x).bind fun x => (some x).bind some`
-- We could consider replacing `filterMap_some` with
-- `filterMap g (filterMap f xs) = filterMap (f >=> g) xs`
-- to avoid the lambda that `grind` struggles with, but this would require more API around the fish.
run_meta analyzeEMatchTheorem ``Array.filterMap_some {}
-- Not entirely certain what is wrong here, but certainly
-- `eq_empty_of_append_eq_empty` is firing too often.
-- Ideally we could instantiate this is we fine `xs ++ ys` in the same equivalence class,
-- note just as soon as we see `xs ++ ys`.
-- I've tried removing this in https://github.com/leanprover/lean4/pull/10162
run_meta analyzeEMatchTheorem ``Array.range'_succ {}
-- Perhaps the same story here.
run_meta analyzeEMatchTheorem ``Array.range_succ {}
-- `zip_map_left` and `zip_map_right` are bad grind lemmas,
-- checking if they can be removed in https://github.com/leanprover/lean4/pull/10163
run_meta analyzeEMatchTheorem ``Array.zip_map {}
-- It seems crazy to me that as soon as we have `0 >>> n = 0`, we instantiate based on the
-- pattern `0 >>> n >>> m` by substituting `0` into `0 >>> n` to produce the `0 >>> n >>> n`.
-- I don't think any forbidden subterms can help us here. I don't know what to do. :-(
run_meta analyzeEMatchTheorem ``Int.zero_shiftRight {}

75
script/Modulize.lean Normal file
View File

@@ -0,0 +1,75 @@
import Lake.CLI.Main
/-!
Usage: `lean --run script/Modulize.lean [--meta] file1.lean file2.lean ...`
A simple script that inserts `module` and `public section` into un-modulized files and
bumps their imports to `public`.
When `--meta` is passed, `public meta section` and `public meta import` is used instead.
-/
open Lean Parser.Module
def main (args : List String) : IO Unit := do
let mut args := args
let mut doMeta := false
while !args.isEmpty && args[0]!.startsWith "-" do
match args[0]! with
| "--meta" => doMeta := true
| arg => throw <| .userError s!"unknown flag '{arg}'"
args := args.tail
for path in args do
-- Parse the input file
let mut text IO.FS.readFile path
let inputCtx := Parser.mkInputContext text path
let (header, parserState, msgs) Parser.parseHeader inputCtx
if !msgs.toList.isEmpty then -- skip this file if there are parse errors
msgs.forM fun msg => msg.toString >>= IO.println
throw <| .userError "parse errors in file"
let `(header| $[module%$moduleTk?]? $imps:import*) := header
| throw <| .userError s!"unexpected header syntax of {path}"
if moduleTk?.isSome then
continue
-- initial whitespace if empty header
let startPos := header.raw.getPos? |>.getD parserState.pos
let dummyEnv mkEmptyEnvironment
let (initCmd, parserState', _) :=
Parser.parseCommand inputCtx { env := dummyEnv, options := {} } parserState msgs
-- insert section if any trailing command
if !initCmd.isOfKind ``Parser.Command.eoi then
let insertPos? :=
-- put below initial module docstring if any
guard (initCmd.isOfKind ``Parser.Command.moduleDoc) *> initCmd.getTailPos? <|>
-- else below header
header.raw.getTailPos?
let insertPos := insertPos?.getD startPos -- empty header
let mut sec := if doMeta then
"public meta section"
else
"@[expose] public section"
if !imps.isEmpty then
sec := "\n\n" ++ sec
if insertPos?.isNone then
sec := sec ++ "\n\n"
text := text.extract 0 insertPos ++ sec ++ text.extract insertPos text.rawEndPos
-- prepend each import with `public `
for imp in imps.reverse do
let insertPos := imp.raw.getPos?.get!
let prfx := if doMeta then "public meta " else "public "
text := text.extract 0 insertPos ++ prfx ++ text.extract insertPos text.rawEndPos
-- insert `module` header
let mut initText := text.extract 0 startPos
if !initText.trim.isEmpty then
-- If there is a header comment, preserve it and put `module` in the line after
initText := initText.trimRight ++ "\n"
text := initText ++ "module\n\n" ++ text.extract startPos text.rawEndPos
IO.FS.writeFile path text

616
script/Shake.lean Normal file
View File

@@ -0,0 +1,616 @@
/-
Copyright (c) 2023 Mario Carneiro. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro, Sebastian Ullrich
-/
import Lake.CLI.Main
import Lean.ExtraModUses
/-! # `lake exe shake` command
This command will check the current project (or a specified target module) and all dependencies for
unused imports. This works by looking at generated `.olean` files to deduce required imports and
ensuring that every import is used to contribute some constant or other elaboration dependency
recorded by `recordExtraModUse`. Because recompilation is not needed this is quite fast (about 8
seconds to check `Mathlib` and all dependencies).
-/
/-- help string for the command line interface -/
def help : String := "Lean project tree shaking tool
Usage: lake exe shake [OPTIONS] <MODULE>..
Arguments:
<MODULE>
A module path like `Mathlib`. All files transitively reachable from the
provided module(s) will be checked.
Options:
--force
Skips the `lake build --no-build` sanity check
--fix
Apply the suggested fixes directly. Make sure you have a clean checkout
before running this, so you can review the changes.
"
open Lean
/-- We use `Nat` as a bitset for doing efficient set operations.
The bit indexes will usually be a module index. -/
structure Bitset where
toNat : Nat
deriving Inhabited, DecidableEq, Repr
namespace Bitset
instance : EmptyCollection Bitset where
emptyCollection := { toNat := 0 }
instance : Insert Nat Bitset where
insert i s := { toNat := s.toNat ||| (1 <<< i) }
instance : Singleton Nat Bitset where
singleton i := insert i
instance : Inter Bitset where
inter a b := { toNat := a.toNat &&& b.toNat }
instance : Union Bitset where
union a b := { toNat := a.toNat ||| b.toNat }
instance : XorOp Bitset where
xor a b := { toNat := a.toNat ^^^ b.toNat }
def has (s : Bitset) (i : Nat) : Bool := s {i}
end Bitset
/-- The kind of a module dependency, corresponding to the homonymous `ExtraModUse` fields. -/
structure NeedsKind where
isExported : Bool
isMeta : Bool
deriving Inhabited, BEq, Repr, Hashable
namespace NeedsKind
@[match_pattern] abbrev priv : NeedsKind := { isExported := false, isMeta := false }
@[match_pattern] abbrev pub : NeedsKind := { isExported := true, isMeta := false }
@[match_pattern] abbrev metaPriv : NeedsKind := { isExported := false, isMeta := true }
@[match_pattern] abbrev metaPub : NeedsKind := { isExported := true, isMeta := true }
def all : Array NeedsKind := #[pub, priv, metaPub, metaPriv]
def ofImport : Lean.Import NeedsKind
| { isExported := true, isMeta := true, .. } => .metaPub
| { isExported := true, isMeta := false, .. } => .pub
| { isExported := false, isMeta := true, .. } => .metaPriv
| { isExported := false, isMeta := false, .. } => .priv
end NeedsKind
/-- Logically, a map `NeedsKind → Bitset`. -/
structure Needs where
pub : Bitset
priv : Bitset
metaPub : Bitset
metaPriv : Bitset
deriving Inhabited, Repr
def Needs.empty : Needs := default
def Needs.get (needs : Needs) (k : NeedsKind) : Bitset :=
match k with
| .pub => needs.pub
| .priv => needs.priv
| .metaPub => needs.metaPub
| .metaPriv => needs.metaPriv
def Needs.has (needs : Needs) (k : NeedsKind) (i : ModuleIdx) : Bool :=
needs.get k |>.has i
def Needs.set (needs : Needs) (k : NeedsKind) (s : Bitset) : Needs :=
match k with
| .pub => { needs with pub := s }
| .priv => { needs with priv := s }
| .metaPub => { needs with metaPub := s }
| .metaPriv => { needs with metaPriv := s }
def Needs.modify (needs : Needs) (k : NeedsKind) (f : Bitset Bitset) : Needs :=
needs.set k (f (needs.get k))
def Needs.union (needs : Needs) (k : NeedsKind) (s : Bitset) : Needs :=
needs.modify k (· s)
def Needs.sub (needs : Needs) (k : NeedsKind) (s : Bitset) : Needs :=
needs.modify k (fun s' => s' ^^^ (s' s))
/-- The main state of the checker, containing information on all loaded modules. -/
structure State where
env : Environment
/--
`transDeps[i]` is the (non-reflexive) transitive closure of `mods[i].imports`. More specifically,
* `j ∈ transDeps[i].pub` if `i -(public import)->+ j`
* `j ∈ transDeps[i].priv` if `i -(import ...)-> _ -(public import)->* j`
* `j ∈ transDeps[i].priv` if `i -(import all)->+ i'` and `j ∈ transDeps[i'].pub/priv`
* `j ∈ transDeps[i].metaPub` if `i -(public (meta)? import)->* _ -(public meta import)-> _ -(public (meta)? import)->* j`
* `j ∈ transDeps[i].metaPriv` if `i -(meta import ...)-> _ -(public (meta)? import)->* j`
* `j ∈ transDeps[i].metaPriv` if `i -(import ...)-> i'` and `j ∈ transDeps[i'].metaPub`
* `j ∈ transDeps[i].metaPriv` if `i -(import all)->+ i'` and `j ∈ transDeps[i'].metaPub/metaPriv`
-/
transDeps : Array Needs := #[]
/--
`transDepsOrig` is the initial value of `transDeps` before changes potentially resulting from
changes to upstream headers.
-/
transDepsOrig : Array Needs := #[]
def State.mods (s : State) := s.env.header.moduleData
def State.modNames (s : State) := s.env.header.moduleNames
/--
Given module `j`'s transitive dependencies, computes the union of `transImps` and the transitive
dependencies resulting from importing the module via `imp` according to the rules of
`State.transDeps`.
-/
def addTransitiveImps (transImps : Needs) (imp : Import) (j : Nat) (impTransImps : Needs) : Needs := Id.run do
let mut transImps := transImps
-- `j ∈ transDeps[i].pub` if `i -(public import)->+ j`
if imp.isExported && !imp.isMeta then
transImps := transImps.union .pub {j} |>.union .pub (impTransImps.get .pub)
if !imp.isExported && !imp.isMeta then
-- `j ∈ transDeps[i].priv` if `i -(import ...)-> _ -(public import)->* j`
transImps := transImps.union .priv {j} |>.union .priv (impTransImps.get .pub)
if imp.importAll then
-- `j ∈ transDeps[i].priv` if `i -(import all)->+ i'` and `j ∈ transDeps[i'].pub/priv`
transImps := transImps.union .priv (impTransImps.get .pub impTransImps.get .priv)
-- `j ∈ transDeps[i].metaPub` if `i -(public (meta)? import)->* _ -(public meta import)-> _ -(public (meta)? import)->* j`
if imp.isExported then
transImps := transImps.union .metaPub (impTransImps.get .metaPub)
if imp.isMeta then
transImps := transImps.union .metaPub {j} |>.union .metaPub (impTransImps.get .pub impTransImps.get .metaPub)
if !imp.isExported then
if imp.isMeta then
-- `j ∈ transDeps[i].metaPriv` if `i -(meta import ...)-> _ -(public (meta)? import)->* j`
transImps := transImps.union .metaPriv {j} |>.union .metaPriv (impTransImps.get .pub impTransImps.get .metaPub)
if imp.importAll then
-- `j ∈ transDeps[i].metaPriv` if `i -(import all)->+ i'` and `j ∈ transDeps[i'].metaPub/metaPriv`
transImps := transImps.union .metaPriv (impTransImps.get .metaPub impTransImps.get .metaPriv)
else
-- `j ∈ transDeps[i].metaPriv` if `i -(import ...)-> i'` and `j ∈ transDeps[i'].metaPub`
transImps := transImps.union .metaPriv (impTransImps.get .metaPub)
transImps
/-- Calculates the needs for a given module `mod` from constants and recorded extra uses. -/
def calcNeeds (env : Environment) (i : ModuleIdx) : Needs := Id.run do
let mut needs := default
for ci in env.header.moduleData[i]!.constants do
-- Added guard for cases like `structure` that are still exported even if private
let pubCI? := guard (!isPrivateName ci.name) *> (env.setExporting true).find? ci.name
let k := { isExported := pubCI?.isSome, isMeta := isMeta env ci.name }
needs := visitExpr k ci.type needs
if let some e := ci.value? (allowOpaque := true) then
-- type and value has identical visibility under `meta`
let k := if k.isMeta then k else
if pubCI?.any (·.hasValue (allowOpaque := true)) then .pub else .priv
needs := visitExpr k e needs
for use in getExtraModUses env i do
let j := env.getModuleIdx? use.module |>.get!
needs := needs.union { use with } {j}
return needs
where
/-- Accumulate the results from expression `e` into `deps`. -/
visitExpr (k : NeedsKind) e deps :=
Lean.Expr.foldConsts e deps fun c deps => match env.getModuleIdxFor? c with
| some j =>
let k := { k with isMeta := k.isMeta && !isMeta env c }
if j != i then deps.union k {j} else deps
| _ => deps
/--
Calculates the same as `calcNeeds` but tracing each module to a use-def declaration pair or
`none` if merely a recorded extra use.
-/
def getExplanations (env : Environment) (i : ModuleIdx) :
Std.HashMap (ModuleIdx × NeedsKind) (Option (Name × Name)) := Id.run do
let mut deps := default
for ci in env.header.moduleData[i]!.constants do
-- Added guard for cases like `structure` that are still exported even if private
let pubCI? := guard (!isPrivateName ci.name) *> (env.setExporting true).find? ci.name
let k := { isExported := pubCI?.isSome, isMeta := isMeta env ci.name }
deps := visitExpr k ci.name ci.type deps
if let some e := ci.value? (allowOpaque := true) then
let k := if k.isMeta then k else
if pubCI?.any (·.hasValue (allowOpaque := true)) then .pub else .priv
deps := visitExpr k ci.name e deps
for use in getExtraModUses env i do
let j := env.getModuleIdx? use.module |>.get!
if !deps.contains (j, { use with }) then
deps := deps.insert (j, { use with }) none
return deps
where
/-- Accumulate the results from expression `e` into `deps`. -/
visitExpr (k : NeedsKind) name e deps :=
Lean.Expr.foldConsts e deps fun c deps => match env.getModuleIdxFor? c with
| some i =>
let k := { k with isMeta := k.isMeta && !isMeta env c }
if
if let some (some (name', _)) := deps[(i, k)]? then
decide (name.toString.length < name'.toString.length)
else true
then
deps.insert (i, k) (name, c)
else
deps
| _ => deps
partial def initStateFromEnv (env : Environment) : State := Id.run do
let mut s := { env }
for i in 0...env.header.moduleData.size do
let mod := env.header.moduleData[i]!
let mut imps := #[]
let mut transImps := Needs.empty
for imp in mod.imports do
let j := env.getModuleIdx? imp.module |>.get!
imps := imps.push j
transImps := addTransitiveImps transImps imp j s.transDeps[j]!
s := { s with transDeps := s.transDeps.push transImps }
s := { s with transDepsOrig := s.transDeps }
return s
/-- The list of edits that will be applied in `--fix`. `edits[i] = (removed, added)` where:
* If `j ∈ removed` then we want to delete module named `j` from the imports of `i`
* If `j ∈ added` then we want to add module index `j` to the imports of `i`.
-/
abbrev Edits := Std.HashMap Name (Array Import × Array Import)
/-- Register that we want to remove `tgt` from the imports of `src`. -/
def Edits.remove (ed : Edits) (src : Name) (tgt : Import) : Edits :=
match ed.get? src with
| none => ed.insert src (#[tgt], #[])
| some (a, b) => ed.insert src (a.push tgt, b)
/-- Register that we want to add `tgt` to the imports of `src`. -/
def Edits.add (ed : Edits) (src : Name) (tgt : Import) : Edits :=
match ed.get? src with
| none => ed.insert src (#[], #[tgt])
| some (a, b) => ed.insert src (a, b.push tgt)
/-- Parse a source file to extract the location of the import lines, for edits and error messages.
Returns `(path, inputCtx, imports, endPos)` where `imports` is the `Lean.Parser.Module.import` list
and `endPos` is the position of the end of the header.
-/
def parseHeaderFromString (text path : String) :
IO (System.FilePath × Parser.InputContext ×
TSyntax ``Parser.Module.header × String.Pos.Raw) := do
let inputCtx := Parser.mkInputContext text path
let (header, parserState, msgs) Parser.parseHeader inputCtx
if !msgs.toList.isEmpty then -- skip this file if there are parse errors
msgs.forM fun msg => msg.toString >>= IO.println
throw <| .userError "parse errors in file"
-- the insertion point for `add` is the first newline after the imports
let insertion := header.raw.getTailPos?.getD parserState.pos
let insertion := text.findAux (· == '\n') text.endPos insertion + '\n'
pure (path, inputCtx, header, insertion)
/-- Parse a source file to extract the location of the import lines, for edits and error messages.
Returns `(path, inputCtx, imports, endPos)` where `imports` is the `Lean.Parser.Module.import` list
and `endPos` is the position of the end of the header.
-/
def parseHeader (srcSearchPath : SearchPath) (mod : Name) :
IO (System.FilePath × Parser.InputContext ×
TSyntax ``Parser.Module.header × String.Pos.Raw) := do
-- Parse the input file
let some path srcSearchPath.findModuleWithExt "lean" mod
| throw <| .userError s!"error: failed to find source file for {mod}"
let text IO.FS.readFile path
parseHeaderFromString text path.toString
def decodeHeader : TSyntax ``Parser.Module.header Option (TSyntax `module) × Option (TSyntax `prelude) × TSyntaxArray ``Parser.Module.import
| `(Parser.Module.header| $[module%$moduleTk?]? $[prelude%$preludeTk?]? $imports*) =>
(moduleTk?.map .mk, preludeTk?.map .mk, imports)
| _ => unreachable!
def decodeImport : TSyntax ``Parser.Module.import Import
| `(Parser.Module.import| $[public%$pubTk?]? $[meta%$metaTk?]? import $[all%$allTk?]? $id) =>
{ module := id.getId, isExported := pubTk?.isSome, isMeta := metaTk?.isSome, importAll := allTk?.isSome }
| stx => panic! s!"unexpected syntax {stx}"
/-- Analyze and report issues from module `i`. Arguments:
* `srcSearchPath`: Used to find the path for error reporting purposes
* `i`: the module index
* `needs`: the module's calculated needs
* `pinned`: dependencies that should be preserved even if unused
* `edits`: accumulates the list of edits to apply if `--fix` is true
* `addOnly`: if true, only add missing imports, do not remove unused ones
-/
def visitModule (srcSearchPath : SearchPath)
(i : Nat) (needs : Needs) (preserve : Needs) (edits : Edits) (headerStx : TSyntax ``Parser.Module.header)
(addOnly := false) (githubStyle := false) (explain := false) : StateT State IO Edits := do
let s get
-- Do transitive reduction of `needs` in `deps`.
let mut deps := needs
let (_, prelude?, imports) := decodeHeader headerStx
if prelude?.isNone then
deps := deps.union .pub {s.env.getModuleIdx? `Init |>.get!}
for imp in imports do
if addOnly || imp.raw.getTrailing?.any (·.toString.toSlice.contains "shake: keep") then
let imp := decodeImport imp
let j := s.env.getModuleIdx? imp.module |>.get!
let k := NeedsKind.ofImport imp
deps := deps.union k {j}
for j in [0:s.mods.size] do
let transDeps := s.transDeps[j]!
for k in NeedsKind.all do
if s.transDepsOrig[i]!.has k j && preserve.has k j then
deps := deps.union k {j}
if deps.has k j then
let transDeps := addTransitiveImps .empty { k with module := .anonymous } j transDeps
for k' in NeedsKind.all do
deps := deps.sub k' (transDeps.sub k' {j} |>.get k')
-- Any import which is not in `transDeps` was unused.
-- Also accumulate `newDeps` which is the transitive closure of the remaining imports
let mut toRemove : Array Import := #[]
let mut newDeps := Needs.empty
for imp in s.mods[i]!.imports do
let j := s.env.getModuleIdx? imp.module |>.get!
if
-- skip folder-nested imports
s.modNames[i]!.isPrefixOf imp.module ||
imp.importAll then
newDeps := addTransitiveImps newDeps imp j s.transDeps[j]!
else
let k := NeedsKind.ofImport imp
-- A private import should also be removed if the public version is needed
if !deps.has k j || !k.isExported && deps.has { k with isExported := true } j then
toRemove := toRemove.push imp
else
newDeps := addTransitiveImps newDeps imp j s.transDeps[j]!
-- If `newDeps` does not cover `deps`, then we have to add back some imports until it does.
-- To minimize new imports we pick only new imports which are not transitively implied by
-- another new import
let mut toAdd : Array Import := #[]
for j in [0:s.mods.size] do
for k in NeedsKind.all do
if deps.has k j && !newDeps.has k j && !newDeps.has { k with isExported := true } j then
let imp := { k with module := s.modNames[j]! }
toAdd := toAdd.push imp
newDeps := addTransitiveImps newDeps imp j s.transDeps[j]!
-- mark and report the removals
let mut edits := toRemove.foldl (init := edits) fun edits imp =>
edits.remove s.modNames[i]! imp
if !toAdd.isEmpty || !toRemove.isEmpty || explain then
if let some path srcSearchPath.findModuleWithExt "lean" s.modNames[i]! then
println! "{path}:"
else
println! "{s.modNames[i]!}:"
if !toRemove.isEmpty then
println! " remove {toRemove}"
if githubStyle then
try
let (path, inputCtx, stx, endHeader) parseHeader srcSearchPath s.modNames[i]!
let (_, _, imports) := decodeHeader stx
for stx in imports do
if toRemove.any fun imp => imp == decodeImport stx then
let pos := inputCtx.fileMap.toPosition stx.raw.getPos?.get!
println! "{path}:{pos.line}:{pos.column+1}: warning: unused import \
(use `lake exe shake --fix` to fix this, or `lake exe shake --update` to ignore)"
if !toAdd.isEmpty then
-- we put the insert message on the beginning of the last import line
let pos := inputCtx.fileMap.toPosition endHeader
println! "{path}:{pos.line-1}:1: warning: \
add {toAdd} instead"
catch _ => pure ()
-- mark and report the additions
edits := toAdd.foldl (init := edits) fun edits imp =>
edits.add s.modNames[i]! imp
if !toAdd.isEmpty then
println! " add {toAdd}"
-- recalculate transitive dependencies of downstream modules
let mut newTransDepsI := Needs.empty
for imp in s.mods[i]!.imports do
if !toRemove.contains imp then
let j := s.env.getModuleIdx? imp.module |>.get!
newTransDepsI := addTransitiveImps newTransDepsI imp j s.transDeps[j]!
for imp in toAdd do
let j := s.env.getModuleIdx? imp.module |>.get!
newTransDepsI := addTransitiveImps newTransDepsI imp j s.transDeps[j]!
set { s with transDeps := s.transDeps.set! i newTransDepsI }
if explain then
let explanation := getExplanations s.env i
let sanitize n := if n.hasMacroScopes then (sanitizeName n).run' { options := {} } else n
let run (imp : Import) := do
let j := s.env.getModuleIdx? imp.module |>.get!
if let some exp? := explanation[(j, NeedsKind.ofImport imp)]? then
println! " note: `{imp}` required"
if let some (n, c) := exp? then
println! " because `{sanitize n}` refers to `{sanitize c}`"
else
println! " because of additional compile-time dependencies"
for j in s.mods[i]!.imports do
if !toRemove.contains j then
run j
for i in toAdd do run i
return edits
/-- Convert a list of module names to a bitset of module indexes -/
def toBitset (s : State) (ns : List Name) : Bitset :=
ns.foldl (init := ) fun c name =>
match s.env.getModuleIdxFor? name with
| some i => c {i}
| none => c
/-- The parsed CLI arguments. See `help` for more information -/
structure Args where
/-- `--help`: shows the help -/
help : Bool := false
/-- `--force`: skips the `lake build --no-build` sanity check -/
force : Bool := false
/-- `--gh-style`: output messages that can be parsed by `gh-problem-matcher-wrap` -/
githubStyle : Bool := false
/-- `--explain`: give constants explaining why each module is needed -/
explain : Bool := false
/-- `--fix`: apply the fixes directly -/
fix : Bool := false
/-- `<MODULE>..`: the list of root modules to check -/
mods : Array Name := #[]
local instance : Ord Import where
compare a b :=
if a.isExported && !b.isExported then
Ordering.lt
else if !a.isExported && b.isExported then
Ordering.gt
else
a.module.cmp b.module
/-- The main entry point. See `help` for more information on arguments. -/
def main (args : List String) : IO UInt32 := do
initSearchPath ( findSysroot)
-- Parse the arguments
let rec parseArgs (args : Args) : List String Args
| [] => args
| "--help" :: rest => parseArgs { args with help := true } rest
| "--force" :: rest => parseArgs { args with force := true } rest
| "--fix" :: rest => parseArgs { args with fix := true } rest
| "--explain" :: rest => parseArgs { args with explain := true } rest
| "--gh-style" :: rest => parseArgs { args with githubStyle := true } rest
| "--" :: rest => { args with mods := args.mods ++ rest.map (·.toName) }
| other :: rest => parseArgs { args with mods := args.mods.push other.toName } rest
let args := parseArgs {} args
-- Bail if `--help` is passed
if args.help then
IO.println help
IO.Process.exit 0
if !args.force then
if ( IO.Process.output { cmd := "lake", args := #["build", "--no-build"] }).exitCode != 0 then
IO.println "There are out of date oleans. Run `lake build` or `lake exe cache get` first"
IO.Process.exit 1
-- Determine default module(s) to run shake on
let defaultTargetModules : Array Name try
let (elanInstall?, leanInstall?, lakeInstall?) Lake.findInstall?
let config Lake.MonadError.runEIO <| Lake.mkLoadConfig { elanInstall?, leanInstall?, lakeInstall? }
let some workspace Lake.loadWorkspace config |>.toBaseIO
| throw <| IO.userError "failed to load Lake workspace"
let defaultTargetModules := workspace.root.defaultTargets.flatMap fun target =>
if let some lib := workspace.root.findLeanLib? target then
lib.roots
else if let some exe := workspace.root.findLeanExe? target then
#[exe.config.root]
else
#[]
pure defaultTargetModules
catch _ =>
pure #[]
let srcSearchPath getSrcSearchPath
-- the list of root modules
let mods := if args.mods.isEmpty then defaultTargetModules else args.mods
-- Only submodules of `pkg` will be edited or have info reported on them
let pkg := mods[0]!.components.head!
-- Load all the modules
let imps := mods.map ({ module := · })
let (_, s) importModulesCore imps (isExported := true) |>.run
let s := s.markAllExported
let env finalizeImport s (isModule := true) imps {} (leakEnv := false) (loadExts := false)
StateT.run' (s := initStateFromEnv env) do
let s get
-- Parse the config file
-- Run the calculation of the `needs` array in parallel
let needs := s.mods.mapIdx fun i _ =>
Task.spawn fun _ => calcNeeds s.env i
-- Parse headers in parallel
let headers s.mods.mapIdxM fun i _ =>
BaseIO.asTask (parseHeader srcSearchPath s.modNames[i]! |>.toBaseIO)
if args.fix then
println! "The following changes will be made automatically:"
-- Check all selected modules
let mut edits : Edits :=
let mut revNeeds : Needs := default
for i in [0:s.mods.size], t in needs, header in headers do
match header.get with
| .ok (_, _, stx, _) =>
edits visitModule (addOnly := !pkg.isPrefixOf s.modNames[i]!)
srcSearchPath i t.get revNeeds edits stx args.githubStyle args.explain
if isExtraRevModUse s.env i then
revNeeds := revNeeds.union .priv {i}
| .error e =>
println! e.toString
if !args.fix then
-- return error if any issues were found
return if edits.isEmpty then 0 else 1
-- Apply the edits to existing files
let mut count := 0
for mod in s.modNames, header? in headers do
let some (remove, add) := edits[mod]? | continue
let add : Array Import := add.qsortOrd
-- Parse the input file
let .ok (path, inputCtx, stx, insertion) := header?.get | continue
let (_, _, imports) := decodeHeader stx
let text := inputCtx.fileMap.source
-- Calculate the edit result
let mut pos : String.Pos.Raw := 0
let mut out : String := ""
let mut seen : Std.HashSet Import := {}
for stx in imports do
let mod := decodeImport stx
if remove.contains mod || seen.contains mod then
out := out ++ text.extract pos stx.raw.getPos?.get!
-- We use the end position of the syntax, but include whitespace up to the first newline
pos := text.findAux (· == '\n') text.rawEndPos stx.raw.getTailPos?.get! + '\n'
seen := seen.insert mod
out := out ++ text.extract pos insertion
for mod in add do
if !seen.contains mod then
seen := seen.insert mod
out := out ++ s!"{mod}\n"
out := out ++ text.extract insertion text.rawEndPos
IO.FS.writeFile path out
count := count + 1
-- Since we throw an error upon encountering issues, we can be sure that everything worked
-- if we reach this point of the script.
if count > 0 then
println! "Successfully applied {count} suggestions."
else
println! "No edits required."
return 0

View File

@@ -1,9 +1,96 @@
#!/usr/bin/env bash
set -euo pipefail
set -euxo pipefail
# We benchmark against stage 2 to test new optimizations.
timeout -s KILL 1h time bash -c 'mkdir -p build/release; cd build/release; cmake ../.. && make -j$(nproc) stage2' 1>&2
cmake --preset release 1>&2
# We benchmark against stage2/bin to test new optimizations.
timeout -s KILL 1h time make -C build/release -j$(nproc) stage3 1>&2
export PATH=$PWD/build/release/stage2/bin:$PATH
# The extra opts used to be passed to the Makefile during benchmarking only but with Lake it is
# easier to configure them statically.
cmake -B build/release/stage3 -S src -DLEAN_EXTRA_LAKEFILE_TOML='weakLeanArgs=["-Dprofiler=true", "-Dprofiler.threshold=9999999", "--stats"]' 1>&2
(
cd tests/bench
timeout -s KILL 1h time temci exec --config speedcenter.yaml --in speedcenter.exec.velcom.yaml 1>&2
temci report run_output.yaml --reporter codespeed2
)
if [ -d .git ]; then
DIR="$(git rev-parse @)"
BASE_URL="https://speed.lean-lang.org/lean4-out/$DIR"
{
cat <<'EOF'
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Lakeprof Report</title>
</head>
<h1>Lakeprof Report</h1>
<button type="button" id="btn_fetch">View build trace in Perfetto</button>
<script type="text/javascript">
const ORIGIN = 'https://ui.perfetto.dev';
const btnFetch = document.getElementById('btn_fetch');
async function fetchAndOpen(traceUrl) {
const resp = await fetch(traceUrl);
// Error checking is left as an exercise to the reader.
const blob = await resp.blob();
const arrayBuffer = await blob.arrayBuffer();
openTrace(arrayBuffer, traceUrl);
}
function openTrace(arrayBuffer, traceUrl) {
const win = window.open(ORIGIN);
if (!win) {
btnFetch.style.background = '#f3ca63';
btnFetch.onclick = () => openTrace(arrayBuffer);
btnFetch.innerText = 'Popups blocked, click here to open the trace file';
return;
}
const timer = setInterval(() => win.postMessage('PING', ORIGIN), 50);
const onMessageHandler = (evt) => {
if (evt.data !== 'PONG') return;
// We got a PONG, the UI is ready.
window.clearInterval(timer);
window.removeEventListener('message', onMessageHandler);
const reopenUrl = new URL(location.href);
reopenUrl.hash = `#reopen=${traceUrl}`;
win.postMessage({
perfetto: {
buffer: arrayBuffer,
title: 'Lake Build Trace',
url: reopenUrl.toString(),
}}, ORIGIN);
};
window.addEventListener('message', onMessageHandler);
}
// This is triggered when following the link from the Perfetto UI's sidebar.
if (location.hash.startsWith('#reopen=')) {
const traceUrl = location.hash.substr(8);
fetchAndOpen(traceUrl);
}
EOF
cat <<EOF
btnFetch.onclick = () => fetchAndOpen("$BASE_URL/lakeprof.trace_event");
</script>
EOF
echo "<pre><code>"
(cd src; lakeprof report -prc)
echo "</code></pre>"
echo "</body></html>"
} | tee index.html
curl -T index.html $BASE_URL/index.html
curl -T src/lakeprof.log $BASE_URL/lakeprof.log
curl -T src/lakeprof.trace_event $BASE_URL/lakeprof.trace_event
fi

9
script/lakefile.toml Normal file
View File

@@ -0,0 +1,9 @@
name = "scripts"
[[lean_exe]]
name = "modulize"
root = "Modulize"
[[lean_exe]]
name = "shake"
root = "Shake"

1
script/lean-toolchain Normal file
View File

@@ -0,0 +1 @@
lean4

View File

@@ -5,8 +5,11 @@ set -euo pipefail
[ $# -eq 1 ] || (echo "usage: $0 <lean4 PR #>"; exit 1)
echo "Warning: the speedcenter is probably not listening on mathlib4-nightly-testing yet."
echo "If you're using this script, please contact @kim-em or @Kha to get this set up, and then remove this notice."
LEAN_PR=$1
PR_RESPONSE=$(gh api repos/leanprover-community/mathlib4/pulls -X POST -f head=lean-pr-testing-$LEAN_PR -f base=nightly-testing -f title="leanprover/lean4#$LEAN_PR benchmarking" -f draft=true -f body="ignore me")
PR_RESPONSE=$(gh api repos/leanprover-community/mathlib4-nightly-testing/pulls -X POST -f head=lean-pr-testing-$LEAN_PR -f base=nightly-testing -f title="leanprover/lean4#$LEAN_PR benchmarking" -f draft=true -f body="ignore me")
PR_NUMBER=$(echo "$PR_RESPONSE" | jq '.number')
echo "opened https://github.com/leanprover-community/mathlib4/pull/$PR_NUMBER"
gh api repos/leanprover-community/mathlib4/issues/$PR_NUMBER/comments -X POST -f body="!bench" > /dev/null
echo "opened https://github.com/leanprover-community/mathlib4-nightly-testing/pull/$PR_NUMBER"
gh api repos/leanprover-community/mathlib4-nightly-testing/issues/$PR_NUMBER/comments -X POST -f body="!bench" > /dev/null

View File

@@ -5,6 +5,7 @@ Merge a tag into a branch on a GitHub repository.
This script checks if a specified tag can be merged cleanly into a branch and performs
the merge if possible. If the merge cannot be done cleanly, it prints a helpful message.
Merge conflicts in the lean-toolchain file are automatically resolved by accepting the incoming changes.
Usage:
python3 merge_remote.py <org/repo> <branch> <tag>
@@ -58,6 +59,32 @@ def clone_repo(repo, temp_dir):
return True
def get_conflicted_files():
"""Get list of files with merge conflicts."""
result = run_command("git diff --name-only --diff-filter=U", check=False)
if result.returncode == 0:
return result.stdout.strip().split('\n') if result.stdout.strip() else []
return []
def resolve_lean_toolchain_conflict(tag):
"""Resolve lean-toolchain conflict by accepting incoming (tag) changes."""
print("Resolving lean-toolchain conflict by accepting incoming changes...")
# Accept theirs (incoming) version for lean-toolchain
result = run_command(f"git checkout --theirs lean-toolchain", check=False)
if result.returncode != 0:
print("Failed to resolve lean-toolchain conflict")
return False
# Add the resolved file
add_result = run_command("git add lean-toolchain", check=False)
if add_result.returncode != 0:
print("Failed to stage resolved lean-toolchain")
return False
return True
def check_and_merge(repo, branch, tag, temp_dir):
"""Check if tag can be merged into branch and perform the merge if possible."""
# Change to the temporary directory
@@ -98,12 +125,37 @@ def check_and_merge(repo, branch, tag, temp_dir):
# Try merging the tag directly
print(f"Merging {tag} into {branch}...")
merge_result = run_command(f"git merge {tag} --no-edit", check=False)
if merge_result.returncode != 0:
print(f"Cannot merge {tag} cleanly into {branch}.")
print("Merge conflicts would occur. Aborting merge.")
run_command("git merge --abort")
return False
# Check which files have conflicts
conflicted_files = get_conflicted_files()
if conflicted_files == ['lean-toolchain']:
# Only lean-toolchain has conflicts, resolve it
print("Merge conflict detected only in lean-toolchain.")
if resolve_lean_toolchain_conflict(tag):
# Continue the merge with the resolved conflict
print("Continuing merge with resolved lean-toolchain...")
continue_result = run_command(f"git commit --no-edit", check=False)
if continue_result.returncode != 0:
print("Failed to complete merge after resolving lean-toolchain")
run_command("git merge --abort")
return False
else:
print("Failed to resolve lean-toolchain conflict")
run_command("git merge --abort")
return False
else:
# Other files have conflicts, or unable to determine
if conflicted_files:
print(f"Cannot merge {tag} cleanly into {branch}.")
print(f"Merge conflicts in: {', '.join(conflicted_files)}")
else:
print(f"Cannot merge {tag} cleanly into {branch}.")
print("Merge conflicts would occur.")
print("Aborting merge.")
run_command("git merge --abort")
return False
print(f"Pushing changes to remote...")
push_result = run_command(f"git push origin {branch}")

View File

@@ -3,6 +3,32 @@ import sys
import subprocess
import requests
def check_gh_auth():
"""Check if GitHub CLI is properly authenticated."""
try:
result = subprocess.run(["gh", "auth", "status"], capture_output=True, text=True)
if result.returncode != 0:
return False, result.stderr
return True, None
except FileNotFoundError:
return False, "GitHub CLI (gh) is not installed. Please install it first."
except Exception as e:
return False, f"Error checking authentication: {e}"
def handle_gh_error(error_output):
"""Handle GitHub CLI errors and provide helpful messages."""
if "Not Found (HTTP 404)" in error_output:
return "Repository not found or access denied. Please check:\n" \
"1. The repository name is correct\n" \
"2. You have access to the repository\n" \
"3. Your GitHub CLI authentication is valid"
elif "Bad credentials" in error_output or "invalid" in error_output.lower():
return "Authentication failed. Please run 'gh auth login' to re-authenticate."
elif "rate limit" in error_output.lower():
return "GitHub API rate limit exceeded. Please try again later."
else:
return f"GitHub API error: {error_output}"
def main():
if len(sys.argv) != 4:
print("Usage: ./push_repo_release_tag.py <repo> <branch> <version_tag>")
@@ -14,6 +40,13 @@ def main():
print(f"Error: Branch '{branch}' is not 'master' or 'main'.")
sys.exit(1)
# Check GitHub CLI authentication first
auth_ok, auth_error = check_gh_auth()
if not auth_ok:
print(f"Authentication error: {auth_error}")
print("\nTo fix this, run: gh auth login")
sys.exit(1)
# Get the `lean-toolchain` file content
lean_toolchain_url = f"https://raw.githubusercontent.com/{repo}/{branch}/lean-toolchain"
try:
@@ -43,12 +76,23 @@ def main():
for tag in existing_tags:
print(tag.replace("refs/tags/", ""))
sys.exit(1)
elif list_tags_output.returncode != 0:
# Handle API errors when listing tags
error_msg = handle_gh_error(list_tags_output.stderr)
print(f"Error checking existing tags: {error_msg}")
sys.exit(1)
# Get the SHA of the branch
get_sha_cmd = [
"gh", "api", f"repos/{repo}/git/ref/heads/{branch}", "--jq", ".object.sha"
]
sha_result = subprocess.run(get_sha_cmd, capture_output=True, text=True, check=True)
sha_result = subprocess.run(get_sha_cmd, capture_output=True, text=True)
if sha_result.returncode != 0:
error_msg = handle_gh_error(sha_result.stderr)
print(f"Error getting branch SHA: {error_msg}")
sys.exit(1)
sha = sha_result.stdout.strip()
# Create the tag
@@ -58,11 +102,20 @@ def main():
"-F", f"ref=refs/tags/{version_tag}",
"-F", f"sha={sha}"
]
subprocess.run(create_tag_cmd, capture_output=True, text=True, check=True)
create_result = subprocess.run(create_tag_cmd, capture_output=True, text=True)
if create_result.returncode != 0:
error_msg = handle_gh_error(create_result.stderr)
print(f"Error creating tag: {error_msg}")
sys.exit(1)
print(f"Successfully created and pushed tag '{version_tag}' to {repo}.")
except subprocess.CalledProcessError as e:
print(f"Error while creating/pushing tag: {e.stderr.strip() if e.stderr else e}")
error_msg = handle_gh_error(e.stderr.strip() if e.stderr else str(e))
print(f"Error while creating/pushing tag: {error_msg}")
sys.exit(1)
except Exception as e:
print(f"Unexpected error: {e}")
sys.exit(1)
if __name__ == "__main__":

View File

@@ -1,5 +1,58 @@
#!/usr/bin/env python3
"""
Release Checklist for Lean4 and Downstream Repositories
This script validates the status of a Lean4 release across all dependent repositories.
It checks whether repositories are ready for release and identifies missing steps.
IMPORTANT: Keep this documentation up-to-date when modifying the script's behavior!
What this script does:
1. Validates preliminary Lean4 release infrastructure:
- Checks that the release branch (releases/vX.Y.0) exists
- Verifies CMake version settings are correct
- Confirms the release tag exists
- Validates the release page exists on GitHub (created automatically by CI after tag push)
- Checks the release notes page on lean-lang.org (updated while bumping the `reference-manual` repository)
**IMPORTANT: If the release page doesn't exist, the script will skip checking
downstream repositories and the master branch configuration. The preliminary
infrastructure must be in place before the release process can proceed.**
**NOTE: The GitHub release page is created AUTOMATICALLY by CI after the tag is pushed.
DO NOT create it manually. Wait for CI to complete after pushing the tag.**
2. For each downstream repository (batteries, mathlib4, etc.):
- Checks if dependencies are ready (e.g., mathlib4 depends on batteries)
- Verifies the main branch is on the target toolchain (or newer)
- Checks if a PR exists to bump the toolchain (if not yet updated)
- Validates tags exist for the release version
- Ensures tags are merged into stable branches (for non-RC releases)
- Verifies bump branches exist and are configured correctly
- Special handling for ProofWidgets4 release tags
3. Optionally automates missing steps (when not in --dry-run mode):
- Creates missing release tags using push_repo_release_tag.py
- Merges tags into stable branches using merge_remote.py
Usage:
./release_checklist.py v4.24.0 # Check release status
./release_checklist.py v4.24.0 --verbose # Show detailed debug info
./release_checklist.py v4.24.0 --dry-run # Check only, don't execute fixes
For automated release management with Claude Code:
/release v4.24.0 # Run full release process with Claude
The script reads repository configurations from release_repos.yml and reports:
- ✅ for completed requirements
- ❌ for missing requirements (with instructions to fix)
- 🟡 for repositories waiting on dependencies
- ⮕ for automated actions being taken
This script is idempotent and safe to rerun multiple times.
"""
import argparse
import yaml
import requests
@@ -76,6 +129,39 @@ def release_page_exists(repo_url, tag_name, github_token):
response = requests.get(api_url, headers=headers)
return response.status_code == 200
def get_tag_workflow_status(repo_url, tag_name, github_token):
"""Get the status of CI workflows running for a specific tag."""
api_base = repo_url.replace("https://github.com/", "https://api.github.com/repos/")
headers = {'Authorization': f'token {github_token}'} if github_token else {}
# Get workflow runs for the tag
# GitHub's workflow runs API uses the branch/tag name in the 'head_branch' field
api_url = f"{api_base}/actions/runs?event=push&head_branch={tag_name}"
response = requests.get(api_url, headers=headers)
if response.status_code != 200:
return None
data = response.json()
workflow_runs = data.get('workflow_runs', [])
if not workflow_runs:
return None
# Get the most recent workflow run for this tag
run = workflow_runs[0]
status = run.get('status')
conclusion = run.get('conclusion')
workflow_name = run.get('name', 'CI')
run_id = run.get('id')
return {
'status': status,
'conclusion': conclusion,
'workflow_name': workflow_name,
'run_id': run_id
}
def get_release_notes(tag_name):
"""Fetch release notes page title from lean-lang.org."""
# Strip -rcX suffix if present for the URL
@@ -84,20 +170,17 @@ def get_release_notes(tag_name):
try:
response = requests.get(reference_url)
response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
# Extract title using regex
match = re.search(r"<title>(.*?)</title>", response.text, re.IGNORECASE | re.DOTALL)
if match:
return match.group(1).strip()
else:
print(f" ⚠️ Could not find <title> tag in {reference_url}")
return None
except requests.exceptions.RequestException as e:
print(f" ❌ Error fetching release notes from {reference_url}: {e}")
except requests.exceptions.RequestException:
return None
except Exception as e:
print(f" ❌ An unexpected error occurred while processing release notes: {e}")
except Exception:
return None
def get_branch_content(repo_url, branch, file_path, github_token):
@@ -231,6 +314,43 @@ def get_next_version(version):
# Next version is always .0
return f"v{major}.{minor + 1}.0"
def get_latest_nightly_tag(github_token):
"""Get the most recent nightly tag from leanprover/lean4-nightly."""
api_url = "https://api.github.com/repos/leanprover/lean4-nightly/tags"
headers = {'Authorization': f'token {github_token}'} if github_token else {}
response = requests.get(api_url, headers=headers)
if response.status_code != 200:
return None
tags = response.json()
if not tags:
return None
# Return the most recent tag name
return tags[0]['name']
def update_lean_toolchain_in_branch(org_repo, branch, toolchain_content, github_token):
"""Update the lean-toolchain file in a specific branch."""
api_url = f"https://api.github.com/repos/{org_repo}/contents/lean-toolchain"
headers = {'Authorization': f'token {github_token}'} if github_token else {}
# First get the current file to get its SHA
response = requests.get(f"{api_url}?ref={branch}", headers=headers)
if response.status_code != 200:
return False
current_file = response.json()
file_sha = current_file['sha']
# Update the file
update_data = {
"message": f"chore: update lean-toolchain to {toolchain_content}",
"content": base64.b64encode(toolchain_content.encode('utf-8')).decode('utf-8'),
"sha": file_sha,
"branch": branch
}
response = requests.put(api_url, json=update_data, headers=headers)
return response.status_code in [200, 201]
def check_bump_branch_toolchain(url, bump_branch, github_token):
"""Check if the lean-toolchain file in bump branch starts with either 'leanprover/lean4:nightly-' or the next version."""
content = get_branch_content(url, bump_branch, "lean-toolchain", github_token)
@@ -249,6 +369,68 @@ def check_bump_branch_toolchain(url, bump_branch, github_token):
print(f" ✅ Bump branch correctly uses toolchain: {content}")
return True
def get_pr_ci_status(repo_url, pr_number, github_token):
"""Get the CI status for a pull request."""
api_base = repo_url.replace("https://github.com/", "https://api.github.com/repos/")
headers = {'Authorization': f'token {github_token}'} if github_token else {}
# Get PR details to find the head SHA
pr_response = requests.get(f"{api_base}/pulls/{pr_number}", headers=headers)
if pr_response.status_code != 200:
return "unknown", "Could not fetch PR details"
pr_data = pr_response.json()
head_sha = pr_data['head']['sha']
# Get check runs for the commit
check_runs_response = requests.get(
f"{api_base}/commits/{head_sha}/check-runs",
headers=headers
)
if check_runs_response.status_code != 200:
return "unknown", "Could not fetch check runs"
check_runs_data = check_runs_response.json()
check_runs = check_runs_data.get('check_runs', [])
if not check_runs:
# No check runs, check for status checks (legacy)
status_response = requests.get(
f"{api_base}/commits/{head_sha}/status",
headers=headers
)
if status_response.status_code == 200:
status_data = status_response.json()
state = status_data.get('state', 'unknown')
if state == 'success':
return "success", "All status checks passed"
elif state == 'failure':
return "failure", "Some status checks failed"
elif state == 'pending':
return "pending", "Status checks in progress"
return "unknown", "No CI checks found"
# Analyze check runs
conclusions = [run['conclusion'] for run in check_runs if run.get('status') == 'completed']
in_progress = [run for run in check_runs if run.get('status') in ['queued', 'in_progress']]
if in_progress:
return "pending", f"{len(in_progress)} check(s) in progress"
if not conclusions:
return "pending", "Checks queued"
if all(c == 'success' for c in conclusions):
return "success", f"All {len(conclusions)} checks passed"
failed = sum(1 for c in conclusions if c in ['failure', 'timed_out', 'action_required'])
if failed > 0:
return "failure", f"{failed} check(s) failed"
# Some checks are cancelled, skipped, or neutral
return "warning", f"Some checks did not complete normally"
def pr_exists_with_title(repo_url, title, github_token):
api_url = repo_url.replace("https://github.com/", "https://api.github.com/repos/") + "/pulls"
headers = {'Authorization': f'token {github_token}'} if github_token else {}
@@ -262,6 +444,61 @@ def pr_exists_with_title(repo_url, title, github_token):
return pr['number'], pr['html_url']
return None
def check_proofwidgets4_release(repo_url, target_toolchain, github_token):
"""Check if ProofWidgets4 has a release tag that uses the target toolchain."""
api_base = repo_url.replace("https://github.com/", "https://api.github.com/repos/")
headers = {'Authorization': f'token {github_token}'} if github_token else {}
# Get all tags matching v0.0.* pattern
response = requests.get(f"{api_base}/git/matching-refs/tags/v0.0.", headers=headers)
if response.status_code != 200:
print(f" ❌ Could not fetch ProofWidgets4 tags")
return False
tags = response.json()
if not tags:
print(f" ❌ No v0.0.* tags found for ProofWidgets4")
return False
# Extract tag names and sort by version number (descending)
tag_names = []
for tag in tags:
ref = tag['ref']
if ref.startswith('refs/tags/v0.0.'):
tag_name = ref.replace('refs/tags/', '')
try:
# Extract the number after v0.0.
version_num = int(tag_name.split('.')[-1])
tag_names.append((version_num, tag_name))
except (ValueError, IndexError):
continue
if not tag_names:
print(f" ❌ No valid v0.0.* tags found for ProofWidgets4")
return False
# Sort by version number (descending) and take the most recent 10
tag_names.sort(reverse=True)
recent_tags = tag_names[:10]
# Check each recent tag to see if it uses the target toolchain
for version_num, tag_name in recent_tags:
toolchain_content = get_branch_content(repo_url, tag_name, "lean-toolchain", github_token)
if toolchain_content is None:
continue
if is_version_gte(toolchain_content.strip(), target_toolchain):
print(f" ✅ Found release {tag_name} using compatible toolchain (>= {target_toolchain})")
return True
# If we get here, no recent release uses the target toolchain
# Find the highest version number to suggest the next one
highest_version = max(version_num for version_num, _ in recent_tags)
next_version = highest_version + 1
print(f" ❌ No recent ProofWidgets4 release uses toolchain >= {target_toolchain}")
print(f" You will need to create and push a tag v0.0.{next_version}")
return False
def main():
parser = argparse.ArgumentParser(description="Check release status of Lean4 repositories")
parser.add_argument("toolchain", help="The toolchain version to check (e.g., v4.6.0)")
@@ -312,30 +549,57 @@ def main():
print(f" ❌ Short commit hash {commit_hash[:SHORT_HASH_LENGTH]} is numeric and starts with 0, causing issues for version parsing. Try regenerating the last commit to get a new hash.")
lean4_success = False
if not release_page_exists(lean_repo_url, toolchain, github_token):
print(f" ❌ Release page for {toolchain} does not exist")
release_page_ready = release_page_exists(lean_repo_url, toolchain, github_token)
if not release_page_ready:
print(f" ❌ Release page for {toolchain} does not exist (This will be created by CI.)")
# Check CI workflow status
workflow_status = get_tag_workflow_status(lean_repo_url, toolchain, github_token)
if workflow_status:
status = workflow_status['status']
conclusion = workflow_status['conclusion']
workflow_name = workflow_status['workflow_name']
run_id = workflow_status['run_id']
workflow_url = f"{lean_repo_url}/actions/runs/{run_id}"
if status == 'in_progress' or status == 'queued':
print(f" 🔄 {workflow_name} workflow is {status}: {workflow_url}")
elif status == 'completed':
if conclusion == 'success':
print(f"{workflow_name} workflow completed successfully: {workflow_url}")
elif conclusion == 'failure':
print(f"{workflow_name} workflow failed: {workflow_url}")
else:
print(f" ⚠️ {workflow_name} workflow completed with status: {conclusion}: {workflow_url}")
else:
print(f" {workflow_name} workflow status: {status}: {workflow_url}")
lean4_success = False
else:
print(f" ✅ Release page for {toolchain} exists")
# Check the actual release notes page title
# Check the actual release notes page title (informational only - does not block)
actual_title = get_release_notes(toolchain)
expected_title_prefix = f"Lean {toolchain.lstrip('v')}" # e.g., "Lean 4.19.0" or "Lean 4.19.0-rc1"
base_tag = toolchain.split('-')[0]
release_notes_url = f"https://lean-lang.org/doc/reference/latest/releases/{base_tag}/"
if actual_title is None:
# Error already printed by get_release_notes
lean4_success = False
print(f" ⚠️ Release notes not found at {release_notes_url} (this will be fixed while updating the reference-manual repository)")
elif not actual_title.startswith(expected_title_prefix):
# Construct URL for the error message (using the base tag)
base_tag = toolchain.split('-')[0]
check_url = f"https://lean-lang.org/doc/reference/latest/releases/{base_tag}/"
print(f" ❌ Release notes page title mismatch. Expected prefix '{expected_title_prefix}', got '{actual_title}'. Check {check_url}")
lean4_success = False
print(f" ⚠️ Release notes page title mismatch. Expected prefix '{expected_title_prefix}', got '{actual_title}'. Check {release_notes_url}")
else:
print(f" ✅ Release notes page title looks good ('{actual_title}').")
repo_status["lean4"] = lean4_success
# If the release page doesn't exist, skip repository checks and master branch checks
# The preliminary infrastructure must be in place first
if not release_page_exists(lean_repo_url, toolchain, github_token):
print("\n⚠️ Release process blocked: preliminary Lean4 infrastructure incomplete.")
print(" Complete the steps above, then rerun this script to proceed with downstream repositories.")
return
# Load repositories and perform further checks
print("\nChecking repositories...")
@@ -379,6 +643,19 @@ def main():
if pr_info:
pr_number, pr_url = pr_info
print(f" ✅ PR with title '{pr_title}' exists: #{pr_number} ({pr_url})")
# Check CI status
ci_status, ci_message = get_pr_ci_status(url, pr_number, github_token)
if ci_status == "success":
print(f" ✅ CI: {ci_message}")
elif ci_status == "failure":
print(f" ❌ CI: {ci_message}")
elif ci_status == "pending":
print(f" 🔄 CI: {ci_message}")
elif ci_status == "warning":
print(f" ⚠️ CI: {ci_message}")
else:
print(f" ❓ CI: {ci_message}")
else:
print(f" ❌ PR with title '{pr_title}' does not exist")
print(f" Run `script/release_steps.py {toolchain} {name}` to create it")
@@ -386,6 +663,12 @@ def main():
continue
print(f" ✅ On compatible toolchain (>= {toolchain})")
# Special handling for ProofWidgets4
if name == "ProofWidgets4":
if not check_proofwidgets4_release(url, toolchain, github_token):
repo_status[name] = False
continue
if check_tag:
tag_exists_initially = tag_exists(url, toolchain, github_token)
if not tag_exists_initially:
@@ -394,7 +677,7 @@ def main():
repo_status[name] = False
continue
else:
print(f" Tag {toolchain} does not exist. Running `script/push_repo_release_tag.py {org_repo} {branch} {toolchain}`...")
print(f" Tag {toolchain} does not exist. Running `script/push_repo_release_tag.py {org_repo} {branch} {toolchain}`...")
# Run the script to create the tag
subprocess.run(["script/push_repo_release_tag.py", org_repo, branch, toolchain])
@@ -417,7 +700,7 @@ def main():
repo_status[name] = False
continue
else:
print(f" Tag {toolchain} is not merged into stable. Running `script/merge_remote.py {org_repo} stable {toolchain}`...")
print(f" Tag {toolchain} is not merged into stable. Running `script/merge_remote.py {org_repo} stable {toolchain}`...")
# Run the script to merge the tag
subprocess.run(["script/merge_remote.py", org_repo, "stable", toolchain])
@@ -434,19 +717,49 @@ def main():
if check_bump:
next_version = get_next_version(toolchain)
bump_branch = f"bump/{next_version}"
if not branch_exists(url, bump_branch, github_token):
# For mathlib4, use the nightly-testing fork for bump branches
bump_org_repo = org_repo
bump_url = url
if name == "mathlib4":
bump_org_repo = "leanprover-community/mathlib4-nightly-testing"
bump_url = "https://github.com/leanprover-community/mathlib4-nightly-testing"
branch_created = False
if not branch_exists(bump_url, bump_branch, github_token):
if args.dry_run:
print(f" ❌ Bump branch {bump_branch} does not exist. Run `gh api -X POST /repos/{org_repo}/git/refs -f ref=refs/heads/{bump_branch} -f sha=$(gh api /repos/{org_repo}/git/refs/heads/{branch} --jq .object.sha)` to create it.")
latest_nightly = get_latest_nightly_tag(github_token)
nightly_note = f" (will set lean-toolchain to {latest_nightly})" if name in ["batteries", "mathlib4"] and latest_nightly else ""
print(f" ❌ Bump branch {bump_branch} does not exist. Run `gh api -X POST /repos/{bump_org_repo}/git/refs -f ref=refs/heads/{bump_branch} -f sha=$(gh api /repos/{org_repo}/git/refs/heads/{branch} --jq .object.sha)` to create it{nightly_note}.")
repo_status[name] = False
continue
print(f" Bump branch {bump_branch} does not exist. Creating it...")
result = run_command(f"gh api -X POST /repos/{org_repo}/git/refs -f ref=refs/heads/{bump_branch} -f sha=$(gh api /repos/{org_repo}/git/refs/heads/{branch} --jq .object.sha)", check=False)
print(f" Bump branch {bump_branch} does not exist. Creating it...")
result = run_command(f"gh api -X POST /repos/{bump_org_repo}/git/refs -f ref=refs/heads/{bump_branch} -f sha=$(gh api /repos/{org_repo}/git/refs/heads/{branch} --jq .object.sha)", check=False)
if result.returncode != 0:
print(f" ❌ Failed to create bump branch {bump_branch}")
repo_status[name] = False
continue
branch_created = True
print(f" ✅ Bump branch {bump_branch} exists")
if not check_bump_branch_toolchain(url, bump_branch, github_token):
# For batteries and mathlib4, update the lean-toolchain to the latest nightly
if branch_created and name in ["batteries", "mathlib4"]:
latest_nightly = get_latest_nightly_tag(github_token)
if latest_nightly:
nightly_toolchain = f"leanprover/lean4:{latest_nightly}"
print(f" ⮕ Updating lean-toolchain to {nightly_toolchain}...")
if update_lean_toolchain_in_branch(bump_org_repo, bump_branch, nightly_toolchain, github_token):
print(f" ✅ Updated lean-toolchain to {nightly_toolchain}")
else:
print(f" ❌ Failed to update lean-toolchain to {nightly_toolchain}")
repo_status[name] = False
continue
else:
print(f" ❌ Could not fetch latest nightly tag")
repo_status[name] = False
continue
if not check_bump_branch_toolchain(bump_url, bump_branch, github_token):
repo_status[name] = False
continue

View File

@@ -52,6 +52,7 @@ def sort_sections_order():
return [
"Language",
"Library",
"Tactics",
"Compiler",
"Pretty Printing",
"Documentation",

View File

@@ -1,4 +1,11 @@
repositories:
- name: lean4-cli
url: https://github.com/leanprover/lean4-cli
toolchain-tag: true
stable-branch: false
branch: main
dependencies: []
- name: batteries
url: https://github.com/leanprover-community/batteries
toolchain-tag: true
@@ -7,6 +14,13 @@ repositories:
bump-branch: true
dependencies: []
- name: verso
url: https://github.com/leanprover/verso
toolchain-tag: true
stable-branch: false
branch: main
dependencies: []
- name: lean4checker
url: https://github.com/leanprover/lean4checker
toolchain-tag: true
@@ -21,13 +35,21 @@ repositories:
branch: master
dependencies: []
- name: lean4-cli
url: https://github.com/leanprover/lean4-cli
- name: plausible
url: https://github.com/leanprover-community/plausible
toolchain-tag: true
stable-branch: false
branch: main
dependencies: []
- name: import-graph
url: https://github.com/leanprover-community/import-graph
toolchain-tag: true
stable-branch: false
branch: main
dependencies:
- lean4-cli
- name: doc-gen4
url: https://github.com/leanprover/doc-gen4
toolchain-tag: true
@@ -35,13 +57,6 @@ repositories:
branch: main
dependencies: [lean4-cli]
- name: verso
url: https://github.com/leanprover/verso
toolchain-tag: true
stable-branch: false
branch: main
dependencies: []
- name: reference-manual
url: https://github.com/leanprover/reference-manual
toolchain-tag: true
@@ -65,22 +80,6 @@ repositories:
dependencies:
- batteries
- name: import-graph
url: https://github.com/leanprover-community/import-graph
toolchain-tag: true
stable-branch: false
branch: main
dependencies:
- lean4-cli
- batteries
- name: plausible
url: https://github.com/leanprover-community/plausible
toolchain-tag: true
stable-branch: false
branch: main
dependencies: []
- name: mathlib4
url: https://github.com/leanprover-community/mathlib4
toolchain-tag: true
@@ -97,6 +96,15 @@ repositories:
- import-graph
- plausible
- name: cslib
url: https://github.com/leanprover/cslib
toolchain-tag: true
stable-branch: true
branch: main
bump-branch: true
dependencies:
- mathlib4
- name: repl
url: https://github.com/leanprover-community/repl
toolchain-tag: true
@@ -104,3 +112,11 @@ repositories:
branch: master
dependencies:
- mathlib4
- name: lean-fro.org
url: https://github.com/leanprover/lean-fro.org
toolchain-tag: false
stable-branch: false
branch: master
dependencies:
- verso

View File

@@ -1,30 +1,53 @@
#!/usr/bin/env python3
"""
Generate release steps script for Lean4 repositories.
Execute Release Steps for Lean4 Downstream Repositories
This script helps automate the release process for Lean4 and its dependent repositories
by generating step-by-step instructions for updating toolchains, creating tags,
and managing branches.
This script automates the process of updating a downstream repository to a new Lean4 release.
It handles creating branches, updating toolchains, merging changes, building, testing, and
creating pull requests.
IMPORTANT: Keep this documentation up-to-date when modifying the script's behavior!
What this script does:
1. Sets up the downstream_releases/ directory for cloning repositories
2. Clones or updates the target repository
3. Creates a branch named bump_to_{version} for the changes
4. Updates the lean-toolchain file to the target version
5. Handles repository-specific variations:
- Different dependency update mechanisms
- Special merging strategies for repositories with nightly-testing branches
- Safety checks for repositories using bump branches
- Custom build and test procedures
6. Commits the changes with message "chore: bump toolchain to {version}"
7. Builds the project (with a clean .lake cache)
8. Runs tests if available
9. Pushes the branch to GitHub
10. Creates a pull request (or reports if one already exists)
Usage:
python3 release_steps.py <version> <repo>
./release_steps.py v4.24.0 batteries # Update batteries to v4.24.0
./release_steps.py v4.24.0-rc1 mathlib4 # Update mathlib4 to v4.24.0-rc1
Arguments:
version: The version to set in the lean-toolchain file (e.g., v4.6.0)
repo: A substring of the repository name as specified in release_repos.yml
The script reads repository configurations from release_repos.yml.
Each repository has specific handling for merging, dependencies, and testing.
Example:
python3 release_steps.py v4.6.0 mathlib
python3 release_steps.py v4.6.0 batt
This script is idempotent - it's safe to rerun if it fails partway through.
Existing branches, commits, and PRs will be reused rather than duplicated.
The script reads repository configurations from release_repos.yml in the same directory.
Each repository may have specific requirements for:
- Branch management
- Toolchain updates
- Dependency updates
- Tagging conventions
- Stable branch handling
Error handling:
- If build or tests fail, the script continues to create the PR anyway
- Manual conflicts must be resolved by the user
- Network issues during push/PR creation are reported with manual instructions
"""
import argparse
@@ -32,23 +55,124 @@ import yaml
import os
import sys
import re
import subprocess
import shutil
import json
from pathlib import Path
# Color functions for terminal output
def blue(text):
"""Blue text for 'I'm doing something' messages."""
return f"\033[94m{text}\033[0m"
def green(text):
"""Green text for 'successful step' messages."""
return f"\033[92m{text}\033[0m"
def red(text):
"""Red text for 'this looks bad' messages."""
return f"\033[91m{text}\033[0m"
def yellow(text):
"""Yellow text for warnings."""
return f"\033[93m{text}\033[0m"
def run_command(cmd, cwd=None, check=True, stream_output=False):
"""Run a shell command and return the result."""
print(blue(f"Running: {cmd}"))
try:
if stream_output:
# Stream output in real-time for long-running commands
result = subprocess.run(cmd, shell=True, cwd=cwd, check=check, text=True)
return result
else:
# Capture output for commands where we need to process the result
result = subprocess.run(cmd, shell=True, cwd=cwd, check=check,
capture_output=True, text=True)
if result.stdout:
# Command output in plain white (default terminal color)
print(result.stdout)
return result
except subprocess.CalledProcessError as e:
print(red(f"Error running command: {cmd}"))
print(red(f"Exit code: {e.returncode}"))
if not stream_output:
print(f"Stdout: {e.stdout}")
print(f"Stderr: {e.stderr}")
raise
def load_repos_config(file_path):
with open(file_path, "r") as f:
return yaml.safe_load(f)["repositories"]
def find_repo(repo_substring, config):
pattern = re.compile(re.escape(repo_substring), re.IGNORECASE)
matching_repos = [r for r in config if pattern.search(r["name"])]
def find_repo(repo_name, config):
matching_repos = [r for r in config if r["name"] == repo_name]
if not matching_repos:
print(f"Error: No repository matching '{repo_substring}' found in configuration.")
sys.exit(1)
if len(matching_repos) > 1:
print(f"Error: Multiple repositories matching '{repo_substring}' found in configuration: {', '.join(r['name'] for r in matching_repos)}")
print(red(f"Error: No repository named '{repo_name}' found in configuration."))
available_repos = [r["name"] for r in config]
print(yellow(f"Available repositories: {', '.join(available_repos)}"))
sys.exit(1)
return matching_repos[0]
def generate_script(repo, version, config):
def setup_downstream_releases_dir():
"""Create the downstream_releases directory if it doesn't exist."""
downstream_dir = Path("downstream_releases")
if not downstream_dir.exists():
print(blue(f"Creating {downstream_dir} directory..."))
downstream_dir.mkdir()
print(green(f"Created {downstream_dir} directory"))
return downstream_dir
def clone_or_update_repo(repo_url, repo_dir, downstream_dir):
"""Clone the repository if it doesn't exist, or update it if it does."""
repo_path = downstream_dir / repo_dir
if repo_path.exists():
print(blue(f"Repository {repo_dir} already exists, updating..."))
run_command("git fetch", cwd=repo_path)
print(green(f"Updated repository {repo_dir}"))
else:
print(blue(f"Cloning {repo_url} to {repo_path}..."))
run_command(f"git clone {repo_url}", cwd=downstream_dir)
print(green(f"Cloned repository {repo_dir}"))
return repo_path
def get_remotes_for_repo(repo_name):
"""Get the appropriate remotes for bump and nightly-testing branches based on repository."""
if repo_name == "mathlib4":
return "nightly-testing", "nightly-testing"
else:
return "origin", "origin"
def check_and_abort_merge(repo_path):
"""Check if repository is in the middle of a merge and abort it if so."""
merge_head_file = repo_path / ".git" / "MERGE_HEAD"
if merge_head_file.exists():
print(yellow(f"Repository {repo_path.name} is in the middle of a merge. Aborting merge..."))
run_command("git merge --abort", cwd=repo_path)
print(green("Merge aborted successfully"))
return True
# Also check git status for other merge-related states
try:
result = run_command("git status --porcelain=v1", cwd=repo_path, check=False)
if result.returncode == 0:
# Check for unmerged paths (indicated by 'UU', 'AA', etc. in git status)
for line in result.stdout.splitlines():
if len(line) >= 2 and line[:2] in ['UU', 'AA', 'DD', 'AU', 'UA', 'DU', 'UD']:
print(yellow(f"Repository {repo_path.name} has unmerged paths. Aborting merge..."))
run_command("git merge --abort", cwd=repo_path)
print(green("Merge aborted successfully"))
return True
except subprocess.CalledProcessError:
# If git status fails, we'll let the main process handle it
pass
return False
def execute_release_steps(repo, version, config):
repo_config = find_repo(repo, config)
repo_name = repo_config['name']
repo_url = repo_config['url']
@@ -59,92 +183,519 @@ def generate_script(repo, version, config):
requires_tagging = repo_config.get("toolchain-tag", True)
has_stable_branch = repo_config.get("stable-branch", True)
script_lines = [
f"cd {repo_dir}",
"git fetch",
f"git checkout {default_branch} && git pull",
f"git checkout -b bump_to_{version}",
f"echo leanprover/lean4:{version} > lean-toolchain",
]
# Setup downstream releases directory
downstream_dir = setup_downstream_releases_dir()
# Clone or update the repository
repo_path = clone_or_update_repo(repo_url, repo_dir, downstream_dir)
# Special remote setup for mathlib4
if repo_name == "mathlib4":
print(blue("Setting up special remotes for mathlib4..."))
try:
# Check if nightly-testing remote already exists
result = run_command("git remote get-url nightly-testing", cwd=repo_path, check=False)
if result.returncode != 0:
# Add the nightly-testing remote
run_command("git remote add nightly-testing https://github.com/leanprover-community/mathlib4-nightly-testing.git", cwd=repo_path)
print(green("Added nightly-testing remote"))
else:
print(green("nightly-testing remote already exists"))
# Fetch from the nightly-testing remote
run_command("git fetch nightly-testing", cwd=repo_path)
print(green("Fetched from nightly-testing remote"))
except subprocess.CalledProcessError as e:
print(red(f"Error setting up mathlib4 remotes: {e}"))
print(yellow("Continuing with default remote setup..."))
print(blue(f"\n=== Executing release steps for {repo_name} ==="))
# Check if repository is in the middle of a merge and abort it if necessary
check_and_abort_merge(repo_path)
# Execute the release steps
run_command(f"git checkout {default_branch} && git pull", cwd=repo_path)
# Special rc1 safety check for batteries and mathlib4 (before creating any branches)
if repo_name in ["batteries", "mathlib4"] and version.endswith('-rc1'):
print(blue("This repo has nightly-testing infrastructure"))
print(blue(f"Checking if nightly-testing can be safely merged into bump/{version.split('-rc')[0]}..."))
# Get the base version (e.g., v4.6.0 from v4.6.0-rc1)
base_version = version.split('-rc')[0]
bump_branch = f"bump/{base_version}"
# Determine which remote to use for bump and nightly-testing branches
bump_remote, nightly_remote = get_remotes_for_repo(repo_name)
try:
# Fetch latest changes from the appropriate remote
run_command(f"git fetch {bump_remote}", cwd=repo_path)
# Check if the bump branch exists
result = run_command(f"git show-ref --verify --quiet refs/remotes/{bump_remote}/{bump_branch}", cwd=repo_path, check=False)
if result.returncode != 0:
print(red(f"Bump branch {bump_remote}/{bump_branch} does not exist. Cannot perform safety check."))
print(yellow("Please ensure the bump branch exists before proceeding."))
return
# Create a temporary branch for testing the merge
temp_branch = f"temp-merge-test-{base_version}"
# Clean up any existing temp branch from previous runs
result = run_command(f"git show-ref --verify --quiet refs/heads/{temp_branch}", cwd=repo_path, check=False)
if result.returncode == 0:
print(blue(f"Cleaning up existing temp branch {temp_branch}..."))
# Make sure we're not on the temp branch before deleting it
run_command(f"git checkout {default_branch}", cwd=repo_path)
run_command(f"git branch -D {temp_branch}", cwd=repo_path)
print(green(f"Deleted existing temp branch {temp_branch}"))
run_command(f"git checkout -b {temp_branch} {bump_remote}/{bump_branch}", cwd=repo_path)
# Try to merge nightly-testing
try:
run_command(f"git merge {nightly_remote}/nightly-testing", cwd=repo_path)
# Check what files have changed compared to the bump branch
changed_files = run_command(f"git diff --name-only {bump_remote}/{bump_branch}..HEAD", cwd=repo_path)
# Filter out allowed changes
allowed_patterns = ['lean-toolchain', 'lake-manifest.json']
problematic_files = []
for file in changed_files.stdout.strip().split('\n'):
if file.strip(): # Skip empty lines
is_allowed = any(pattern in file for pattern in allowed_patterns)
if not is_allowed:
problematic_files.append(file)
# Clean up temporary branch and return to default branch
run_command(f"git checkout {default_branch}", cwd=repo_path)
run_command(f"git branch -D {temp_branch}", cwd=repo_path)
if problematic_files:
print(red("❌ Safety check failed!"))
print(red(f"Merging nightly-testing into {bump_branch} would result in changes to:"))
for file in problematic_files:
print(red(f" - {file}"))
print(yellow("\nYou need to make a PR merging the changes from nightly-testing into the bump branch first."))
print(yellow(f"Create a PR from nightly-testing targeting {bump_branch} to resolve these changes."))
return
else:
print(green("✅ Safety check passed - only lean-toolchain and/or lake-manifest.json would change"))
except subprocess.CalledProcessError:
# Merge failed due to conflicts - check which files are conflicted
print(blue("Merge failed, checking which files are affected..."))
# Get all changed files using git status
status_result = run_command("git status --porcelain", cwd=repo_path)
changed_files = []
for line in status_result.stdout.splitlines():
if line.strip(): # Skip empty lines
# Extract filename (skip the first 3 characters which are status codes)
changed_files.append(line[3:])
# Filter out allowed files
allowed_patterns = ['lean-toolchain', 'lake-manifest.json']
problematic_files = []
for file in changed_files:
is_allowed = any(pattern in file for pattern in allowed_patterns)
if not is_allowed:
problematic_files.append(file)
if problematic_files:
# There are changes in non-allowed files - fail the safety check
# First abort the merge to clean up the conflicted state
run_command("git merge --abort", cwd=repo_path)
run_command(f"git checkout {default_branch}", cwd=repo_path)
run_command(f"git branch -D {temp_branch}", cwd=repo_path)
print(red("❌ Safety check failed!"))
print(red(f"Merging nightly-testing into {bump_branch} would result in changes to:"))
for file in problematic_files:
print(red(f" - {file}"))
print(yellow("\nYou need to make a PR merging the changes from nightly-testing into the bump branch first."))
print(yellow(f"Create a PR from nightly-testing targeting {bump_branch} to resolve these changes."))
return
else:
# Only allowed files are changed - resolve them and continue
print(green(f"✅ Only allowed files changed: {', '.join(changed_files)}"))
print(blue("Resolving conflicts by taking nightly-testing version..."))
# For each changed allowed file, take the nightly-testing version
for file in changed_files:
run_command(f"git checkout --theirs {file}", cwd=repo_path)
# Complete the merge
run_command("git add .", cwd=repo_path)
run_command("git commit --no-edit", cwd=repo_path)
print(green("✅ Safety check passed - changes only in allowed files"))
# Clean up temporary branch and return to default branch
run_command(f"git checkout {default_branch}", cwd=repo_path)
run_command(f"git branch -D {temp_branch}", cwd=repo_path)
except subprocess.CalledProcessError as e:
# Ensure we're back on the default branch even if setup failed
try:
run_command(f"git checkout {default_branch}", cwd=repo_path)
except subprocess.CalledProcessError:
print(red(f"Cannot return to {default_branch} branch. Repository is in an inconsistent state."))
print(red("Please manually check the repository state and fix any issues."))
return
print(red(f"Error during safety check: {e}"))
print(yellow("Skipping safety check and proceeding with normal merge..."))
# Check if the branch already exists
branch_name = f"bump_to_{version}"
try:
# Check if branch exists locally
result = run_command(f"git show-ref --verify --quiet refs/heads/{branch_name}", cwd=repo_path, check=False)
if result.returncode == 0:
print(blue(f"Branch {branch_name} already exists, checking it out..."))
run_command(f"git checkout {branch_name}", cwd=repo_path)
print(green(f"Checked out existing branch {branch_name}"))
else:
print(blue(f"Creating new branch {branch_name}..."))
run_command(f"git checkout -b {branch_name}", cwd=repo_path)
print(green(f"Created new branch {branch_name}"))
except subprocess.CalledProcessError:
print(blue(f"Creating new branch {branch_name}..."))
run_command(f"git checkout -b {branch_name}", cwd=repo_path)
print(green(f"Created new branch {branch_name}"))
# Update lean-toolchain
print(blue("Updating lean-toolchain file..."))
toolchain_file = repo_path / "lean-toolchain"
with open(toolchain_file, "w") as f:
f.write(f"leanprover/lean4:{version}\n")
print(green(f"Updated lean-toolchain to leanprover/lean4:{version}"))
# Special cases for specific repositories
if repo_name == "repl":
script_lines.extend([
"lake update",
"cd test/Mathlib",
f"perl -pi -e 's/rev = \"v\\d+\\.\\d+\\.\\d+(-rc\\d+)?\"/rev = \"{version}\"/g' lakefile.toml",
f"echo leanprover/lean4:{version} > lean-toolchain",
"lake update",
"cd ../..",
"./test.sh"
])
run_command("lake update", cwd=repo_path, stream_output=True)
mathlib_test_dir = repo_path / "test" / "Mathlib"
run_command(f'perl -pi -e \'s/rev = "v\\d+\\.\\d+\\.\\d+(-rc\\d+)?"/rev = "{version}"/g\' lakefile.toml', cwd=mathlib_test_dir)
# Update lean-toolchain in test/Mathlib
print(blue("Updating test/Mathlib/lean-toolchain..."))
mathlib_toolchain = mathlib_test_dir / "lean-toolchain"
with open(mathlib_toolchain, "w") as f:
f.write(f"leanprover/lean4:{version}\n")
print(green(f"Updated test/Mathlib/lean-toolchain to leanprover/lean4:{version}"))
run_command("lake update", cwd=mathlib_test_dir, stream_output=True)
try:
result = run_command("./test.sh", cwd=repo_path, stream_output=True, check=False)
if result.returncode == 0:
print(green("Tests completed successfully"))
else:
print(red("Tests failed, but continuing with PR creation..."))
print(red(f"Test exit code: {result.returncode}"))
except subprocess.CalledProcessError as e:
print(red("Tests failed, but continuing with PR creation..."))
print(red(f"Test error: {e}"))
elif repo_name == "lean-fro.org":
# Update lean-toolchain in examples/hero
print(blue("Updating examples/hero/lean-toolchain..."))
docs_toolchain = repo_path / "examples" / "hero" / "lean-toolchain"
with open(docs_toolchain, "w") as f:
f.write(f"leanprover/lean4:{version}\n")
print(green(f"Updated examples/hero/lean-toolchain to leanprover/lean4:{version}"))
print(blue("Running `lake update`..."))
run_command("lake update", cwd=repo_path, stream_output=True)
print(blue("Running `lake update` in examples/hero..."))
run_command("lake update", cwd=repo_path / "examples" / "hero", stream_output=True)
elif repo_name == "cslib":
print(blue("Updating lakefile.toml..."))
run_command(f'perl -pi -e \'s/"v4\\.[0-9]+(\\.[0-9]+)?(-rc[0-9]+)?"/"' + version + '"/g\' lakefile.*', cwd=repo_path)
print(blue("Updating docs/lakefile.toml..."))
run_command(f'perl -pi -e \'s/"v4\\.[0-9]+(\\.[0-9]+)?(-rc[0-9]+)?"/"' + version + '"/g\' lakefile.*', cwd=repo_path / "docs")
# Update lean-toolchain in docs
print(blue("Updating docs/lean-toolchain..."))
docs_toolchain = repo_path / "docs" / "lean-toolchain"
with open(docs_toolchain, "w") as f:
f.write(f"leanprover/lean4:{version}\n")
print(green(f"Updated docs/lean-toolchain to leanprover/lean4:{version}"))
run_command("lake update", cwd=repo_path, stream_output=True)
elif dependencies:
script_lines.append('perl -pi -e \'s/"v4\\.[0-9]+(\\.[0-9]+)?(-rc[0-9]+)?"/"' + version + '"/g\' lakefile.*')
script_lines.append("lake update")
run_command(f'perl -pi -e \'s/"v4\\.[0-9]+(\\.[0-9]+)?(-rc[0-9]+)?"/"' + version + '"/g\' lakefile.*', cwd=repo_path)
run_command("lake update", cwd=repo_path, stream_output=True)
script_lines.append("")
# Commit changes (only if there are changes)
print(blue("Checking for changes to commit..."))
try:
# Check if there are any changes to commit (staged or unstaged)
result = run_command("git status --porcelain", cwd=repo_path, check=False)
if result.stdout.strip(): # There are changes
print(blue("Committing changes..."))
run_command(f'git commit -am "chore: bump toolchain to {version}"', cwd=repo_path)
print(green(f"Committed changes: chore: bump toolchain to {version}"))
else:
print(green("No changes to commit - toolchain already up to date"))
except subprocess.CalledProcessError:
print(yellow("Failed to check for changes, attempting commit anyway..."))
try:
run_command(f'git commit -am "chore: bump toolchain to {version}"', cwd=repo_path)
except subprocess.CalledProcessError as e:
if "nothing to commit" in e.stderr:
print(green("No changes to commit - toolchain already up to date"))
else:
raise
script_lines.extend([
f'git commit -am "chore: bump toolchain to {version}"',
""
])
# Handle special merging cases
if version.endswith('-rc1') and repo_name in ["batteries", "mathlib4"]:
print(blue("This repo uses `bump/v4.X.0` branches for reviewed content from nightly-testing."))
# Determine which remote to use for bump branches
bump_remote, nightly_remote = get_remotes_for_repo(repo_name)
# Fetch latest changes to ensure we have the most up-to-date bump branch
print(blue(f"Fetching latest changes from {bump_remote}..."))
run_command(f"git fetch {bump_remote}", cwd=repo_path)
try:
print(blue(f"Merging {bump_remote}/bump/{version.split('-rc')[0]}..."))
run_command(f"git merge {bump_remote}/bump/{version.split('-rc')[0]}", cwd=repo_path)
print(green("Merge completed successfully"))
except subprocess.CalledProcessError:
# Merge failed due to conflicts - check which files are conflicted
print(blue("Merge conflicts detected, checking which files are affected..."))
# Get conflicted files using git status
status_result = run_command("git status --porcelain", cwd=repo_path)
conflicted_files = []
for line in status_result.stdout.splitlines():
if len(line) >= 2 and line[:2] in ['UU', 'AA', 'DD', 'AU', 'UA', 'DU', 'UD']:
# Extract filename (skip the first 3 characters which are status codes)
conflicted_files.append(line[3:])
# Filter out allowed files
allowed_patterns = ['lean-toolchain', 'lake-manifest.json']
problematic_files = []
for file in conflicted_files:
is_allowed = any(pattern in file for pattern in allowed_patterns)
if not is_allowed:
problematic_files.append(file)
if problematic_files:
# There are conflicts in non-allowed files - fail
print(red("❌ Merge failed!"))
print(red(f"Merging {bump_remote}/bump/{version.split('-rc')[0]} resulted in conflicts in:"))
for file in problematic_files:
print(red(f" - {file}"))
print(red("Please resolve these conflicts manually."))
return
else:
# Only allowed files are conflicted - resolve them automatically
print(green(f"✅ Only allowed files conflicted: {', '.join(conflicted_files)}"))
print(blue("Resolving conflicts automatically..."))
# Overwrite lean-toolchain with our target version
if 'lean-toolchain' in conflicted_files:
print(blue(f"Overwriting lean-toolchain with target version {version}"))
toolchain_file = repo_path / "lean-toolchain"
with open(toolchain_file, "w") as f:
f.write(f"leanprover/lean4:{version}\n")
# For other allowed files, take our version (since we want our changes)
for file in conflicted_files:
if file != 'lean-toolchain':
run_command(f"git checkout --ours {file}", cwd=repo_path)
# Run lake update to rebuild lake-manifest.json
print(blue("Running lake update to rebuild lake-manifest.json..."))
run_command("lake update", cwd=repo_path, stream_output=True)
# Complete the merge
run_command("git add .", cwd=repo_path)
run_command("git commit --no-edit", cwd=repo_path)
print(green("✅ Merge completed successfully with automatic conflict resolution"))
elif version.endswith('-rc1'):
# For all other repos with rc versions, merge nightly-testing
if repo_name in ["verso", "reference-manual"]:
print(yellow("This repo does development on nightly-testing: remember to rebase merge the PR."))
# Fetch latest changes to ensure we have the most up-to-date nightly-testing branch
print(blue("Fetching latest changes from origin..."))
run_command("git fetch origin", cwd=repo_path)
try:
print(blue("Merging origin/nightly-testing..."))
run_command("git merge origin/nightly-testing", cwd=repo_path)
print(green("Merge completed successfully"))
except subprocess.CalledProcessError:
# Merge failed due to conflicts - check which files are conflicted
print(blue("Merge conflicts detected, checking which files are affected..."))
# Get conflicted files using git status
status_result = run_command("git status --porcelain", cwd=repo_path)
conflicted_files = []
for line in status_result.stdout.splitlines():
if len(line) >= 2 and line[:2] in ['UU', 'AA', 'DD', 'AU', 'UA', 'DU', 'UD']:
# Extract filename (skip the first 3 characters which are status codes)
conflicted_files.append(line[3:])
# Filter out allowed files
allowed_patterns = ['lean-toolchain', 'lake-manifest.json']
problematic_files = []
for file in conflicted_files:
is_allowed = any(pattern in file for pattern in allowed_patterns)
if not is_allowed:
problematic_files.append(file)
if problematic_files:
# There are conflicts in non-allowed files - fail
print(red("❌ Merge failed!"))
print(red(f"Merging nightly-testing resulted in conflicts in:"))
for file in problematic_files:
print(red(f" - {file}"))
print(red("Please resolve these conflicts manually."))
return
else:
# Only allowed files are conflicted - resolve them automatically
print(green(f"✅ Only allowed files conflicted: {', '.join(conflicted_files)}"))
print(blue("Resolving conflicts automatically..."))
# For lean-toolchain and lake-manifest.json, keep our versions
for file in conflicted_files:
print(blue(f"Keeping our version of {file}"))
run_command(f"git checkout --ours {file}", cwd=repo_path)
# Complete the merge
run_command("git add .", cwd=repo_path)
run_command("git commit --no-edit", cwd=repo_path)
print(green("✅ Merge completed successfully with automatic conflict resolution"))
if re.search(r'rc\d+$', version) and repo_name in ["batteries", "mathlib4"]:
script_lines.extend([
"echo 'This repo has nightly-testing infrastructure'",
f"git merge origin/bump/{version.split('-rc')[0]}",
"echo 'Please resolve any conflicts.'",
"grep nightly-testing lakefile.* && echo 'Please ensure the lakefile does not include nightly-testing versions.'",
""
])
if re.search(r'rc\d+$', version) and repo_name in ["verso", "reference-manual"]:
script_lines.extend([
"echo 'This repo does development on nightly-testing: remember to rebase merge the PR.'",
f"git merge origin/nightly-testing",
"echo 'Please resolve any conflicts.'",
""
])
if repo_name != "Mathlib":
script_lines.extend([
"lake build && if lake check-test; then lake test; fi",
""
])
# Build and test (skip for Mathlib)
if repo_name not in ["mathlib4"]:
print(blue("Building project..."))
# Clean lake cache for a fresh build
print(blue("Cleaning lake cache..."))
run_command("lake clean", cwd=repo_path)
script_lines.extend([
'gh pr create --title "chore: bump toolchain to ' + version + '" --body ""',
"echo 'Please review the PR and merge or rebase it.'",
""
])
# Check if downstream of Mathlib and get cache if so
mathlib_package_dir = repo_path / ".lake" / "packages" / "mathlib"
if mathlib_package_dir.exists():
print(blue("Project is downstream of Mathlib, fetching cache..."))
try:
run_command("lake exe cache get", cwd=repo_path, stream_output=True)
print(green("Cache fetched successfully"))
except subprocess.CalledProcessError as e:
print(yellow("Failed to fetch cache, continuing anyway..."))
print(yellow(f"Cache fetch error: {e}"))
return "\n".join(script_lines)
try:
run_command("lake build", cwd=repo_path, stream_output=True)
print(green("Build completed successfully"))
except subprocess.CalledProcessError as e:
print(red("Build failed, but continuing with PR creation..."))
print(red(f"Build error: {e}"))
# Check if lake check-test exists before running tests
print(blue("Running tests..."))
check_test_result = run_command("lake check-test", cwd=repo_path, check=False)
if check_test_result.returncode == 0:
try:
run_command("lake test", cwd=repo_path, stream_output=True)
print(green("Tests completed successfully"))
except subprocess.CalledProcessError as e:
print(red("Tests failed, but continuing with PR creation..."))
print(red(f"Test error: {e}"))
else:
print(yellow("lake check-test reports that there is no test suite"))
# Push the branch to remote before creating PR
print(blue("Checking remote branch status..."))
try:
# Check if branch exists on remote
result = run_command(f"git ls-remote --heads origin {branch_name}", cwd=repo_path, check=False)
if not result.stdout.strip():
print(blue(f"Pushing branch {branch_name} to remote..."))
run_command(f"git push -u origin {branch_name}", cwd=repo_path)
print(green(f"Successfully pushed branch {branch_name} to remote"))
else:
print(blue(f"Branch {branch_name} already exists on remote, pushing any new commits..."))
run_command(f"git push", cwd=repo_path)
print(green("Successfully pushed commits to remote"))
except subprocess.CalledProcessError:
print(red("Failed to push branch to remote. Please check your permissions and network connection."))
print(yellow(f"You may need to run: git push -u origin {branch_name}"))
return
# Create pull request (only if one doesn't already exist)
print(blue("Checking for existing pull request..."))
try:
# Check if PR already exists for this branch
result = run_command(f'gh pr list --head {branch_name} --json number', cwd=repo_path, check=False)
if result.returncode == 0 and result.stdout.strip() != "[]":
print(green(f"Pull request already exists for branch {branch_name}"))
# Get the PR URL
pr_result = run_command(f'gh pr view {branch_name} --json url', cwd=repo_path, check=False)
if pr_result.returncode == 0:
pr_data = json.loads(pr_result.stdout)
print(green(f"PR URL: {pr_data.get('url', 'N/A')}"))
else:
# Create new PR
print(blue("Creating new pull request..."))
run_command(f'gh pr create --title "chore: bump toolchain to {version}" --body ""', cwd=repo_path)
print(green("Pull request created successfully!"))
except subprocess.CalledProcessError:
print(red("Failed to check for existing PR or create new PR."))
print(yellow("This could be due to:"))
print(yellow("1. GitHub CLI not authenticated"))
print(yellow("2. No push permissions to the repository"))
print(yellow("3. Network issues"))
print(f"Branch: {branch_name}")
print(f"Title: chore: bump toolchain to {version}")
print(yellow("Please create the PR manually if needed."))
def main():
parser = argparse.ArgumentParser(
description="Generate release steps script for Lean4 repositories.",
description="Execute release steps for Lean4 repositories.",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
%(prog)s v4.6.0 mathlib Generate steps for updating Mathlib to v4.6.0
%(prog)s v4.6.0 batt Generate steps for updating Batteries to v4.6.0
%(prog)s v4.6.0 mathlib4 Execute steps for updating Mathlib to v4.6.0
%(prog)s v4.6.0 batteries Execute steps for updating Batteries to v4.6.0
The script will generate shell commands to:
1. Update the lean-toolchain file
2. Create appropriate branches and commits
3. Create pull requests
The script will:
1. Create a downstream_releases/ directory
2. Clone or update the target repository
3. Update the lean-toolchain file
4. Create appropriate branches and commits
5. Build and test the project
6. Create pull requests
(Note that the steps of creating toolchain version tags, and merging these into `stable` branches,
are handled by `script/release_checklist.py`.)
"""
)
parser.add_argument("version", help="The version to set in the lean-toolchain file (e.g., v4.6.0)")
parser.add_argument("repo", help="A substring of the repository name as specified in release_repos.yml")
parser.add_argument("repo", help="The repository name as specified in release_repos.yml")
args = parser.parse_args()
config_path = os.path.join(os.path.dirname(__file__), "release_repos.yml")
config = load_repos_config(config_path)
script = generate_script(args.repo, args.version, config)
print(script)
execute_release_steps(args.repo, args.version, config)
if __name__ == "__main__":
main()

View File

@@ -10,7 +10,7 @@ endif()
include(ExternalProject)
project(LEAN CXX C)
set(LEAN_VERSION_MAJOR 4)
set(LEAN_VERSION_MINOR 22)
set(LEAN_VERSION_MINOR 26)
set(LEAN_VERSION_PATCH 0)
set(LEAN_VERSION_IS_RELEASE 0) # This number is 1 in the release revision, and 0 otherwise.
set(LEAN_SPECIAL_VERSION_DESC "" CACHE STRING "Additional version description like 'nightly-2018-03-11'")
@@ -34,7 +34,14 @@ if (NOT LEAN_PLATFORM_TARGET)
OUTPUT_VARIABLE LEAN_PLATFORM_TARGET OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
set(LEAN_EXTRA_LINKER_FLAGS "" CACHE STRING "Additional flags used by the linker")
set(LEAN_EXTRA_LINKER_FLAGS_DEFAULT "")
# Use lld by default, if available
find_program(LLD_PATH lld)
if(LLD_PATH)
string(APPEND LEAN_EXTRA_LINKER_FLAGS_DEFAULT " -fuse-ld=lld")
endif()
set(LEAN_EXTRA_LINKER_FLAGS ${LEAN_EXTRA_LINKER_FLAGS_DEFAULT} CACHE STRING "Additional flags used by the linker")
set(LEAN_EXTRA_CXX_FLAGS "" CACHE STRING "Additional flags used by the C++ compiler")
set(LEAN_TEST_VARS "LEAN_CC=${CMAKE_C_COMPILER}" CACHE STRING "Additional environment variables used when running tests")
@@ -81,7 +88,8 @@ option(USE_MIMALLOC "use mimalloc" ON)
# development-specific options
option(CHECK_OLEAN_VERSION "Only load .olean files compiled with the current version of Lean" OFF)
option(USE_LAKE "Use Lake instead of lean.mk for building core libs from language server" OFF)
option(USE_LAKE "Use Lake instead of lean.mk for building core libs from language server" ON)
option(USE_LAKE_CACHE "Use the Lake artifact cache for stage 1 builds (requires USE_LAKE)" OFF)
set(LEAN_EXTRA_MAKE_OPTS "" CACHE STRING "extra options to lean --make")
set(LEANC_CC ${CMAKE_C_COMPILER} CACHE STRING "C compiler to use in `leanc`")
@@ -469,6 +477,7 @@ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
string(APPEND CMAKE_CXX_FLAGS " -ftls-model=initial-exec")
string(APPEND INIT_SHARED_LINKER_FLAGS " -install_name @rpath/libInit_shared.dylib")
string(APPEND LEANSHARED_1_LINKER_FLAGS " -install_name @rpath/libleanshared_1.dylib")
string(APPEND LEANSHARED_2_LINKER_FLAGS " -install_name @rpath/libleanshared_2.dylib")
string(APPEND LEANSHARED_LINKER_FLAGS " -install_name @rpath/libleanshared.dylib")
string(APPEND LAKESHARED_LINKER_FLAGS " -Wl,-force_load,${CMAKE_BINARY_DIR}/lib/lean/libLake.a.export -install_name @rpath/libLake_shared.dylib")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,-rpath,@executable_path/../lib -Wl,-rpath,@executable_path/../lib/lean")
@@ -502,7 +511,7 @@ endif()
# are already loaded) and probably fail unless we set up LD_LIBRARY_PATH.
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
# import libraries created by the stdlib.make targets
string(APPEND LEANC_SHARED_LINKER_FLAGS " -lInit_shared -lleanshared_1 -lleanshared")
string(APPEND LEANC_SHARED_LINKER_FLAGS " -lInit_shared -lleanshared_2 -lleanshared_1 -lleanshared")
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
# The second flag is necessary to even *load* dylibs without resolved symbols, as can happen
# if a Lake `extern_lib` depends on a symbols defined by the Lean library but is loaded even
@@ -533,12 +542,21 @@ else()
OUTPUT_VARIABLE GIT_SHA1
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "stage0 sha1: ${GIT_SHA1}")
# Now that we've prepared the information for the next stage, we can forget that we will use
# Lake in the future as we won't use it in this stage
set(USE_LAKE OFF)
else()
set(GIT_SHA1 "")
endif()
endif()
configure_file("${LEAN_SOURCE_DIR}/githash.h.in" "${LEAN_BINARY_DIR}/githash.h")
if(USE_LAKE AND ${STAGE} EQUAL 0)
# Now that we've prepared the information for the next stage, we can forget that we will use
# Lake in the future as we won't use it in this stage
set(USE_LAKE OFF)
endif()
# Windows uses ";" as a path separator. We use `LEAN_PATH_SEPARATOR` on scripts such as lean.mk.in
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(LEAN_PATH_SEPARATOR ";")
@@ -580,7 +598,7 @@ endif()
add_subdirectory(initialize)
add_subdirectory(shell)
# to be included in `leanshared` but not the smaller `leanshared_1` (as it would pull
# to be included in `leanshared` but not the smaller `leanshared_*` (as it would pull
# in the world)
add_library(leaninitialize STATIC $<TARGET_OBJECTS:initialize>)
set_target_properties(leaninitialize PROPERTIES
@@ -634,8 +652,6 @@ else()
set(LEAN_OBJS ${LEAN_OBJS} $<TARGET_OBJECTS:library>)
add_subdirectory(library/constructions)
set(LEAN_OBJS ${LEAN_OBJS} $<TARGET_OBJECTS:constructions>)
add_subdirectory(library/compiler)
set(LEAN_OBJS ${LEAN_OBJS} $<TARGET_OBJECTS:compiler>)
# leancpp without `initialize` (see `leaninitialize` above)
add_library(leancpp_1 STATIC ${LEAN_OBJS})
@@ -677,12 +693,17 @@ if (LLVM AND ${STAGE} GREATER 0)
set(EXTRA_LEANMAKE_OPTS "LLVM=1")
endif()
set(STDLIBS Init Std Lean Leanc)
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
list(APPEND STDLIBS Lake)
endif()
add_custom_target(make_stdlib ALL
WORKING_DIRECTORY ${LEAN_SOURCE_DIR}
# The actual rule is in a separate makefile because we want to prefix it with '+' to use the Make job server
# for a parallelized nested build, but CMake doesn't let us do that.
# We use `lean` from the previous stage, but `leanc`, headers, etc. from the current stage
COMMAND $(MAKE) -f ${CMAKE_BINARY_DIR}/stdlib.make Init Std Lean Leanc
COMMAND $(MAKE) -f ${CMAKE_BINARY_DIR}/stdlib.make ${STDLIBS}
VERBATIM)
# if we have LLVM enabled, then build `lean.h.bc` which has the LLVM bitcode
@@ -702,6 +723,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
)
add_custom_target(leanshared ALL
DEPENDS Init_shared leancpp
COMMAND touch ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libleanshared_2${CMAKE_SHARED_LIBRARY_SUFFIX}
COMMAND touch ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libleanshared_1${CMAKE_SHARED_LIBRARY_SUFFIX}
COMMAND touch ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libleanshared${CMAKE_SHARED_LIBRARY_SUFFIX}
)
@@ -722,18 +744,13 @@ else()
COMMAND $(MAKE) -f ${CMAKE_BINARY_DIR}/stdlib.make leanshared
VERBATIM)
string(APPEND CMAKE_EXE_LINKER_FLAGS " -lInit_shared -lleanshared_1 -lleanshared")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -lInit_shared -lleanshared_2 -lleanshared_1 -lleanshared")
endif()
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
add_custom_target(lake_lib
WORKING_DIRECTORY ${LEAN_SOURCE_DIR}
DEPENDS leanshared
COMMAND $(MAKE) -f ${CMAKE_BINARY_DIR}/stdlib.make Lake
VERBATIM)
add_custom_target(lake_shared
WORKING_DIRECTORY ${LEAN_SOURCE_DIR}
DEPENDS lake_lib
DEPENDS leanshared
COMMAND $(MAKE) -f ${CMAKE_BINARY_DIR}/stdlib.make libLake_shared
VERBATIM)
add_custom_target(lake ALL
@@ -788,6 +805,9 @@ install(DIRECTORY "${CMAKE_BINARY_DIR}/lib/" DESTINATION lib
# symlink source into expected installation location for go-to-definition, if file system allows it
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/src)
# get rid of all files in `src/lean` that may have been loaded from the cache
# (at the time of writing this, this is the case for some lake test .c files)
file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/src/lean)
if(${STAGE} EQUAL 0)
file(CREATE_LINK ${CMAKE_SOURCE_DIR}/../../src ${CMAKE_BINARY_DIR}/src/lean RESULT _IGNORE_RES SYMBOLIC)
else()
@@ -814,6 +834,15 @@ if(LEAN_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "${LEAN_INSTALL_PREFIX}/lean-${LEAN_VERSION_STRING}${LEAN_INSTALL_SUFFIX}")
endif()
if (USE_LAKE_CACHE AND STAGE EQUAL 1)
set(LAKE_ARTIFACT_CACHE_TOML "true")
else()
# The build of stage2+ may depend on local changes made to src/ that are not reflected by the
# commit hash in stage1/bin/lean, so we make sure to disable the global cache
set(LAKE_ARTIFACT_CACHE_TOML "false")
endif()
# Escape for `make`. Yes, twice.
string(REPLACE "$" "\\\$$" CMAKE_EXE_LINKER_FLAGS_MAKE "${CMAKE_EXE_LINKER_FLAGS}")
configure_file(${LEAN_SOURCE_DIR}/stdlib.make.in ${CMAKE_BINARY_DIR}/stdlib.make)
@@ -829,17 +858,19 @@ endfunction()
string(REPLACE "ROOT" "${CMAKE_BINARY_DIR}" LEANC_CC "${LEANC_CC}")
string(REPLACE "ROOT" "${CMAKE_BINARY_DIR}" LEANC_INTERNAL_FLAGS "${LEANC_INTERNAL_FLAGS}")
string(REPLACE "ROOT" "${CMAKE_BINARY_DIR}" LEANC_INTERNAL_LINKER_FLAGS "${LEANC_INTERNAL_LINKER_FLAGS}")
set(LEANC_OPTS_TOML "${LEANC_OPTS} ${LEANC_EXTRA_CC_FLAGS} ${LEANC_INTERNAL_FLAGS}")
set(LINK_OPTS_TOML "${LEANC_INTERNAL_LINKER_FLAGS} -L${CMAKE_BINARY_DIR}/lib/lean ${LEAN_EXTRA_LINKER_FLAGS}")
toml_escape("${LEAN_EXTRA_MAKE_OPTS}" LEAN_EXTRA_OPTS_TOML)
toml_escape("${LEANC_OPTS_TOML}" LEANC_OPTS_TOML)
toml_escape("${LINK_OPTS_TOML}" LINK_OPTS_TOML)
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(LAKE_LIB_PREFIX "lib")
if(${CMAKE_BUILD_TYPE} MATCHES "Debug|Release|RelWithDebInfo|MinSizeRel")
set(CMAKE_BUILD_TYPE_TOML "${CMAKE_BUILD_TYPE}")
else()
set(CMAKE_BUILD_TYPE_TOML "Release")
endif()
if(USE_LAKE AND STAGE EQUAL 1)
configure_file(${LEAN_SOURCE_DIR}/lakefile.toml.in ${LEAN_SOURCE_DIR}/lakefile.toml)
if(USE_LAKE)
configure_file(${LEAN_SOURCE_DIR}/lakefile.toml.in ${CMAKE_BINARY_DIR}/lakefile.toml)
# copy for editing
if(STAGE EQUAL 1)
configure_file(${LEAN_SOURCE_DIR}/lakefile.toml.in ${LEAN_SOURCE_DIR}/lakefile.toml)
endif()
endif()

View File

@@ -6,41 +6,43 @@ Authors: Leonardo de Moura
module
prelude
import Init.Prelude
import Init.Notation
import Init.Tactics
import Init.TacticsExtra
import Init.ByCases
import Init.RCases
import Init.Core
import Init.Control
import Init.Data.Basic
import Init.WF
import Init.WFTactics
import Init.Data
import Init.System
import Init.Util
import Init.Dynamic
import Init.ShareCommon
import Init.MetaTypes
import Init.Meta
import Init.NotationExtra
import Init.SimpLemmas
import Init.PropLemmas
import Init.Hints
import Init.Conv
import Init.Guard
import Init.Simproc
import Init.SizeOfLemmas
import Init.BinderPredicates
import Init.Ext
import Init.Omega
import Init.MacroTrace
import Init.Grind
import Init.GrindInstances
import Init.While
import Init.Syntax
import Init.Internal
import Init.Try
import Init.BinderNameHint
import Init.Task
public import Init.Prelude
public import Init.Notation
public import Init.Tactics
public import Init.TacticsExtra
public import Init.ByCases
public import Init.RCases
public import Init.Core
public import Init.Control
public import Init.WF
public import Init.WFTactics
public import Init.Data
public import Init.System
public import Init.Util
public import Init.Dynamic
public import Init.ShareCommon
public import Init.MetaTypes
public import Init.Meta
public import Init.NotationExtra
public import Init.SimpLemmas
public import Init.PropLemmas
public import Init.Hints
public import Init.Conv
public import Init.Guard
public import Init.Simproc
public import Init.SizeOfLemmas
public import Init.BinderPredicates
public import Init.Ext
public import Init.Omega
public import Init.MacroTrace
public import Init.Grind
public import Init.GrindInstances
public import Init.While
public import Init.Syntax
public import Init.Internal
public import Init.Try
public meta import Init.Try -- make sure `Try.Config` can be evaluated anywhere
public import Init.BinderNameHint
public import Init.Task
public import Init.MethodSpecsSimp
public import Init.LawfulBEqTactics

View File

@@ -7,8 +7,9 @@ Authors: Joachim Breitner
module
prelude
import Init.Prelude
import Init.Tactics
public import Init.Tactics
public section
set_option linter.unusedVariables false in
/--
@@ -37,7 +38,7 @@ This gadget is supported by
* `simp`, `dsimp` and `rw` in the right-hand-side of an equation
* `simp` in the assumptions of congruence rules
It is ineffective in other positions (hyptheses of rewrite rules) or when used by other tactics
It is ineffective in other positions (hypotheses of rewrite rules) or when used by other tactics
(e.g. `apply`).
-/
@[simp , expose]

View File

@@ -6,7 +6,9 @@ Authors: Gabriel Ebner
module
prelude
import Init.NotationExtra
public import Init.NotationExtra
public section
namespace Lean

View File

@@ -6,7 +6,9 @@ Authors: Leonardo de Moura, Mario Carneiro
module
prelude
import Init.Classical
public import Init.Classical
public section
/-! # by_cases tactic and if-then-else support -/
@@ -42,3 +44,10 @@ theorem apply_ite (f : α → β) (P : Prop) [Decidable P] (x y : α) :
/-- A `dite` whose results do not actually depend on the condition may be reduced to an `ite`. -/
@[simp] theorem dite_eq_ite [Decidable P] :
(dite P (fun _ => a) (fun _ => b)) = ite P a b := rfl
-- Remark: dite and ite are "defally equal" when we ignore the proofs.
@[deprecated dite_eq_ite (since := "2025-10-29")]
theorem dif_eq_if (c : Prop) {h : Decidable c} {α : Sort u} (t : α) (e : α) : dite c (fun _ => t) (fun _ => e) = ite c t e :=
match h with
| isTrue _ => rfl
| isFalse _ => rfl

View File

@@ -6,7 +6,9 @@ Authors: Leonardo de Moura, Mario Carneiro
module
prelude
import Init.PropLemmas
public import Init.PropLemmas
@[expose] public section
universe u v
@@ -179,9 +181,6 @@ theorem not_imp_iff_and_not : ¬(a → b) ↔ a ∧ ¬b := Decidable.not_imp_iff
theorem not_and_iff_not_or_not : ¬(a b) ¬a ¬b := Decidable.not_and_iff_not_or_not
@[deprecated not_and_iff_not_or_not (since := "2025-03-18")]
abbrev not_and_iff_or_not_not := @not_and_iff_not_or_not
theorem not_iff : ¬(a b) (¬a b) := Decidable.not_iff
@[simp] theorem imp_iff_left_iff : (b a b) a b := Decidable.imp_iff_left_iff

View File

@@ -6,8 +6,10 @@ Authors: Leonardo de Moura, Mario Carneiro
module
prelude
import Init.Prelude
meta import Init.Prelude
public import Init.Prelude
public meta import Init.Prelude
public section
set_option linter.missingDocs true -- keep it documented
/-!

View File

@@ -6,13 +6,13 @@ Authors: Leonardo de Moura
module
prelude
import Init.Control.Basic
import Init.Control.State
import Init.Control.StateRef
import Init.Control.Id
import Init.Control.Except
import Init.Control.Reader
import Init.Control.Option
import Init.Control.Lawful
import Init.Control.StateCps
import Init.Control.ExceptCps
public import Init.Control.Basic
public import Init.Control.State
public import Init.Control.StateRef
public import Init.Control.Id
public import Init.Control.Except
public import Init.Control.Reader
public import Init.Control.Option
public import Init.Control.Lawful
public import Init.Control.StateCps
public import Init.Control.ExceptCps

View File

@@ -6,8 +6,10 @@ Author: Leonardo de Moura, Sebastian Ullrich
module
prelude
import Init.Core
import Init.BinderNameHint
public import Init.Core
public import Init.BinderNameHint
@[expose] public section
universe u v w
@@ -43,9 +45,6 @@ instance (priority := 500) instForInOfForIn' [ForIn' m ρ α d] : ForIn m ρ α
forIn x b f = forIn' x b (fun x h => binderNameHint x f <| binderNameHint h () <| f x) := by
rfl
@[deprecated forIn_eq_forIn' (since := "2025-04-04")]
abbrev forIn_eq_forin' := @forIn_eq_forIn'
/--
Extracts the value from a `ForInStep`, ignoring whether it is `ForInStep.done` or `ForInStep.yield`.
-/

View File

@@ -6,9 +6,9 @@ Authors: Leonardo de Moura
module
prelude
import Init.Control.State
import Init.Control.Except
import Init.Data.ToString.Basic
public import Init.Data.ToString.Basic
public section
universe u v
namespace EStateM
@@ -17,8 +17,8 @@ variable {ε σ α : Type u}
instance [ToString ε] [ToString α] : ToString (Result ε σ α) where
toString
| Result.ok a _ => "ok: " ++ toString a
| Result.error e _ => "error: " ++ toString e
| Result.ok a _ => String.Internal.append "ok: " (toString a)
| Result.error e _ => String.Internal.append "error: " (toString e)
instance [Repr ε] [Repr α] : Repr (Result ε σ α) where
reprPrec

View File

@@ -8,9 +8,10 @@ The Except monad transformer.
module
prelude
import Init.Control.Basic
import Init.Control.Id
import Init.Coe
public import Init.Control.Basic
public import Init.Control.Id
@[expose] public section
namespace Except
variable {ε : Type u}

View File

@@ -6,7 +6,9 @@ Authors: Leonardo de Moura
module
prelude
import Init.Control.Lawful.Basic
public import Init.Control.Lawful.Basic
public section
/-!
The Exception monad transformer using CPS style.

View File

@@ -8,7 +8,9 @@ The identity Monad.
module
prelude
import Init.Core
public import Init.Core
public section
universe u
@@ -62,4 +64,7 @@ protected def run (x : Id α) : α := x
instance [OfNat α n] : OfNat (Id α) n :=
inferInstanceAs (OfNat α n)
instance {m : Type u Type v} [Pure m] : MonadLiftT Id m where
monadLift x := pure x.run
end Id

Some files were not shown because too many files have changed in this diff Show More