Compare commits

...

1612 Commits

Author SHA1 Message Date
Kim Morrison
66b47a843b feat: deprecate Array.mkArray in favour of Array.replicate 2025-03-24 10:30:32 +11:00
Kim Morrison
cff19d7edf chore: update stage0 2025-03-24 10:25:35 +11:00
Kim Morrison
600b5c5f9c feat: add Array.replicate 2025-03-24 10:21:22 +11:00
Kyle Miller
414ba28cef fix: make pretty printed structure instances hoverable (#7648)
This PR fixes a bug introduced in #7589, causing pretty printed
structure instances to not be hoverable in the Infoview.

This was caused by a choice node being introduced, since `{ $fields,* }`
is ambiguous syntax.
2025-03-23 19:36:13 +00:00
Henrik Böving
d24dfa1031 perf: add a cache to bv_decide's reflection procedure (#7644)
This PR adds a cache to the reflection procedure of bv_decide.

This was motivated by the following profile on QF_BV SMTLIB problem
`sage/app12/bench_3564.smt2`: https://share.firefox.dev/4iTG8KX. After
this change we roughly get a 10x speedup and `simp` is the bottleneck
again: https://share.firefox.dev/4iuezYT
2025-03-23 13:56:00 +00:00
Henrik Böving
f241cc832b perf: bv_decide don't drop the expression level cache (#7636)
This PR makes sure that the expression level cache in bv_decide is
maintained across the entire bitblaster instead of just locally per
BitVec expression.

The PR was split off from the first one (#7606) as this mostly entails
pulling the invariant through and is thus much more mechanical.
2025-03-23 13:05:01 +00:00
Kyle Miller
e663eb1b7a feat: structure autoParam inheritance (#7640)
This PR implements the main logic for inheriting and overriding
autoParam fields in the `structure`/`class` commands, pending being
enabled in the structure instance notation elaborator. Adds term info to
overridden fields, so they now can be hovered over, and "go to
definition" goes to the structure the field is originally defined in.

Implementation notes:
- The inherited autoParams are all recorded in the flat constructor.
Defined/overridden autoParam auxiliary tactic declarations now have
names of the form `StructName.fieldName._autoParam`
- The field `StructureFieldInfo.autoParam?` is soon to be deprecated.
The elaborator is still setting it for now, since the structure instance
notation elaborator is still using it.
2025-03-23 06:04:00 +00:00
Leonardo de Moura
06d6dbff5d feat: model-based theory combination in grind (#7641)
This PR implements basic model-based theory combination in `grind`.
`grind` can now solve examples such as
```lean
example (f : Int → Int) (x : Int)
    : 0 ≤ x → x ≠ 0 → x ≤ 1 → f x = 2 → f 1 = 2 := by
  grind
```
2025-03-23 04:06:09 +00:00
Mac Malone
66e0a5440b refactor: lake: unified configuration (#7504)
This PR augments the Lake configuration data structures declarations
(e.g., `PackageConfig`, `LeanLibConfig`) to produce additional metadata
which is used to automatically generate the Lean & TOML encoders and
decoders via metaprograms.

**Warning:** This refactor should not produce any significant
user-facing breaking changes. However, configurations have been tweaked,
so there is a chance something may have slipped through.

Lake TOML decoding and Lean syntax manipulation utilities have also
undergone significant rework to facilitate this PR. Such utilities are
considered internal and thus little has been done to mitigate possible
downstream breakages.
2025-03-23 02:49:57 +00:00
Lean stage0 autoupdater
7f362c8e8a chore: update stage0 2025-03-23 00:37:25 +00:00
Kyle Miller
cde237daea feat: change structure command to elaborate fields as if structures are flat (#7302)
This PR changes how fields are elaborated in the `structure`/`class`
commands and also makes default values respect the structure resolution
order when there is diamond inheritance. Before, the details of
subobjects were exposed during elaboration, and in the local context any
fields that came from a subobject were defined to be projections of the
subobject field. Now, every field is represented as a local variable.
All parents (not just subobject parents) are now represented in the
local context, and they are now local variables defined to be parent
constructors applied to field variables (inverting the previous
relationship). Other notes:
- The entire collection of parents is processed, and all parent
projection names are checked for consistency. Every parent appears in
the local context now.
- For classes, every parent now contributes an instance, not just the
parents represented as subobjects.
- Default values are now processed according to the parent resolution
order. Default value definition/override auxiliary definitions are
stored at `StructName.fieldName._default`, and inherited values are
stored at `StructName.fieldName._inherited_default`. Metaprograms no
longer need to look at parents when doing calculations on default
values.
- Default value omission for structure instance notation pretty printing
has been updated in consideration of this.
- Now the elaborator generates a `_flat_ctor` constructor that will be
used for structure instance elaboration. All types in this constructor
are put in "field normal form" (projections of parent constructors are
reduced, and parent constructors are eta reduced), and all fields with
autoParams are annotated as such. This is not meant for users, but it
may be useful for metaprogramming.
- While elaborating fields, any metavariables whose type is one of the
parents is assigned to that parent. The hypothesis is that, for the
purpose of elaborating structure fields, parents are fixed: there is
only *one* instance of any given parent under consideration. See the
`Magma` test for an example of this being necessary. The hypothesis may
not be true when there are recursive structures, since different values
of the structure might not agree on parent fields.

Other notes:
- The elaborator has been refactored, and it now uses a monad to keep
track of the elaboration state.
- This PR was motivation for #7100, since we need to be able to make all
parents have consistent projection names when there is diamond
inheritance.

Still to do:
- Handle autoParams like we do default values. Inheritance for these is
not correct when there is diamond inheritance.
- Avoid splitting apart parents if the overlap is only on proof fields.
- Non-subobject parent projections do not have parameter binder kinds
that are consistent with other projections (i.e., all implicit by
default, no inst implicits). This needs to wait on adjustments to the
synthOrder algorithm.
- We could elide parents with no fields, letting their projections be
constant functions. This causes some trouble for defeq checking however
(maybe #2258 would address this).
2025-03-22 22:33:10 +00:00
Henrik Böving
b97a7ef4cb perf: bv_decide introduce an expression level bitblasting cache (#7606)
This PR introduces an expression level bitblasting cache to bv_decide.
2025-03-22 13:25:52 +00:00
Leonardo de Moura
eb0c015e7c perf: quadratic behavior in whnfCore (#7630)
This PR fixes a performance issue in the `whnfCore` procedure.
2025-03-21 22:29:21 +00:00
David Thrane Christiansen
b768e44ba7 doc: further missing docstrings (#7613)
This PR adds a variety of docstrings for names that appear in the
manual.
2025-03-21 22:20:07 +00:00
Lean stage0 autoupdater
385c6db4ce chore: update stage0 2025-03-21 21:12:34 +00:00
David Thrane Christiansen
aef6c6d518 doc: review docstrings for fixed-width integer types (#7602)
This PR adds missing docstrings for fixed-width integer operations and
makes their style consistent.
2025-03-21 20:16:28 +00:00
Sebastian Ullrich
d57cbdfb95 chore: CI: bring back coredump tracing (#7625) 2025-03-21 15:25:45 +00:00
Sebastian Ullrich
7240d910d3 chore: more core proof benchmarks 2025-03-21 15:59:14 +01:00
Joachim Breitner
6931e91bf0 fix: mark Nat.div and Nat.modCore irreducible (#7614)
This PR marks `Nat.div` and `Nat.modCore` as `irreducible`, to recover 
the behavior from from before #7558.

Fixes #7612. H't to @tobiasgrosser for the good bug report.
2025-03-21 14:23:03 +00:00
Sebastian Ullrich
501bd64a89 chore: CI: avoid empty matrix error (#7620) 2025-03-21 13:30:58 +00:00
Marc Huisinga
2b11c8d9a4 chore: bump server version to 0.3.0 (#7624)
This PR bumps the server version so that clients like NeoVim can detect
whether the server supports our recent language server extensions
(modulo the time that has passed since these extension PRs).

I'd like to have server capabilities for this at some point, but this
will have to do for now.
2025-03-21 12:56:59 +00:00
Joachim Breitner
770af38c14 fix: fun_induction: correctly identify params and targets (#7622)
This PR fixes `fun_induction` when used on structurally recursive
functions where there are targets occurring before fixed parameters.

Fixes #7550
2025-03-21 12:12:15 +00:00
Sebastian Ullrich
7b787c81f3 perf: avoid contended access to IO.Ref in isTracingEnabledFor (#7601) 2025-03-21 12:07:25 +00:00
Joachim Breitner
bd01461b5f chore: run awaiting-mathlib.yml on more events (#7621)
so that we can make it a required check
2025-03-21 11:37:35 +00:00
Henrik Böving
1afd678100 perf: handle more symmetries in bv_decide bitblasting (#7617)
This PR adds the known bits optimization from the multiplication circuit
to the add one, allowing us to discover potentially even more symmetries
before going to the SAT solver.
2025-03-21 10:45:06 +00:00
Henrik Böving
677d26a581 refactor: apply fording to BVExpr to enable deriving DecidableEq (#7619)
This PR applies fording to bv_decide's BVExpr type to enable deriving
DecidableEq.
2025-03-21 10:29:04 +00:00
Henrik Böving
f673facdbe feat: add BV_EXTRACT_ADD to bv_decide (#7615)
This PR adds the ADD part of bitwuzlas BV_EXTRACT_ADD_MUL rule to
bv_decide's preprocessor.
2025-03-21 09:31:12 +00:00
Siddharth
9fc991da33 feat: add BV De Morgan's (extended) theorems from Hacker's Delight, 2.1 (#7604)
This PR adds bitvector theorems that to push negation into other
operations, following Hacker's Delight: Ch2.1.
2025-03-21 08:58:18 +00:00
Sebastian Ullrich
3d0f41e323 chore: fix interpreter lean_assert 2025-03-21 09:38:50 +01:00
David Thrane Christiansen
7e1ee70b7c doc: add docstrings for String.drop and String.dropRight (#7607)
This PR adds docstrings for `String.drop` and `String.dropRight`.
2025-03-21 05:38:07 +00:00
Mac Malone
131b458236 chore: lake: revert use of Lake plugin (#7608)
This PR removes the use of the Lake plugin in the Lake build and in
configuration files.

With #7399, the plugin is no longer necessary and may be the source of
some persistent intermittent Lake test failures.
2025-03-21 00:59:43 +00:00
Kim Morrison
74ffa1e413 chore: remove the old Lean.Data.HashMap implementation (#7519)
This PR removes `Lean.Data.HashMap` and `HashSet`. These have been
deprecated for 6 months, replaced by `Std.Data.HashMap` and `HashSet`.
2025-03-20 23:49:55 +00:00
Siddharth
42bbc4b6e2 feat: BitVec.extractLsb'_add_eq (#7595)
This PR implements the addition rewrite from the Bitwuzla rewrite
[BV_EXTRACT_ADD_MUL](e09c50818b/src/rewrite/rewrites_bv.cpp (L1495-L1510)),
which witness that the high bits at `i >= len` do not affect the bits of
the sum upto `len`:

```lean
theorem extractLsb'_add {w len} {x y : BitVec w} (hlen : len ≤ w) : 
    (x + y).extractLsb' 0 len = x.extractLsb' 0 len + y.extractLsb' 0 len
```

---------

Co-authored-by: Luisa Cicolini <48860705+luisacicolini@users.noreply.github.com>
2025-03-20 22:51:21 +00:00
Tobias Grosser
7c62881a95 feat: bv_decide short-circuit a * x = b * x (#6496)
This PR adds short-circuit support to bv_decide to accelerate
multiplications with shared coefficients. In particular, `a * x = b * x`
can be extended to `a = b v (a * x = b * x)`. The latter is faster if `a
= b` is true, as `a = b` may be evaluated without considering the
multiplication circuit. On the other hand, we require the multiplication
circuit, as `a * x = b * x -> a = b` is not always true due to two's
complement wrapping.

We support multiplications through acNF, which takes into account shared
terms across equality canonicalizing `a * (b * c1) = a * (b * c2)` to
`(a * b) * c1 = (a * b) * c2`. As a result, the non-shared terms are
lifted to the top such that canonical rewrites for binary multiplication
with shared terms on the left/right are sufficient.

We add an option `bv_decide +shortCircuit` which controls this feature
(currently disabled by default).

---------

Co-authored-by: Siddharth Bhat <siddu.druid@gmail.com>
Co-authored-by: Henrik Böving <hargonix@gmail.com>
2025-03-20 19:51:53 +00:00
Henrik Böving
c66cb00c0f refactor: turn the AIG framework's RefVec from Array to Vector (#7603)
This PR uses the new `Vector` API inside of the AIG framework's `RefVec`
datatype.
2025-03-20 16:57:04 +00:00
Kyle Miller
c066b5cf1c feat: pretty printing structures, omit default values (#7589)
This PR changes the structure instance notation pretty printer so that
fields are omitted if their value is definitionally equal to the default
value for the field (up to reducible transparancy). Setting
`pp.structureInstances.defaults` to true forces such fields to be pretty
printed anyway.

Closes #1100
2025-03-20 15:32:13 +00:00
Henrik Böving
3221ca1704 fix: interaction of enums and fixedInt in bv_decide (#7596)
This PR fixes an interaction between the enums and fixedInt pass in
bv_decide.

Marked as no changelog as this feature isn't released yet.
2025-03-20 15:12:52 +00:00
David Thrane Christiansen
c279c088c8 doc: review Int docstrings (#7568)
This PR adds missing `Int` docstrings and makes the style of all of them
consistent.
2025-03-20 14:04:56 +00:00
Sebastian Ullrich
086d45f27c perf: interpreter: use global native symbol cache (#7575)
With parallelism, a thread-local cache is not sufficient anymore.
2025-03-20 12:51:27 +00:00
Luisa Cicolini
637d8b2a2d feat: add BitVec.(negOverflow, negOverflow_eq) (#7554)
This PR adds SMT-LIB operators to detect overflow `BitVec.negOverflow`,
according to the [SMTLIB
standard](https://github.com/SMT-LIB/SMT-LIB-2/blob/2.7/Theories/FixedSizeBitVectors.smt2),
and the theorem proving equivalence of such definition with the `BitVec`
library functions (`negOverflow_eq`).

Co-authored by @bollu and @alexkeizer

---------

Co-authored-by: Siddharth <siddu.druid@gmail.com>
2025-03-20 12:43:43 +00:00
David Thrane Christiansen
d8cbf1cefc doc: docstring review for monads and transformers (#7548)
This PR adds missing monad transformer docstrings and makes their style
consistent.

---------

Co-authored-by: Bhavik Mehta <bm489@cam.ac.uk>
2025-03-20 12:18:46 +00:00
Sebastian Ullrich
edbb84d23b chore: CI: USE_LAKE secondary build job (#7505)
As preparation for the module system, and in hopes it will be faster
than and replace the Nix CI. Secondary build jobs do not block merging.

Also makes macOS aarch64 a secondary build job on the PR level, where it
is the current bottleneck.

---------

Co-authored-by: Mac Malone <tydeu@hatpress.net>
2025-03-20 12:16:53 +00:00
Sebastian Ullrich
756fd66745 chore: CI: relax check-stage0 check 2025-03-20 13:16:43 +01:00
David Thrane Christiansen
99f296a2e7 doc: review docstrings for universe lifting operators (#7564)
This PR updates the docstrings for `ULift` and `PLift`, making their
style consistent with the others.
2025-03-20 10:52:48 +00:00
Paul Reichert
d2c35fd39d feat: more tree map lemmas for minKey? (#7556)
This PR provides lemmas about the tree map function `minKey?` and its
interaction with other functions for which lemmas already exist.

---------

Co-authored-by: Paul Reichert <datokrat@users.noreply.github.com>
2025-03-20 10:40:30 +00:00
David Thrane Christiansen
cbfb9e482f doc: review of Nat docstrings (#7552)
This PR adds missing `Nat` docstrings and makes their style consistent.

---------

Co-authored-by: Bhavik Mehta <bm489@cam.ac.uk>
2025-03-20 09:13:36 +00:00
Sebastian Ullrich
1fb4a32c8d fix: avoid follow-up kernel errors (#7570)
Asynchronous elaboration means that constants can exist in the elab
environment while failing to be added to the kernel environment, avoid
the latter by falling back to axioms there
2025-03-20 09:11:25 +00:00
Sebastian Ullrich
f42a28f718 chore: revert "perf: avoid taking mutex on task deactivation" (#7590)
Likely introduced segfaults.

Reverts leanprover/lean4#7572
2025-03-20 07:04:50 +00:00
Mac Malone
160ca476a1 chore: USE_LAKE touchups (#7581)
This PR adds some documentation to the Lean's `lakefile.toml` and makes
a few tweaks required to get `USE_LAKE` working properly on Windows. It
also adds a `stage1-configure` step target so the Lake configuration
files can be generated without performing a build of stage 1. This
enables one to build stage 0 and configure Lake via CMake and then use
Lake instead of CMake to build stage 1.

Partly adapted from #7505.
2025-03-20 06:27:22 +00:00
Lean stage0 autoupdater
17f67df257 chore: update stage0 2025-03-20 05:52:03 +00:00
Mac Malone
10f0adc9f9 feat: lake: thin libraries for static.export (#7586)
This PR changes the `static.export` facet for Lean libraries to produce
thin static libraries.

Static libraries with explicitly exported symbols are only necessary on
Windows (where symbol counts are a concern) and are usually used as part
of local build process and not distributed (as they are in Lean's
build). Thus, it seems reasonable to make them unilaterally thin. They
also need to be thin for the Lean build with Lake.
2025-03-20 04:53:35 +00:00
Mac Malone
a67de7ebda fix: lake: use response files on Windows to avoid CLI length limits (#7576)
This PR changes Lake to produce and use response files on Windows when
building executables and libraries (static and shared). This is done to
avoid potentially exceeding Windows command line length limits.

Closes #4159.
2025-03-20 02:58:10 +00:00
Leonardo de Moura
08af091a1c chore: missing normalization rules for cutsat (#7583) 2025-03-20 01:39:16 +00:00
Leonardo de Moura
22b327f077 test: cutsat (#7582)
Additional tests for cutsat
2025-03-20 00:46:07 +00:00
Leonardo de Moura
497ac70c38 feat: improve cutsat counterexamples (#7579)
This PR improves the counterexamples produced by the cutsat procedure,
and adds proper support for `Nat`. Before this PR, the assignment for an
natural variable `x` would be represented as `NatCast.natCast x`.
2025-03-19 19:27:40 +00:00
Sebastian Ullrich
a5348f4bdc perf: avoid taking mutex on task deactivation (#7572) 2025-03-19 15:59:45 +00:00
Sofia Rodrigues
d7d1754e69 feat: socket support using LibUV (#6683)
This PR introduces TCP socket support using the LibUV library, enabling
asynchronous I/O operations with it.

---------

Co-authored-by: Henrik Böving <hargonix@gmail.com>
Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
2025-03-19 13:54:51 +00:00
Kim Morrison
720f6fca94 chore: fix name of Nat.mul_add_lt_is_or (#7563) 2025-03-19 11:23:03 +00:00
Paul Reichert
a634b96f6d feat: tree map lemmas for minKey? (#7437)
This PR provides (some but not all) lemmas about the tree map function
`minKey?`.
2025-03-19 09:54:33 +00:00
Lean stage0 autoupdater
9821bd9707 chore: update stage0 2025-03-19 10:13:04 +00:00
Kim Morrison
0f781136e7 chore: remove @[simp] from Int.neg_mul and Int.mul_neg (#7559)
This PR removes `@[simp]` from `Int.neg_mul` and `Int.mul_neg`. These
simp lemmas were interfering with normalization of numerals in `simp
+arith`.
2025-03-19 09:21:18 +00:00
Joachim Breitner
41a2e9af19 feat: well-founded recursion: opaque well-foundedness proofs (#5182)
This PR makes functions defined by well-founded recursion use an
`opaque` well-founded proof by default. This reliably prevents kernel
reduction of such definitions and proofs, which tends to be
prohibitively slow (fixes #2171), and which regularly causes
hard-to-debug kernel type-checking failures. This changes renders
`unseal` ineffective for such definitions. To avoid the opaque proof,
annotate the function definition with `@[semireducible]`.
2025-03-19 09:21:04 +00:00
Paul Reichert
bf241f9e86 feat: List.min? lemmas and Option.bind_congr (#7529)
This PR upstreams `bind_congr` from Mathlib and proves that the minimum
of a sorted list is its head and weakens the antisymmetry condition of
`min?_eq_some_iff`. Instead of requiring an `Std.Antisymm` instance,
`min?_eq_some_iff` now only expects a proof that the relation is
antisymmetric *on the elements of the list*. If the new premise is left
out, an autoparam will try to derive it from `Std.Antisymm`, so existing
usages of the theorem will most likely continue to work.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-03-19 07:33:49 +00:00
David Thrane Christiansen
a97813e11f doc: review docstrings for syntax-related operators in manual (#7534)
This PR adds missing `Syntax`-related docstrings and makes the existing
ones consistent in style with the others.
2025-03-19 05:15:05 +00:00
David Thrane Christiansen
1b0168d7b3 doc: docstring review for System and System.FilePath (#7523)
This PR adds missing docstrings and makes docstring style consistent for
`System` and `System.FilePath`.
2025-03-19 05:14:35 +00:00
David Thrane Christiansen
dc57365e95 doc: review docstrings for Thunk (#7528)
This PR makes the docstrings for `Thunk` consistent with the style of
the others.
2025-03-19 05:14:20 +00:00
Leonardo de Moura
174145929f test: omega test suite with grind (#7562)
We have removed tests about `Fin` and `BitVec` since these features are
not supported in `grind` yet.
2025-03-19 02:04:03 +00:00
Mac Malone
75300d30d3 refactor: lake: unified target config declarations (#7543)
This PR unifies the configuration declarations of dynamic targets,
external libraries, Lean libraries, and Lean executables into a single
data type stored in a unified map within a package.

As a side-effect of these changes, auto-completion now also works on an
empty configuration (after the `where`).

**Breaking change:** Users can no longer define multiple targets with
the same name but different kinds (e.g., a Lean executable and a Lean
library both named `foo`). This should not effect most users as the Lake
DSL already discouraged this.
2025-03-19 01:14:02 +00:00
Leonardo de Moura
2946ba04d5 fix: assert that nonlinear Nat terms are nonneg in cutsat (#7561)
This PR fixes the support for nonlinear `Nat` terms in cutsat. For
example, cutsat was failing in the following example
```lean
example (i j k l : Nat) : i / j + k + l - k = i / j + l := by grind
```
because we were not adding the fact that `i / j` is non negative when we
inject the `Nat` expression into `Int`.
2025-03-19 00:52:04 +00:00
Joachim Breitner
3857603dbb feat: Nat.{div,mod} to use fuel, not fix (#7558)
This PR changes the definition of `Nat.div` and `Nat.mod` to use a
structurally recursive, fuel-based implementation rather than
well-founded recursion. This leads to more predicable reduction behavior
in the kernel.

`Nat.div` and `Nat.mod` are somewhat special because the kernel has
native reduction for them when applied to literals. But sometimes this
does not kick in, and the kernel has to unfold `Nat.div`/`Nat.mod` (e.g.
in `lazy_delta_reduction` when there are open terms around). In these
cases we want a well-behaved definition.

We really do not want to reduce proofs in the kernel, which we want to
prevent anyways well-founded recursion (to be prevented by #5182).

Hence we avoid well-founded recursion here, and use a (somewhat
standard) translation to a fuel-based definition.

(If this idiom is needed more often we could even support it in Lean
with `termination_by +fuel <measure>` rather easily.)
2025-03-18 23:08:42 +00:00
Leonardo de Moura
389537cf0e fix: consistent term order in linear integer normalization (#7560)
This PR ensures that we use the same ordering to normalize linear `Int`
terms and relations. This change affects `simp +arith` and `grind`
normalizer.

This consistency is important in the cutsat procedure. We want to avoid
a situation where the cutsat state contains both "atoms":
- `「(NatCast.natCast x + NatCast.natCast y) % 8」`
- `「(NatCast.natCast y + NatCast.natCast x) % 8」`

This was happening because we were using different orderings for
(nested) terms and relations (`=`, `<=`).
2025-03-18 23:04:06 +00:00
Wojciech Rozowski
134d11f1a3 fix: ignore optParams in isNatCmp (#7551)
This PR changes `isNatCmp` to ignore optional arguments annotations,
when checking for `<`-like comparison between elements of `Nat`. That
previously caused `guessLex` to fail when checking termination of a
function, whose signature involved an optional argument of the type
`Nat`.

Closes https://github.com/leanprover/lean4/issues/7458
2025-03-18 21:21:43 +00:00
David Thrane Christiansen
404a931219 doc: review funext docstring (#7535)
This PR revises the docstring for `funext`, making it more concise and
adding a reference to the manual for more details.

This revised docstring is less technical, while still capturing the most
important points of the prior one.
2025-03-18 20:26:36 +00:00
Leonardo de Moura
e288e9266b fix: bad normalization rule in grind, and missing dsimproc (#7553)
This PR removes a bad normalization rule in `grind`, and adds a missing
dsimproc.
2025-03-18 18:32:25 +00:00
Sebastian Ullrich
53fcae031e perf: async optimizations for Init.Data.BitVec.Lemmas (#7546) 2025-03-18 12:56:16 +00:00
Markus Himmel
d66abc0fc0 feat: lemmas about operations on finite unsigned integers (#7484)
This PR adds some lemmas about operations defined on `UIntX`
2025-03-18 10:52:54 +00:00
Markus Himmel
6a202f5acb feat: Nat, Fin and BitVec theorems required for unsigned integers (#7522)
This PR splits off the required theory about `Nat`, `Fin` and `BitVec`
from #7484.
2025-03-18 08:35:02 +00:00
Siddharth
4e83f23955 feat: bv_normalize pass: AC normalization of multiplication (#7461)
This PR introduces a bitvector associativity/commutativity normalization
on bitvector terms of the form `(a * b) = (c * d)` for `a, b, c, d`
bitvectors. This mirrors Bitwuzla's `PassNormalize::process`'s
`PassNormalize::normalize_eq_add_mul`.

For example, `x₁ * (y₁ * z) = x₂ * (y₂ * z)` is normalized to `z * (x₁ *
y₁) = z * (x₂ * y₂)`,
pulling the shared variable `z` to the front on both sides. The PR also
replaces the use of `ac_nf` in the normalization pass of `bv_decide`.

Note that this is based on Bitwuzla's normalizer, and we eventually want
to have support for bitvector addition normalization as well. However,
since we currently lack a `ring` equivalent for bitvectors, we cannot
currently justify rewrites such as `x + x + x → 3 * x`. Similarly, we
leave the implementation of `PassNormalize::normalize_comm_assoc`, which
is called when the toplevel terms are different for a subsequent patch.

For posterity, we record the precise location in Bitwuzla where the
implemented codepath occurs:
```cpp
-- d1f1bc2ad3/src/preprocess/pass/normalize.cpp (L1550-L1554)
        Kind k = cur.kind();
        if (k == Kind::EQUAL && children[0].kind() == children[1].kind()
            && (children[0].kind() == Kind::BV_ADD
                || children[0].kind() == Kind::BV_MUL))
        {
          auto [res, norm] = normalize_eq_add_mul(children[0], children[1]);
          ...
```

---------

Co-authored-by: Henrik Böving <hargonix@gmail.com>
Co-authored-by: Tobias Grosser <github@grosser.es>
2025-03-18 08:28:35 +00:00
David Thrane Christiansen
5d91ed01b7 doc: review String docstrings (#7506)
This PR adds missing `String` docstrings and makes the existing ones
consistent in style.
2025-03-18 04:36:49 +00:00
Kim Morrison
ce138e1cec fix: correct names in library lemmas (#7541)
This PR corrects names of a number of lemmas, where the incorrect name
was identified automatically by a
[tool](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/automatic.20spelling.20generation.20.26.20comparison/near/505760384)
written by @Rob23oba.
2025-03-18 03:50:03 +00:00
Leonardo de Moura
0e598c96c9 feat: add [grind cases eager] Subtype (#7540)
This PR adds `[grind cases eager]` attribute to `Subtype`. See new test.
2025-03-18 01:19:22 +00:00
Leonardo de Moura
dad9b18d49 fix: missing reset at decision stack in cutsat (#7538)
This PR fixes a bug in the cutsat model construction. It was not
resetting the decision stack at the end of the search.
2025-03-18 00:21:56 +00:00
Leonardo de Moura
a638e2e207 feat: Int.toNat and Int.natAbst in cutsat (#7537)
This PR implements support for `Int.natAbs` and `Int.toNat` in the
cutsat procedure.
2025-03-17 23:29:21 +00:00
Leonardo de Moura
a0acbd77ea feat: not divides in cutsat (#7536)
This PR implements support for `¬ d ∣ p` in the cutsat procedure.
2025-03-17 22:29:42 +00:00
Joachim Breitner
a26084c433 refactor: Int.div: avoid using unseal (#7533)
In preparation for #5182 (and arguably good practice anyways).
2025-03-17 20:29:27 +00:00
Leonardo de Moura
798da80459 fix: grind push new fact (#7532)
This PR fixes the procedure for putting new facts into the `grind`
"to-do" list. It ensures the new facts are preprocessed. This PR also
removes some of the clutter in the `Nat.sub` support.
2025-03-17 19:14:08 +00:00
Lean stage0 autoupdater
5513f6a468 chore: update stage0 2025-03-17 19:01:29 +00:00
David Thrane Christiansen
70fb253739 doc: review of Array docstrings for manual (#7492)
This PR adds missing `Array` docstrings and makes their style
consistent.
2025-03-17 18:22:01 +00:00
jrr6
4b406b6d5f chore: remove comment from src/stdlib_flags.h (#7531)
This PR removes a misplaced comment from `src/stdlib_flags.h` introduced
by #7425 that was intended to (ephemerally) go in
`stage0/src/stdlib_flags.h`.
2025-03-17 18:07:58 +00:00
David Thrane Christiansen
1a3614616d doc: review docstrings for IO (#7476)
This PR adds missing docstrings for `IO` and related code and makes the
style of the existing docstrings consistent.
2025-03-17 17:59:44 +00:00
David Thrane Christiansen
c53b0c99de fix: broken docstring examples (#7526)
This PR fixes docstring breakage from #7516.
2025-03-17 17:59:03 +00:00
Henrik Böving
5a5e83c26c refactor: the AIG framework to track negations in a more efficient way (#7381)
This PR refactors the AIG datastructures that underly bv_decide in order
to allow a better tracking of negations in the circuit. This refactor
has two effects, for one adding full constant folding to the AIG
framework and secondly enabling us to add further simplifications from
the Brummayer Biere paper in the future which was previously
architecturally impossible.
2025-03-17 17:33:49 +00:00
Henrik Böving
5e0648fe98 feat: bv_decide rewrites around concat, extract and multplication (#7527)
This PR adds the BV_EXTRACT_CONCAT_LHS_RHS, NORM_BV_ADD_MUL and
NORM_BV_SHL_NEG rewrite from Bitwuzla as well as a reduction from
getLsbD to extractLsb' to bv_decide.
2025-03-17 16:01:15 +00:00
Henrik Böving
49819dad16 perf: Add RefVec.emptyWithCapacity to the AIG framework (#7521)
This PR adds the equivalent of `Array.emptyWithCapacity` to the AIG
framework and applies it to `bv_decide`. This is particularly useful as
we are only working with capacities that are always known at run time so
we should never have to reallocate a `RefVec`.
2025-03-17 13:02:51 +00:00
Luisa Cicolini
594587541c feat: add Bitvec.[(toInt, toFin)_twoPow, toNat_twoPow_of_le, toNat_twoPow_of_lt, toNat_twoPow_eq_ite] (#7225)
This PR contains `BitVec.(toInt, toFin)_twoPow` theorems, completing the
API for `BitVec.*_twoPow`. It also expands the `toNat_twoPow` API with
`toNat_twoPow_of_le`, `toNat_twoPow_of_lt`, as well as
`toNat_twoPow_eq_if` and moves `msb_twoPow` up, as it is used in the
`toInt_msb` proof.

---------

Co-authored-by: Henrik Böving <hargonix@gmail.com>
2025-03-17 12:51:58 +00:00
Siddharth
6df6011641 feat: BitVec.shiftLeft_neg_eq_neg_shiftLeft (#7508)
This PR shows that negation commutes with left shift, which is the
Bitwuzla rewrite
[NORM_BV_SHL_NEG](e09c50818b/src/rewrite/rewrites_bv_norm.cpp (L142-L148)).

```lean
theorem shiftLeft_neg_eq_neg_shiftLeft {x : BitVec w} {y : Nat} :
    (-x) <<< y = - (x <<< y)
```

---------

Co-authored-by: Tobias Grosser <github@grosser.es>
2025-03-17 11:54:43 +00:00
Rob23oba
e77b528ef5 perf: reduce elaboration time and proof size of tree map internals (#7459)
There are several things done here:
1. Use the modified `simp_to_model` which already exists in hash maps.
This version of `simp_to_model` allows specifying the query operations
to use in addition to the modifying operations. This is mostly to
improve elaboration time and actually increases olean size.
2. Instead of proving `toListModel_balance` directly, we write
`toListModel_balanceₘ` and use that instead (this saves ~3 MB).
3. Use `fun_cases` and `dsimp` instead of `rw [x.eq_def]` more
frequently in `Balancing.olean` (this saves a bit over 2 MB).
4. Mark `updateCell` and other functions dependent on it as
`noncomputable`. The main problem with `updateCell` is how other
functions, in particular `glue`, get recursively inlined, which blows
the size of the IR (this saves ~1 MB).
5. Instead of using `simp_to_model` to prove results on `insert!`,
`erase!`, etc., `simpa`s are used now, e.g. `simpa only
[insert_eq_insert!] using isEmpty_insert h`. This mainly improves
elaboration time although the olean size also goes down by ~0.3 MB.
2025-03-17 10:05:49 +00:00
Markus Himmel
6153474c00 feat: Neg instance for unsigned integers (#7487)
This PR adds the instance `Neg UInt8`.

This useful if you want to think about finite unsigned integers as a
commutative ring.
2025-03-17 09:06:14 +00:00
Siddharth
654c3781c4 feat: BitVec.neg_mul_not_eq_add_mul (#7493)
This PR implements the Bitwuzla rewrite rule
[NORM_BV_ADD_MUL](e09c50818b/src/rewrite/rewrites_bv_norm.cpp (L19-L23)),
and the associated lemmas to allow for expedient rewriting:

```lean
theorem neg_add_mul_eq_mul_not {x y : BitVec w} : - (x + x * y) = x * ~~~ y
```

---------

Co-authored-by: Henrik Böving <hargonix@gmail.com>
2025-03-17 08:54:56 +00:00
Kim Morrison
d32a7b250a chore: remove >6 month old deprecations (#7518) 2025-03-17 04:42:05 +00:00
Kim Morrison
53abb99a81 fix: make List/Array modify argument order consistent (#7516)
This PR changes the order of arguments for `List.modify` and
`List.insertIdx`, making them consistent with `Array`.
2025-03-17 04:36:05 +00:00
Leonardo de Moura
e7cde1180b fix: simp +arith (#7515)
This PR fixes another bug in `simp +arith`. This bug was affecting
`grind`. See new test for an example.
2025-03-17 03:11:48 +00:00
Leonardo de Moura
318c782ea7 feat: missing normalization rules for div and mod in grind (#7514)
This PR adds more missing normalization rules for `div` and `mod` to
`grind`.
2025-03-16 23:00:12 +00:00
Leonardo de Moura
0da54f517a fix: missing Nat div and mod norm rules in grind (#7512)
This PR adds missing normalization rules for `Nat` div and mod to the
`grind` tactic.
2025-03-16 21:23:49 +00:00
Leonardo de Moura
1284d43ad7 fix: simp +arith (#7511)
This PR fixes two bugs in `simp +arith` that were preventing specific
subterms from being normalized.
2025-03-16 20:24:51 +00:00
Leonardo de Moura
71b2b67a12 feat: exfalso in grind (#7510)
This PR ensures that `grind` can be used as a more powerful
`contradiction` tactic, sparing the user from having to type `exfalso;
grind` or `intros; exfalso; grind`.
2025-03-16 17:25:19 +00:00
Henrik Böving
84a4e37f1b perf: disable implicitDefEqProofs in bv_decide (#7509)
This PR disables the `implicitDefEqProofs` simp option in the
preprocessor of `bv_decide` in order to account for regressions caused
by #7387.

These regressions were noticed by @abdoo8080 while benchmarking on
SMTLIB:
- 07/03/2025: 30,661 with kernel, 35,153 without kernel
- 14/03/2025: 26,405 with kernel, 35,797 without kernel

I performed testing on a bunch of randomly failing problems from the
regressed set and all of them seem to pass again.

---------

Co-authored-by: Siddharth <siddu.druid@gmail.com>
2025-03-16 14:45:28 +00:00
Henrik Böving
6f16a535f8 perf: speedup bv_decide's LRAT checker by improving input validaton (#7491)
This PR achieves a speed up in bv_decide's LRAT checker by improving its
input validation.

When the LRAT checker works on a clause it needs to know that the clause
has no duplicate literals and is not tautological (i.e. doesn't contain
the same variable in different polarities). Previously this was done
using a naive quadratic algorithm, now we check the property using a
HashMap in linear time. Beyond this there is also a few micro
optimizations.
Together they improve the runtime on the SMTLIB problem
`non-incremental/QF_BV/20210312-Bouvier/vlsat3_a15.smt2` from `1:25.31`
to `1:01.32` minutes (where 39 seconds of this run time are the SAT
solver and thus completely unaffected by the optimization)

Co-authored-by: @JOSHCLUNE

---------

Co-authored-by: JOSHCLUNE <josh.seth.clune@gmail.com>
2025-03-16 14:29:33 +00:00
Leonardo de Moura
6cbb8876d6 feat: Nat.sub in cutsat (#7503)
This PR implements support for `Nat.sub` in cutsat
2025-03-16 03:03:36 +00:00
Leonardo de Moura
ae81567fbe feat: Nat div/mod in cutsat (#7502)
This PR implements support for `Nat` div and mod in the cutsat
procedure.
2025-03-16 00:29:43 +00:00
Leonardo de Moura
b7354aacaa feat: Nat equalities and disequalities in cutsat (#7501)
This PR implements support for `Nat` equalities and disequalities in the
cutsat procedure.
2025-03-15 21:24:04 +00:00
Sebastian Ullrich
1dc3626ff7 perf: remove most remaining async blockers in Init.Data.List.Sublist (#7500) 2025-03-15 15:26:06 +00:00
Sebastian Ullrich
a788e6aa67 perf: remove more async blockers (#7497) 2025-03-15 11:07:04 +00:00
Sebastian Ullrich
0f06393149 chore: USE_LAKE: integrate into CMake (#4466)
With `USE_LAKE=ON`, only linking is now left to the Makefile.

TODO:
* include stage 0 changes in Lake's trace. This is an issue already on
master but prevents us from using this PR to put .oleans in an Actions
cache.
2025-03-15 08:58:01 +00:00
Sebastian Ullrich
141e52685c fix: include async elaboration time in elaboration profile (#7496) 2025-03-15 07:59:03 +00:00
Lean stage0 autoupdater
10b7c4e46e chore: update stage0 2025-03-15 08:02:41 +00:00
Sebastian Ullrich
41c58002f1 feat: enable Elab.async by default (#7485)
...after successful test on Mathlib
2025-03-15 07:24:52 +00:00
Leonardo de Moura
d5f01f2db1 feat: Nat divisibility constraints in cutsat (#7495)
This PR implements support for `Nat` divisibility constraints in the
cutsat procedure.
2025-03-15 03:46:47 +00:00
Leonardo de Moura
c8aae00847 feat: Nat inequalities in cutsat (#7494)
This PR implements support for `Nat` inequalities in the cutsat
procedure.
2025-03-15 00:43:18 +00:00
Siddharth
1bbd2c183b feat: BitVec.extract_Lsb'_append_[ite|of_lt|of_le] (#7482)
This PR implements the
[BV_EXTRACT_CONCAT](6a1a768987/src/rewrite/rewrites_bv.cpp (L1264))
rule from Bitwuzla, which explains how to extract bits from an append.
We first prove a 'master theorem' which has the full case analysis, from
which we rapidly derive the necessary `BV_EXTRACT_CONCAT` theorems:

```lean
theorem extractLsb'_append_eq_ite {v w} {xhi : BitVec v} {xlo : BitVec w} {start len : Nat} :
    extractLsb' start len (xhi ++ xlo) =
    if hstart : start < w
    then
      if hlen : start + len < w
      then extractLsb' start len xlo
      else
        (((extractLsb' (start - w) (len - (w - start)) xhi) ++
            extractLsb' start (w - start) xlo)).cast (by omega)
    else
      extractLsb' (start - w) len xhi

theorem extractLsb'_append_eq_of_lt {v w} {xhi : BitVec v} {xlo : BitVec w}
    {start len : Nat} (h : start + len < w) :
    extractLsb' start len (xhi ++ xlo) = extractLsb' start len xlo

theorem extractLsb'_append_eq_of_le {v w} {xhi : BitVec v} {xlo : BitVec w}
    {start len : Nat} (h : w ≤ start) :
    extractLsb' start len (xhi ++ xlo) = extractLsb' (start - w) len xhi
```

---------

Co-authored-by: Tobias Grosser <github@grosser.es>
2025-03-14 18:25:50 +00:00
Henrik Böving
b55a5b0826 feat: add BitVec.add_neg_mul to bv_decide (#7486)
This PR adds the BitVec.add_neg_mul rule introduced in #7481 to
bv_decide's preprocessor.
2025-03-14 15:28:20 +00:00
Sebastian Ullrich
eeca0ce96b perf: Environment blocker removals from async-proofs branch (#7483) 2025-03-14 13:37:01 +00:00
Siddharth
2cb89823f3 feat: BitVec.BV_ADD_NEG_MUL (#7481)
This PR implements the Bitwuzla rewrites [BV_ADD_NEG_MUL](), and
associated lemmas to make the proof streamlined. ```bvneg (bvadd a
(bvmul a b)) = (bvmul a (bvnot b))```, or spelled as lean:

```lean
theorem neg_add_mul_eq_mul_not {x y : BitVec w} :
    - (x + x * y) = (x * ~~~ y)
```

---------

Co-authored-by: Tobias Grosser <github@grosser.es>
2025-03-14 13:21:17 +00:00
Henrik Böving
297be24c0d feat: bv_decide rewrites around ult, signExtend and extractLsb (#7480)
This PR adds the necessary rewrites for the Bitwuzla rules
BV_ULT_SPECIAL_CONST, BV_SIGN_EXTEND_ELIM, TODO.
2025-03-14 09:55:44 +00:00
Lean stage0 autoupdater
e59f487bf0 chore: update stage0 2025-03-14 08:29:06 +00:00
Sebastian Ullrich
e1d15946f7 feat: elaborate theorem bodies in parallel (#7084)
This PR enables the elaboration of theorem bodies, i.e. proofs, to
happen in parallel to each other as well as to other elaboration tasks.

Specifically, to be eligible for parallel proof elaboration,
* the theorem must not be in a `mutual` block
* `deprecated.oldSectionVars` must not be set
* `Elab.async` must be set (currently defaults to `true` in the language
server, `false` on the cmdline)

To be activated for downstream projects (i.e. in stage 1) pending
further Mathlib validation.
2025-03-14 07:50:42 +00:00
Eric Wieser
5c333d88c0 feat: mark forIn_pure_yield lemmas simp (#7433)
This PR makes `simp` able to simplify basic `for` loops in monads other
than `Id`.

This is some prework for #7352, where the `Id` lemmas will be
deprecated.
2025-03-14 00:28:23 +00:00
Sebastian Ullrich
07ee2eea21 fix: report replay kernel errors as standard diagnostics (#7471)
Avoids panics from follow-up cancellation errors

Fixes #7462
2025-03-13 18:45:46 +00:00
Henrik Böving
af82d75e86 fix: bv_decide don't analyze terms under binders by accident (#7477)
This PR ensures that bv_decide doesn't accidentally operate on terms
underneath binders. As there is currently no binder construct that is in
the supported fragment of bv_decide this changes nothing about the proof
power.

Closes #7475
2025-03-13 16:47:20 +00:00
David Thrane Christiansen
25179352b4 doc: review List docstrings for manual (#7452)
This PR makes the style of all `List` docstrings that appear in the
language reference consistent.

Relies on #7240 for links and example formatting.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2025-03-13 16:10:06 +00:00
David Thrane Christiansen
06c57826ae doc: manual docstring review for smaller namespaces (#7365)
This PR updates docstrings and adds some that are missing.
2025-03-13 16:09:37 +00:00
Sebastian Ullrich
044e3b1b56 fix: heartbeats from realizeConst should be ignored (#7473)
Avoids nondeterministic counting from racing threads
2025-03-13 15:10:29 +00:00
Sebastian Ullrich
96f9ee2a41 feat: allow async elab tasks to contribute to info trees reported to linters and request handlers (#7457)
This PR ensures info tree users such as linters and request handlers
have access to info subtrees created by async elab task by introducing
API to leave holes filled by such tasks.

**Breaking change**: other metaprogramming users of
`Command.State.infoState` may need to call `InfoState.substituteLazy` on
it manually to fill all holes.
2025-03-13 15:09:00 +00:00
Sebastian Ullrich
0f3d426591 chore: fix confusing Environment.replayConsts parameter order (#7472) 2025-03-13 12:35:45 +00:00
Sebastian Ullrich
a014ae1001 fix: make Term.mkAuxName async-compatible (#7468) 2025-03-13 12:24:24 +00:00
Lean stage0 autoupdater
137f559520 chore: update stage0 2025-03-13 11:55:08 +00:00
Siddharth
3d6d51d2c6 feat: BitVec.lt_allOnes (#7465)
This PR adds the theorem:  
```lean
theorem lt_allOnes_iff {x : BitVec w} : x < allOnes w ↔ x ≠ allOnes w
```
to simplify comparisons against `-1#w`. This is a corollary of the
existing lemma:
```lean
theorem allOnes_le_iff {x : BitVec w} : allOnes w ≤ x ↔ x = allOnes w
```
2025-03-13 09:43:17 +00:00
Sebastian Ullrich
3786ad6d0c chore: reset stdlib_flags (#7469)
Changed accidentally at
a2cb435aa1 (diff-83fe8b23d47dfed772cebbb2d0f7809b137482ab0d5c5aea66fb5b8ccefa1898)
2025-03-13 09:40:27 +00:00
Paul Reichert
b16769f5a0 feat: new tree map lemmas for getKey (#7412)
This PR provides lemmas about the tree map that have been introduced to
the hash map in #7289.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-03-13 08:13:18 +00:00
Markus Himmel
4262ea14d6 fix: Repr instance for Int32 (#7467)
This PR fixes the `Repr Int32` instance, which was previously repeating
the `Repr Int16` instance due to a copy-and-paste error.
2025-03-13 06:24:42 +00:00
Kim Morrison
816da7120e feat: cleanup of Int simp lemmas (#7466)
This PR further cleans up simp lemmas for `Int`.
2025-03-13 06:07:19 +00:00
Kim Morrison
38ed354cdb feat: Nat.add_div_of_dvd_add_add_one (#7432)
This PR adds a consequence of `Nat.add_div` using a divisibility
hypothesis.
2025-03-13 05:40:34 +00:00
Kim Morrison
56ac94b591 chore: rename Array.mkEmpty to emptyWithCapacity (#7445)
This PR renames `Array.mkEmpty` to `emptyWithCapacity`. (Similarly for
`ByteArray` and `FloatArray`.)
2025-03-12 23:19:17 +00:00
Lean stage0 autoupdater
b78352ec9d chore: update stage0 2025-03-12 23:48:59 +00:00
Kim Morrison
1feae7abe1 fix: indenting in release notes script (#7326)
This PR updates the release notes script to better indent PR
descriptions.
2025-03-12 23:02:02 +00:00
Kim Morrison
a2cb435aa1 chore: rename HashMap.empty to HashMap.emptyWithCapacity (#7447)
This PR renames `.empty` with `.emptyWithCapacity`. This is a companion
to #7445 for `Array`.
2025-03-12 23:01:18 +00:00
David Thrane Christiansen
c3f61ba3a2 chore: fix typo in test (#7460)
This PR fixes a minor typo in a test.
2025-03-12 16:43:35 +00:00
Siddharth
8850f9e9aa feat: BitVec.signExtend_eq_append_extractLsb' (#7454)
This PR implements the bitwuzla rule
[BV_SIGN_EXTEND_ELIM](https://github.com/bitwuzla/bitwuzla/blob/main/src/rewrite/rewrites_bv.cpp#L3638-L3663),
which rewrites a `signExtend x` as an `append` of the appropriate sign
bits, followed by the bits of `x`.

---------

Co-authored-by: Alex Keizer <alex@keizer.dev>
2025-03-12 15:40:23 +00:00
Pim Otte
2363d2fa87 chore: readd "(kernel)" to kernel error message (#7453)
This PR adds "(kernel)" to the message for the kernel-level application
type mismatch error.

It appears to have been accidentally removed in
b705142ae4.
2025-03-12 11:27:42 +00:00
Lean stage0 autoupdater
d1d2f215ad chore: update stage0 2025-03-12 10:19:24 +00:00
David Thrane Christiansen
eb58f46ce7 feat: language reference links and examples in docstrings (#7240)
This PR adds a canonical syntax for linking to sections in the language
reference along with formatting of examples in docstrings according to
the docstring style guide.


Docstrings are now pre-processed as follows:

* Output included as part of examples is shown with leading line comment
indicators in hovers

* URLs of the form `lean-manual://section/section-id` are rewritten to
links that point at the corresponding section in the Lean reference
manual. The reference manual's base URL is configured when Lean is built
and can be overridden with the `LEAN_MANUAL_ROOT` environment variable.
This way, releases can point documentation links to the correct
snapshot, and users can use their own, e.g. for offline reading.

Manual URLs in docstrings are validated when the docstring is added. The
presence of a URL starting with `lean-manual://` that is not a
syntactically valid section link causes the docstring to be rejected.
This allows for future extensibility to the set of allowed links. There
is no validation that the linked-to section actually exists. To provide
the best possible error messages in case of validation failures,
`Lean.addDocString` now takes a `TSyntax ``docComment` instead of a
string; clients should adapt by removing the step that extracts the
string, or by calling the lower-level `addDocStringCore` in cases where
the docstring in question is obtained from the environment and has thus
already had its links validated.

A stage0 update is required to make the documentation site configurable
at build time and for releases. A local commit on top of a stage0 update
that will be sent in a followup PR includes the configurable reference
manual root and updates to the release checklist.

---------

Co-authored-by: Marc Huisinga <mhuisi@protonmail.com>
2025-03-12 09:17:27 +00:00
Markus Himmel
1a2345b47f chore: rename insert_emptyc_eq to insert_empty_eq (#7451)
This PR renames the member `insert_emptyc_eq` of the `LawfulSingleton`
typeclass to `insert_empty_eq` to conform to the recommended spelling of
`∅` as `empty`.

See also #7447.
2025-03-12 09:14:05 +00:00
Kim Morrison
c1d145e9d7 feat: revision of Nat/Int lemmas (#7435)
This PR reviews the `Nat` and `Int` API, making the interfaces more
consistent.
2025-03-12 05:52:09 +00:00
Kim Morrison
3a308324f6 chore: use notation in favour of .empty functions (#7446)
This PR prefers using `∅` instead of `.empty` functions. We may later
rename `.empty` functions to avoid the naming clash with
`EmptyCollection`, and to better express semantics of functions which
take an optional capacity argument.
2025-03-12 04:22:40 +00:00
Kim Morrison
bc2561f538 chore: better hypothesis for Vector.getElem_take (#7449)
Fixes a problematic hypothesis as reported on zulip: 
[#lean4 > Vector refactor @
💬](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Vector.20refactor/near/500330457).
2025-03-12 04:16:22 +00:00
Kim Morrison
ed89c2611e chore: fix duplicated namespaces (#7448) 2025-03-12 04:14:31 +00:00
Henrik Böving
2952cf81e6 feat: bv_decide rewrites for concatenation and extraction (#7441)
This PR adds the BV_CONCAT_CONST, BV_CONCAT_EXTRACT and ELIM_ZERO_EXTEND
rule from Bitwuzla to bv_decide.
2025-03-11 22:24:05 +00:00
Bhavik Mehta
589eff6187 doc: correct typo in PSigma projection docstrings (#7443)
These docstrings are for PSigma projections, so change them to refer to
PSigma rather than Sigma.
2025-03-11 18:36:24 +00:00
Sebastian Ullrich
7c5b423659 chore: unconditionally re-enable realizeConst (#7334)
To be merged when Mathlib adaption passes
2025-03-11 16:39:17 +00:00
jrr6
b1bd2c931c feat: allow turnstiles anywhere in location sequences (#7431)
This PR changes the syntax of location modifiers for tactics like `simp`
and `rw` (e.g., `simp at h ⊢`) to allow the turnstile `⊢` to appear
anywhere in the sequence of locations.

Closes #2278.
2025-03-11 15:34:40 +00:00
Henrik Böving
ce614bd830 chore: don't run MacOS aarch64 in merge queue (#7439)
This PR skips running MacOS aarch64 CI in merge queue but leaves it
enabled in PR and release CI.
2025-03-11 14:35:10 +00:00
Henrik Böving
1731f2f850 feat: add more constant related rewrites to bv_decide (#7438)
This PR adds the EQUAL_CONST_BV_ADD and BV_AND_CONST rules to
bv_decide's preprocessor.
2025-03-11 13:37:12 +00:00
Siddharth
bfe7b1fb34 feat: BitVec.extractLsb'_append_extractLsb'_eq_extractLsb' (#7427)
This PR implements the bitwuzla rule
[`BV_CONCAT_EXTRACT`](https://github.com/bitwuzla/bitwuzla/blob/main/src/rewrite/rewrites_bv.cpp#L1146-L1176).
This will be used by the bitblaster to simplify adjacent `extract`s
into a single `extract`.

We also implement the negated version of the rule,
which allows adjacent `not (extractLsb' _)` to be simplified into a
single `not (extractLsb' _)`.
2025-03-11 12:27:39 +00:00
Siddharth
0a14ec0978 feat: BitVec.setWidth_eq_append (#7424)
This PR proves Bitwuzla's rule
[`BV_ZERO_EXTEND_ELIM`](6a1a768987/src/rewrite/rewrites_bv.cpp (L4021-L4033)):

```lean
theorem setWidth_eq_append {v : Nat} {x : BitVec v} {w : Nat} (h : v ≤ w) :
    x.setWidth w = ((0#(w - v)) ++ x).cast (by omega) := by
```

We introduce a more general helper lemma for the above:

```lean
theorem setWidth_eq_append_extractLsb' {v : Nat} {x : BitVec v} {w : Nat} :
    x.setWidth w = ((0#(w - v)) ++ x.extractLsb' 0 (min v w)).cast (by omega)
```

---------

Co-authored-by: Tobias Grosser <github@grosser.es>
2025-03-11 12:26:30 +00:00
Henrik Böving
bb47469d1a feat: add simprocs for turning shifts by constants into extracts to bv_decide (#7436)
This PR adds simprocs that turn left and right shifts by constants into
extracts to bv_decide.
2025-03-11 10:09:16 +00:00
Tobias Grosser
e7e57d40c4 feat: add BitVec.[toNat|toFin|toInt]_[sshiftRight|sshiftRight'] (#7104)
This PR adds `BitVec.[toNat|toFin|toInt]_[sshiftRight|sshiftRight']`
plus variants with `of_msb_*`. While at it, we also add
`toInt_zero_length` and `toInt_of_zero_length`. In support of our main
theorem we add `toInt_shiftRight_lt` and `le_toInt_shiftRight`, which
make the main theorem automatically derivable via omega.

We also add four shift lemmas for `Int`: `le_shiftRight_of_nonpos`,
`shiftRight_le_of_nonneg`, `le_shiftRight_of_nonneg`,
`shiftRight_le_of_nonpos`, as well as `emod_eq_add_self_emod`,
`ediv_nonpos_of_nonpos_of_neg `, and`bmod_eq_emod_of_lt `. For `Nat` we
add `shiftRight_le`.

Beyond the lemmas directly needed in the proof, we added a couple more
to ensure the API is complete.

We also fix the casing of `toFin_ushiftRight` and rename `lt_toInt` to
`two_mul_lt_toInt` to avoid `'`-ed lemmas.
2025-03-11 09:51:37 +00:00
Parth Shastri
7c0b72e2c5 fix: make the Subsingleton instance for Squash work for an arbitrary Sort (#7406)
This PR makes the instance for `Subsingleton (Squash α)` work for `α :
Sort u`.

Closes #7405

The fix removes some unused `section`/`variable` commands. They were
mistakenly kept when `EqvGen` was removed in 1d338c4.
2025-03-11 08:41:30 +00:00
Tobias Grosser
8fc8e8ed19 chore: generalize BitVec.toInt_[lt|le]' (#7420)
This PR generalizes `BitVec.toInt_[lt|le]'` to not require `0 < w`.
2025-03-11 06:20:27 +00:00
Kim Morrison
96947280df doc: reference mkEmpty in Array doc-string (#7430)
This PR explains how to use `Array.mkEmpty` to specify the capacity of a
new array, from the `Array` doc-string.
2025-03-10 22:28:22 +00:00
Henrik Böving
0af15f9b1d feat: bv_decide add BV_EXTRACT_FULL preprocessing rule (#7429)
This PR adds the BV_EXTRACT_FULL preprocessing rule from Bitwuzla to
bv_decide.
2025-03-10 22:08:59 +00:00
Lean stage0 autoupdater
dab4908317 chore: update stage0 2025-03-10 22:14:37 +00:00
jrr6
aca1d54514 refactor: add definitions to allow turnstiles anywhere in locations (#7425)
This PR adds definitions that will be required to allow to appear
turnstiles anywhere in tactic location specifiers.

This is the first (pre-stage0 update) half of #6992.
2025-03-10 21:18:00 +00:00
Lean stage0 autoupdater
817772e97b chore: update stage0 2025-03-10 20:18:34 +00:00
Siddharth
af8ec41014 feat: BitVec.extractLsb'_eq_self (#7426)
This PR adds the Bitwuzla rewrite rule
[`BV_EXTRACT_FULL`](6a1a768987/src/rewrite/rewrites_bv.cpp (L1236-L1253)),
which is useful for the bitblaster to simplify `extractLsb'` based
expressions.

```lean
theorem extractLsb'_eq_self (x : BitVec w) : x.extractLsb' 0 w = x
```
2025-03-10 19:16:25 +00:00
Marc Huisinga
51794c384a feat: parallel watchdog requests (#7223)
This PR implements parallel watchdog request processing so that requests
that are processed by the watchdog cannot block the main thread of the
watchdog anymore.

Since this shares the `References` data structure in the watchdog, we
adjust the `References` architecture to use `Std.TreeMap` instead of
`Std.HashMap`, so that updates to the data structure can still be
reasonably fast despite the sharing. This PR also optimizes the
`References` data structure a bit.
2025-03-10 18:46:25 +00:00
jrr6
acfc11ae42 fix: correctly collect let-rec fvars through delayed-assigned mvar (#7304)
This PR fixes an issue where nested `let rec` declarations within
`match` expressions or tactic blocks failed to compile if they were
nested within, and recursively called, a `let rec` that referenced a
variable bound by a containing declaration.

Closes #6927

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2025-03-10 18:13:48 +00:00
Sebastian Ullrich
9d39942189 fix: find realizations from other env branches (#7385) 2025-03-10 18:04:38 +00:00
Joachim Breitner
829522ba55 test: expand f91 test (#7421) 2025-03-10 17:15:54 +00:00
Lean stage0 autoupdater
d538e1cd90 chore: update stage0 2025-03-10 17:45:27 +00:00
Mac Malone
77609dcdc7 feat: lake: config field autocomplete in whitespace (#7393)
This PR adds autocompletion support for Lake configuration fields in the
Lean DSL at the indented whitespace after an existing field.
Autocompletion in the absence of any fields is currently still not
supported.

**Breaking change:** The nonstandard braced configuration syntax now
uses a semicolon `;` rather than a comma `,` as a separator. Indentation
can still be used as an alternative to the separator.
2025-03-10 15:37:39 +00:00
Lean stage0 autoupdater
22b6b49a43 chore: update stage0 2025-03-10 15:29:45 +00:00
Paul Reichert
f3c507ec57 feat: tree map lemmas for modify (#7419)
This PR provides lemmas about the tree map function `modify` and its
interactions with other functions for which lemmas already exist.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-03-10 14:35:24 +00:00
Henrik Böving
e0fa6a1792 feat: bv_decide support enum inductive matches with default branches (#7417)
This PR adds support for enum inductive matches with default branches to
bv_decide.
2025-03-10 14:05:04 +00:00
Eric Wieser
9a435b4f4a feat: lemmas about pure for {List,Array,Vector}.{mapM,foldlM,foldrM,anyM,allM,findM?,findSomeM?} (#7356)
This PR adds lemmas reducing monadic operations with `pure` to the
non-monadic counterparts.
2025-03-10 13:55:17 +00:00
Marc Huisinga
80b1ce8cad fix: language server dropping requests (#7178)
This PR fixes a race condition in the language server that would
sometimes cause it to drop requests and never respond to them when
editing the header of a file. This in turn could cause semantic
highlighting to stop functioning in VS Code, as VS Code would stop
emitting requests when a prior request was dropped, and also cause the
InfoView to become defective. It would also cause import auto-completion
to feel a bit wonky, since these requests were sometimes dropped. This
race condition has been present in the language server since its first
version in 2020.

This PR also reverts the futile fix attempt in #7130.

The specific race condition was that if the file worker crashed or had
to be restarted while a request was in flight in the file worker, then
we wouldn't correctly replay it in our watchdog crash-restart logic.
This PR adjusts this logic to fix this.
2025-03-10 13:45:17 +00:00
Paul Reichert
2ac0e4c061 fix: use getElem instead of get in the statements of hash map lemmas (#7418)
This PR renames several hash map lemmas (`get` -> `getElem`) and uses
`m[k]?` instead of `get? m k` (and also for `get!` and `get`).

BREAKING CHANGE: While many lemmas were renamed and the lemma with the
old signature was simply deprecated, some lemmas were changed without
renaming them. They now use the `getElem` variants instead of `get`.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-03-10 13:31:30 +00:00
Markus Himmel
cdfec6971f feat: remaining lemmas about iterated conversions of finite types (#7414)
This PR adds the remaining lemmas about iterated conversions of finite
type that go through signed or unsigned bounded integers.
2025-03-10 12:58:30 +00:00
Markus Himmel
7365600cf8 feat: BitVec conversion lemmas (#7415)
This PR adds a few lemmas about the interactions of `BitVec` with `Fin`
and `Nat`.
2025-03-10 12:58:13 +00:00
Joachim Breitner
754bab442a feat: omega to abstract its own proofs (#5998)
This PR lets `omega` always abstract its own proofs into an auxiliary
definition. The size of the olean of Vector.Extract goes down from 20MB
to 5MB with this, overall stdlib olean size and build instruction count
go down 5%.

Needs #7362.
2025-03-10 12:39:30 +00:00
Marc Huisinga
4593ff50f0 fix: only log goals accomplished in language server (#7416)
This PR addresses a performance regression noticed at
https://github.com/leanprover/lean4/pull/7366#issuecomment-2708162029.
It also ensures that we also consider the current message log when
logging the goals accomplished message.


`Language.Lean.internal.cmdlineSnapshots` in `Lean.Language.Lean` is
moved to `Lean.internal.cmdlineSnapshots` in `Lean.CoreM` to make the
option available in the elaborator.
2025-03-10 12:17:10 +00:00
Sebastian Ullrich
6ecce365e9 feat: make more constructions async-compatible (#7384) 2025-03-10 09:56:30 +00:00
Paul Reichert
1d17119710 refactor: make DHashMap.Raw.foldRev(M) internal (#7380)
This PR moves `DHashMap.Raw.foldRev(M)` into `DHashMap.Raw.Internal`.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-03-10 09:51:41 +00:00
Paul Reichert
9233d7a4d7 feat: tree map lemmas for alter (#7367)
This PR provides lemmas for the tree map functions `alter` and `modify`
and their interactions with other functions for which lemmas already
exist.

BREAKING CHANGE: The signature of `size_alter` was corrected for all
four hash map types. Instead of relying on the boolean operations
`contains` and `&&` in the if statements, we now use the `Prop`-based
operations `Membership` and `And`.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-03-10 09:42:25 +00:00
Sebastian Ullrich
060e137599 chore: enforce awaiting-mathlib label (#7342) 2025-03-10 09:27:43 +00:00
Markus Himmel
7bfa8f6296 feat: finite type conversions (Nat/Int/Fin/BitVec -> IntX -> *) (#7368)
This PR adds lemmas for iterated conversions between finite types,
starting with something of type `Nat`/`Int`/`Fin`/`BitVec` and going
through `IntX`.
2025-03-10 05:53:41 +00:00
Leonardo de Moura
84c7e5db1f test: cutsat (#7411) 2025-03-10 03:30:36 +00:00
Joachim Breitner
c797525d2a fix: WellFounded preprocessing: use dsimp (#7409)
This PR allows the use of `dsimp` during preprocessing of well-founded
definitions. This fixes regressions when using `if-then-else` without
giving a name to the condition, but where the condition is needed for
the termination proof, in cases where that subexpression is reachable
only by dsimp, but not by simp (e.g. inside a dependent let)

Also fixes some preprocessing lemmas to not be bad simp lemmas (with
lambdas on the LHS, due to dot notation and unfortunate argument order)

This fixes #7408.
2025-03-09 22:19:16 +00:00
Henrik Böving
0714a7150b feat: add more multiplication lemmas to bv_normalize (#7407)
This PR adds rules for `-1#w * a = -a` and `a * -1#w = -a` to
bv_normalize as seen in Bitwuzla's BV_MUL_SPECIAL_CONST.

This allows us to solve 
```lean
example {a : BitVec 32} : a + -1 * a = 0 := by bv_normalize
```
which would previously time out.
2025-03-09 18:14:30 +00:00
Leonardo de Moura
9c36901728 chore: cutsat minor improvements (#7404) 2025-03-09 14:50:55 +00:00
Leonardo de Moura
da2d877019 fix: cutsat conflict resolution bug (#7403) 2025-03-09 03:58:30 +00:00
Mac Malone
ffc7ba0829 chore: lake: revert builtin inits, elabs, & macros (#7399)
This PR reverts the new builtin initializers, elaborators, and macros in
Lake back to non-builtin.

That is, it reverts the significant change of #7171. This is done to
potential solve the intermittent test failures Lake has been
experiencing on `master`, which I suspect may be caused by this change.
2025-03-09 01:52:50 +00:00
Leonardo de Moura
09161f6fdd chore: remove workaround (#7402) 2025-03-09 01:46:17 +00:00
Leonardo de Moura
8dc3c53240 feat: tight inequalities using divisibility constraints in cutsat (#7401)
This PR improves the cutsat model search procedure by tightening
inequalities using divisibility constraints.
2025-03-09 00:23:32 +00:00
Joachim Breitner
dd91d7e2e2 fix: bv_omega to use -implicitDefEqProofs (#7387)
This PR uses `-implicitDefEqProofs` in `bv_omega` to ensure it is not
affected by the change in #7386.

---------

Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
2025-03-09 00:13:14 +00:00
David Thrane Christiansen
599444e27e doc: docstrings for Id (#7204)
This PR adds docstrings for the `Id` monad.
2025-03-08 22:17:32 +00:00
David Thrane Christiansen
1a0d2b6fc1 doc: Char docstring proofreading (#7198)
This PR makes the docstrings in the `Char` namespace follow the
documentation conventions.

---------

Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
2025-03-08 22:17:01 +00:00
Cameron Zwarich
8d0093b43f fix: properly handle scoping of join point candidates in cce (#7398)
This PR fixes a scoping error in the cce (Common Case Elimination) pass
of the old code generator. This pass would create a join point for
common minor premises even if some of those premises were in the bodies
of locally defined functions, which results in an improperly scoped
reference to a join point. The fix is to save/restore candidates when
visiting a lambda.
2025-03-08 18:10:41 +00:00
Leonardo de Moura
d07897fc36 fix: Poly.mul p 0 (#7397)
This PR ensures that `Poly.mul p 0` always returns `Poly.num 0`.
2025-03-08 16:57:13 +00:00
Leonardo de Moura
bfe8e5a958 fix: bug in cutsat model construction (#7396)
This PR fixes a bug in the cutsat model construction. It was searching
for a solution in the wrong direction.
2025-03-08 15:58:20 +00:00
Rob23oba
b9f8a859e7 feat: equivalence on hash maps (#7341)
This PR adds an equivalence relation to the hash map with several lemmas
for it.
2025-03-08 10:44:12 +00:00
Leonardo de Moura
0d3ae7fde5 feat: infrastructure for supporting Nat in cutsat (#7394)
This PR adds infrastructure necessary for supporting `Nat` in the cutsat
procedure. It also makes the `grind` more robust.
2025-03-08 08:36:58 +00:00
David Thrane Christiansen
1bfccf88da doc: add missing Bool docstrings and review existing ones (#7246)
This PR updates existing docstrings for Bool and adds the missing ones.
2025-03-08 08:16:13 +00:00
Leonardo de Moura
565c6f3eb2 fix: if-then-else split + normalization issue in grind (#7392)
This PR fixes an issue in the `grind` tactic when case splitting on
if-then-else expressions.

It adds a new marker gadget that prevents `grind` for re-normalizing the
condition `c` of an if-then-else
expression. Without this marker, the negated condition `¬c` might be
rewritten into
an alternative form `c'`, which `grind` may not recognize as equivalent
to `¬c`.
As a result, `grind` could fail to propagate that `if c then a else b`
simplifies to `b`
in the `¬c` branch.
2025-03-07 23:05:59 +00:00
Henrik Böving
77ae842496 feat: bv_decide remove casts (#7390)
This PR makes bv_decide's preprocessing handle casts, as we are in the
constant BitVec fragment we should be able to always remove them using
BitVec.cast_eq.
2025-03-07 22:40:53 +00:00
Sebastian Ullrich
250b977616 feat: support weak options coming from lake setup-file (#7376)
This PR ensures `weak` options do not have to be repeated in both Lake
`leanOptions` and `moreServerOptions`.
2025-03-07 20:55:53 +00:00
Markus Himmel
a8a5c6cff1 feat: integer prerequisites for finite type lemmas (#7378)
This PR adds lemmas about `Int` that will be required in #7368.

Most notably, we add
```lean
@[simp] theorem neg_nonpos_iff (i : Int) : -i ≤ 0 ↔ 0 ≤ i
```
which causes some breakage but gets us closer to mathlib which has a
more general version of this that applies to `Int`.

Note also that the mathlib adaptation branch deletes the (unused in
mathlib) mathib lemma `Int.zero_le_ofNat` as there is now a
syntactically different (but definitionally equal) `Int.zero_le_ofNat`
in core.
2025-03-07 16:09:03 +00:00
Lean stage0 autoupdater
555f3d86fb chore: update stage0 2025-03-07 15:15:36 +00:00
Marc Huisinga
dc5eb40ca3 feat: 'unsolved goals' & 'goals accomplished' diagnostics (#7366)
This PR adds server-side support for dedicated 'unsolved goals' and
'goals accomplished' diagnostics that will have special support in the
Lean 4 VS Code extension. The special 'unsolved goals' diagnostic is
adapted from the 'unsolved goals' error diagnostic, while the 'goals
accomplished' diagnostic is issued when a `theorem` or `Prop`-typed
`example` has no errors or `sorry`s. The Lean 4 VS Code extension
companion PR is at leanprover/vscode-lean4#585.

Specifically, this PR extends the diagnostics served by the language
server with the following fields:
- `leanTags`: Custom tags that denote the kind of diagnostic that is
being served. As opposed to the `code`, `leanTags` should never be
displayed in the UI. Examples introduced by this PR are a tag to
distinguish 'unsolved goals' errors from other diagnostics, as well as a
tag to distinguish the new 'goals accomplished' diagnostic from other
diagnostics.
- `isSilent`: Whether a diagnostic should not be displayed as a regular
diagnostic in the editor. In VS Code, this means that the diagnostic is
displayed in the InfoView under 'Messages', but that it will not be
displayed under 'All Messages' and that it will also not be displayed
with a squiggly line.

The `isSilent` field is also implemented for `Message` so that silent
diagnostics can be logged in the elaborator. All code paths except for
the language server that display diagnostics to users are adjusted to
filter `Message`s with `isSilent := true`.
2025-03-07 13:50:56 +00:00
Henrik Böving
20571a938b feat: bv_decide support for simple pattern matching on enum inductives (#7329)
This PR adds support to bv_decide for simple pattern matching on enum
inductives. By simple we mean non dependent match statements with all
arms written out.

This PR enables use cases such as:
```lean
namespace PingPong

inductive Direction where
  | goingDown
  | goingUp

structure State where
  val : BitVec 16
  low : BitVec 16
  high : BitVec 16
  direction : Direction

def State.step (s : State) : State :=
  match s.direction with
  | .goingDown =>
    if s.val = s.low then
      { s with direction := .goingUp }
    else
      { s with val := s.val - 1 }
  | .goingUp =>
    if s.val = s.high then
      { s with direction := .goingDown }
    else
      { s with val := s.val + 1 }

def State.steps (s : State) (n : Nat) : State :=
  match n with
  | 0 => s
  | n + 1 => (State.steps s n).step

def Inv (s : State) : Prop := s.low ≤ s.val ∧ s.val ≤ s.high ∧ s.low < s.high

example (s : State) (h : Inv s) (n : Nat) : Inv (State.steps s n) := by
  induction n with
  | zero => simp only [State.steps, Inv] at *; bv_decide
  | succ n ih =>
    simp only [State.steps, State.step, Inv] at *
    bv_decide
```

There is an important thing to consider in this implementation. As the
enums pass can now deal with control flow there is a tension between the
structures and enums pass at play:
1. Enums should run before structures as it could convert matches on
enums into `cond`
chains. This in turn can be used by the structures pass to float
projections into control
   flow which might be necessary.
2. Structures should run before enums as it could reveal new facts about
enums that we might
need to handle. For example a structure might contain a field that
contains a fact about
   some enum. This fact needs to be processed properly by the enums pass

To resolve this tension we do the following:
1. Run the structures pass (if enabled)
2. Run the enums pass (if enabled)
3. Within the enums pass we rerun the part of the structures pass (if
enabled) that could profit from the
enums pass as described above. This comes down to adding a few more
lemmas to a simp
invocation that is going to happen in the enums pass anyway and should
thus be cheap.
2025-03-07 09:23:48 +00:00
Leonardo de Moura
e9f2e1861e feat: cutsat missing case: disequality+inequality+divisibility conflict (#7373)
This PR implements the last missing case for the cutsat procedure and
fixes a bug. During model construction, we may encounter a bounded
interval containing integer solutions that satisfy the divisibility
constraint but fail to satisfy known disequalities.
2025-03-07 01:36:29 +00:00
Leonardo de Moura
905b2eedcd test: cutsat (#7372)
Additional tests for cutsat
2025-03-07 00:31:49 +00:00
Leonardo de Moura
00a4503c4f feat: combine two cutsat proof steps (#7371)
This PR combines two cutsat proof steps that often appear together.
2025-03-06 23:28:49 +00:00
JovanGerb
11aff52fb1 fix: abstractNestedProofs should see into the head of an application (#7353)
This PR changes `abstractNestedProofs` so that it also visits the
subterms in the head of an application.

This oversight caused some definitions in mathlib to have unabstracted
proofs, such as
[CategoryTheory.StructuredArrow.commaMapEquivalenceInverse](https://leanprover-community.github.io/mathlib4_docs/Mathlib/CategoryTheory/Comma/StructuredArrow/CommaMap.html#CategoryTheory.StructuredArrow.commaMapEquivalenceInverse)

Mathlib
[bench](https://github.com/leanprover-community/mathlib4/pull/22613#issuecomment-2704288815):
build instructions -0,166 %
lint instructions -0.72 %

This speedup comes from files containing `CategoryTheory.Functor`, which
contains beta unreduced expressions, where abstracting proofs used to
not happen.

Zulip:
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/dsimp.20simplifies.20proofs.2C.20which.20is.20slow/near/503630173
2025-03-06 20:08:38 +00:00
Leonardo de Moura
ec127a780e feat: simplify cooper case-split proof (#7370)
This PR simplifies the proof term due to the Cooper's conflict
resolution in cutsat.
2025-03-06 19:52:48 +00:00
Leonardo de Moura
b958109d06 feat: let-decls for polynomials in cutsat proof terms (#7369)
This PR uses `let`-declarations for each polynomial occurring in a proof
term generated by the cutsat procedure.
2025-03-06 18:34:26 +00:00
Paul Reichert
d0f4e7c590 feat: tree map lemmas for ofList (#7360)
This PR provides lemmas about the tree map function `ofList` and
interactions with other functions for which lemmas already exist.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-03-06 16:20:52 +00:00
Joachim Breitner
20d191bc8e fix: allow simp dischargers to add aux decls to the environment (#7362)
This PR allows simp dischargers to add aux decls to the environment.
This enables tactics like `native_decide` to be used here, and unblocks
improvements to omega in #5998.

Fixes #7318
2025-03-06 16:00:59 +00:00
Sebastian Ullrich
24db5b598b feat: use realizeConst for all equation, unfold, induction, and partial fixpoint theorems (#7261)
This PR ensures all equation, unfold, induction, and partial fixpoint
theorem generators in core are compatible with parallelism.

Stacked on #7247
2025-03-06 15:38:04 +00:00
Sebastian Ullrich
141e519009 feat: add async support to more extensions and constructions (#7363) 2025-03-06 14:27:45 +00:00
Kim Morrison
c5cec10788 feat: parity between Int.ediv/tdiv/fdiv theorems (#7358)
This PR fills further gaps in the integer division API, and mostly
achieves parity between the three variants of integer division. There
are still some inequality lemmas about `tdiv` and `fdiv` that are
missing, but as they would have quite awkward statements I'm hoping that
for now no one is going to miss them.
2025-03-06 12:04:14 +00:00
Sebastian Ullrich
950ab377c6 fix: remove incorrect Environment.findAsyncCore? shortcut (#7361)
Breaks with parallel elaboration
2025-03-06 11:07:21 +00:00
Paul Reichert
0c898742f6 feat: tree map lemmas for insertMany (#7331)
This PR provides lemmas about the tree map function `insertMany` and its
interaction with other functions for which lemmas already exist. Most
lemmas about `ofList`, which is related to `insertMany`, are not
included.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-03-06 08:54:42 +00:00
Kim Morrison
ca0d822619 chore: protect Int.sub_eq_iff_eq_add (#7359)
Minor problems introduced in #7274.
2025-03-06 05:42:12 +00:00
Kitamado
e2a80875c9 fix: doc in List.removeAll (#7288)
This PR fixes the doc of `List.removeAll`
2025-03-06 05:25:19 +00:00
Leonardo de Moura
061ebe1dca feat: mod and div in cutsat (#7357)
This PR adds support for `/` and `%` to the cutsat procedure.
2025-03-06 04:15:28 +00:00
Leonardo de Moura
7a8c8a4fb3 fix: markNestedProofs (#7355)
This PR fixes a bug in the `markNestedProofs` preprocessor used in the
`grind` tactic.
2025-03-06 00:51:13 +00:00
Leonardo de Moura
3ff10c6cdd test: cutsat cooper resolution (#7354) 2025-03-06 00:40:38 +00:00
Leonardo de Moura
9ae2ac39c9 feat: avoid cooper case analysis for univariate polynomials (#7351)
This PR ensures cutsat does not have to perform case analysis in the
univariate polynomial case. That it, it can close a goal whenever there
is no solution for a divisibility constraint in an interval. Example of
theorem that is now proved in a single step by cutsat:
```lean
example (x : Int) : 100 ≤ x → x ≤ 10000 → 20000 ∣ 3*x → False := by
  grind
```
2025-03-05 20:37:29 +00:00
Wojciech Rozowski
2c8fb9d3fc fix: strip optional parameters when elaborating the termination hints (#7335)
This PR modifies `elabTerminationByHints` in a way that the type of the
recursive function used for elaboration of the termination measure is
striped of from optional parameters. It prevents introducing
dependencies between the default values for arguments, that can cause
the termination checker to fail.

Closes https://github.com/leanprover/lean4/issues/6351.
2025-03-05 18:15:49 +00:00
Henrik Böving
dc7358b4df feat: upgrade cadical to 2.1.2 (#7347)
This PR upgrades the CaDiCal we ship and use for bv_decide to version
2.1.2. Additionally it enables binary LRAT proofs on windows by default
as https://github.com/arminbiere/cadical/issues/112 has been fixed.

Version 2.1.3 is already available but as the Bitwuzla authors [have
pointed out](https://github.com/bitwuzla/bitwuzla/pull/129) one needs to
be careful when upgrading CaDiCal so we just move to a version [they
confirmed](6e93389d86)
is fine for now.
2025-03-05 17:58:58 +00:00
Sebastian Ullrich
44a518b331 fix: never transfer constants from checked environment into elab branches (#7306)
Otherwise we may lose the environment extension state of the constant
2025-03-05 17:12:27 +00:00
Markus Himmel
68f3fc6d5d feat: finite type conversions (Nat/Int/Fin/BitVec -> UIntX -> *) (#7340)
This PR adds lemmas for iterated conversions between finite types which
start with `Nat`/`Int`/`Fin`/`BitVec` and then go through `UIntX`.
2025-03-05 15:35:36 +00:00
Sebastian Ullrich
72c4630aab feat: use realizeConst for all equation and unfold theorems (#7348)
This PR ensures all equation and unfold theorem generators in core are
compatible with parallelism.
2025-03-05 14:56:50 +00:00
Lean stage0 autoupdater
db0abe89cf chore: update stage0 2025-03-05 13:37:40 +00:00
Marc Huisinga
2b44a4f0d9 fix: inlay hint assertion violation when deleting open file (#7346)
This PR fixes an issue where the language server would run into an inlay
hint assertion violation when deleting a file that is still open in the
language server.
2025-03-05 12:40:21 +00:00
Marc Huisinga
72f4098156 feat: combined auto-implicit inlay hint tooltip (#7344)
This PR combines the auto-implicit inlay hint tooltips into a single
tooltip. This works around an issue in VS Code where VS Code fails to
update hovers for tooltips in adjacent inlay hint parts when moving the
mouse.
2025-03-05 12:23:58 +00:00
Marc Huisinga
f0f7c3ff01 fix: inlay hints inserted at wrong position after edit (#7343)
This PR mitigates an issue where inserting an inlay hint in VS Code by
double-clicking would insert the inlay hint at the wrong position right
after an edit.

This bug was originally reported by @plp127 at
https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/v4.2E18.2E0.20-.20inlay.20hints/near/503362330.

The cause of this bug is that when VS Code hasn't yet received a new set
of inlay hints for a new document state, it will happily move around the
displayed inlay hint, but it won't move around any of the other
position-dependent properties of the inlay hint, like the property
describing where to insert the inlay hint. Since we delay responses
after an edit by an edit delay of 3000ms to prevent inlay hint
flickering while typing, the window for this bug is relatively large.

To work around this bug, we now always immediately respond to the first
inlay hint request after an edit with the old state of the inlay hints,
which we already update correctly on edits on the server-side so that we
can serve old inlay hints for parts of the file that are still
in-progress. Essentially, we are just telling VS Code how it should have
moved all position-dependent properties of each inlay hint.

Even with this mitigation, there is still a small window for this bug to
occur, namely the window from an edit to when VS Code receives the old
inlay hints from the server. In practice, this window should be a couple
of milliseconds at most, so I'd hope it doesn't cause many problems.
There's nothing we can do about this in either vscode-lean4 or the
language server, unfortunately.
2025-03-05 12:23:53 +00:00
Kim Morrison
5536281238 feat: force-mathlib-ci label (#7337)
This PR adds support for a `force-mathlib-ci` label, which attempts full
Mathlib CI even if the PR branch is not based off the
`nightly-with-mathlib` branch, or if the relevant
`nightly-testing-YYYY-MM-DD` branch is not present at Batteries or
Mathlib.
2025-03-05 06:36:38 +00:00
Markus Himmel
8de6233326 feat: IntX conversion lemmas (#7274)
This PR adds lemmas about iterated conversions between finite types,
starting with something of type `IntX`.
2025-03-05 06:27:53 +00:00
Leonardo de Moura
f312170f21 feat: cooper resolution in cutsat (#7339)
This PR implements cooper conflict resolution in the cutsat procedure.
It also fixes several bugs in the proof term construction. We still need
to add more tests, but we can already solve the following example that
`omega` fails to solve:
```lean
example (x y : Int) :
    27 ≤ 11*x + 13*y →
    11*x + 13*y ≤ 45 →
    -10 ≤ 7*x - 9*y →
    7*x - 9*y ≤ 4 → False := by
  grind
```
2025-03-05 03:37:45 +00:00
Kim Morrison
6d1bda6ff2 feat: add @[simp] to Int.neg_inj (#7338)
This PR adds @[simp] to `Int.neg_inj`.
2025-03-05 02:53:41 +00:00
Joachim Breitner
f45c19b428 feat: identify more fixed parameters (#7166)
This PR extends the notion of “fixed parameter” of a recursive function
also to parameters that come after varying function. The main benefit is
that we get nicer induction principles.


Before the definition

```lean
def app (as : List α) (bs : List α) : List α :=
  match as with
  | [] => bs
  | a::as => a :: app as bs
```

produced

```lean
app.induct.{u_1} {α : Type u_1} (motive : List α → List α → Prop) (case1 : ∀ (bs : List α), motive [] bs)
  (case2 : ∀ (bs : List α) (a : α) (as : List α), motive as bs → motive (a :: as) bs) (as bs : List α) : motive as bs
```
and now you get
```lean
app.induct.{u_1} {α : Type u_1} (motive : List α → Prop) (case1 : motive [])
  (case2 : ∀ (a : α) (as : List α), motive as → motive (a :: as)) (as : List α) : motive as
```
because `bs` is fixed throughout the recursion (and can completely be
dropped from the principle).

This is a breaking change when such an induction principle is used
explicitly. Using `fun_induction` makes proof tactics robust against
this change.

The rules for when a parameter is fixed are now:

1. A parameter is fixed if it is reducibly defq to the the corresponding
argument in each recursive call, so we have to look at each such call.
2. With mutual recursion, it is not clear a-priori which arguments of
another function correspond to the parameter. This requires an analysis
with some graph algorithms to determine.
3. A parameter can only be fixed if all parameters occurring in its type
are fixed as well.
This dependency graph on parameters can be different for the different
functions in a recursive group, even leading to cycles.
4. For structural recursion, we kinda want to know the fixed parameters
before investigating which argument to actually recurs on. But once we
have that we may find that we fixed an index of the recursive
parameter’s type, and these cannot be fixed. So we have to un-fix them
5. … and all other fixed parameters that have dependencies on them.

Lean tries to identify the largest set of parameters that satisfies
these criteria.

Note that in a definition like
```lean
def app : List α → List α → List α
  | [], bs => bs
  | a::as, bs => a :: app as bs
```
the `bs` is not considered fixes, as it goes through the matcher
machinery.


Fixes #7027
Fixes #2113
2025-03-04 22:26:20 +00:00
Joachim Breitner
e2ee629022 fix: allow aux decls to be generated by decreasing_by tactics (#7333)
This PR allows aux decls (like generated by `match`) to be generated by
decreasing_by tactics.

Fixes #7332.
2025-03-04 18:42:36 +00:00
Sebastian Ullrich
64731b71aa fix: enable realizations for inductives as late as possible (#7336)
Realizations on them were missing access to e.g. `recOn`
2025-03-04 17:57:51 +00:00
Joachim Breitner
23b5baa5ec feat: WF/Fix.lean: only refine fix’s ih for atomic discriminant onlys (#7324)
This PR changes the internal construction of well-founded recursion, to
not change the type of `fix`’s induction hypothesis in non-defeq ways.

Fixes #7322 and hopefully unblocks #7166.
2025-03-04 13:49:01 +00:00
Sebastian Ullrich
f58e893e63 chore: Mathlib fixes (#7327)
* chore: revert changes to Environment.replay 
* chore: disable realizeConst for now when Elab.async is not set
2025-03-04 13:41:30 +00:00
Rob23oba
a856518265 perf: optimize elaboration of HashMap verification files (#7323)
This PR improves the elaboration time of
`Std.Data.DHashMap.Internal.RawLemmas` and
`Std.Data.DHashMap.RawLemmas`.
2025-03-04 13:30:15 +00:00
Joachim Breitner
45806017e5 feat: allow cond to be used in proofs (#7141)
This PR generalizes `cond` to allow the motive to be in `Sort u`, not
just `Type u`.
2025-03-04 12:10:29 +00:00
Paul Reichert
058e63a3d6 feat: tree map lemmas for foldlM, foldl, foldrM and foldr (#7270)
This PR provides lemmas about the tree map functions `foldlM`, `foldl`,
`foldrM` and `foldr` and their interactions with other functions for
which lemmas already exist. Additionally, it generalizes the
`fold*`/`keys` lemmas to arbitrary tree maps, which were previously
stated only for the `DTreeMap α Unit` case.

A later PR will make the hash map functions `fold` and `revFold`
internal and also update their signature to conform to the tree map and
list API. This is out of scope for this PR.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-03-04 11:44:41 +00:00
Kim Morrison
e8e6c4716f chore: copy v4.17.0 release notes from releases/v4.17.0 branch (#7325) 2025-03-04 11:24:51 +00:00
Lean stage0 autoupdater
3ce8c73315 chore: update stage0 2025-03-04 11:40:02 +00:00
Kim Morrison
88edd13642 feat: alignment of Int.ediv/fdiv/tdiv lemmas (#7319)
This PR continues alignment of lemmas about `Int.ediv/fdiv/tdiv`,
including adding notes about "missing" lemmas that do not apply in one
case. Also lemmas about `emod/fmod/tmod`. There's still more to do.
2025-03-04 10:41:01 +00:00
Sebastian Ullrich
c70e614a5b chore: harden use of panics in Lean.Environment (#7321)
* avoid `panic!`s that return `Unit` or some otherwise unused value lest
they get optimized away
* make some fallback values explicit to avoid follow-up errors
* avoid redundant declaration names in panic messages
2025-03-04 10:29:54 +00:00
Joachim Breitner
aa8faae576 feat: allow cond to be used in proofs (stage0 update prep) (#7320)
This PR prepares for #7141.
2025-03-04 10:26:12 +00:00
euprunin
2f8901d6d0 chore: add missing period to grind warning message (#7317)
Co-authored-by: euprunin <euprunin@users.noreply.github.com>
2025-03-04 09:42:17 +00:00
Leonardo de Moura
9ff8c5ac2d feat: cooper conflict resolution in cutsat (#7315)
This PR implements the Cooper conflict resolution in cutsat. We still
need to implement the backtracking and disequality case.
2025-03-04 03:23:14 +00:00
Kyle Miller
48491e5262 chore: re-enable synthesis checkpoint for structure parent elaboration (#7314)
This PR changes elaboration of `structure` parents so that each must be
fully elaborated before the next one is processed.

In particular, it re-adds synthesizing synthetic mvars between
`structure` parents, in the same manner as other fields. This synthesis
step was removed in #5842 because I had thought parents were like type
parameters and would participate in header elaboration, but in the end
it made more sense elaborating parents after the headers are done, since
they're like fields.

We want this enabled because it will help ensure that all the necessary
reductions are done to types of fields as they're added to the
structure.
2025-03-04 02:49:30 +00:00
Leonardo de Moura
9f5cc7262b feat: proof generation for cooper_dvd_left and variants in cutsat (#7312)
This PR implements proof term generation for `cooper_dvd_left` and its
variants in the cutsat procedure for linear integer arithmetic.
2025-03-04 00:40:31 +00:00
Kim Morrison
957beb02bc chore: deprecate Environment.replay; use lean4checker (#7311) 2025-03-04 00:23:36 +00:00
Henrik Böving
017a1f2b94 fix: bv_decide structures pass instantiate mvars (#7309)
This PR fixes a bug where bv_decide's new structure support would
sometimes not case split on all available structure fvars as their type
was an mvar.
2025-03-03 21:27:53 +00:00
Lean stage0 autoupdater
f8f1b2212a chore: update stage0 2025-03-03 20:17:14 +00:00
Sebastian Ullrich
dab6a161bd feat: realizeConst for match equations (#7247)
This PR makes generation of `match` equations and splitters compatible
with parallelism.
2025-03-03 17:18:29 +00:00
Sebastian Ullrich
8e47d29bf9 feat: debug_assert! (#7256)
This PR introduces the `assert!` variant `debug_assert!` that is
activated when compiled with `buildType` `debug`.

---------

Co-authored-by: Mac Malone <tydeu@hatpress.net>
2025-03-03 16:34:44 +00:00
jrr6
e337129108 fix: move auxDeclToFullName to LocalContext to fix name (un)resolution (#7075)
This PR ensures that names suggested by tactics like `simp?` are not
shadowed by auxiliary declarations in the local context and that names
of `let rec` and `where` declarations are correctly resolved in tactic
blocks.

This PR contains the following potentially breaking changes:
* Moves the `auxDeclToFullName` map from `TermElab.Context` to
`LocalContext`.
* Refactors `Lean.Elab.Term.resolveLocalName : Name → TermElabM …` to
`Lean.resolveLocalName [MonadResolveName m] [MonadEnv m] [MonadLCtx m] :
Name → m …`.
* Refactors the `TermElabM` action `Lean.Elab.Term.withAuxDecl` to a
monad-polymorphic action `Lean.Meta.withAuxDecl`.
* Adds an optional `filter` argument to `Lean.unresolveNameGlobal`.

Closes #6706, closes #7073.
2025-03-03 16:10:54 +00:00
Rob23oba
d3eb2fe13c feat: HashMap getKey lemmas (#7289)
This PR adds `getKey_beq`, `getKey_congr` and variants to the hashmap
api.
2025-03-03 15:06:58 +00:00
Markus Himmel
d2239a5770 feat: IntX simprocs (#7228)
This PR adds simprocs to reduce expressions involving `IntX`.
2025-03-03 13:37:57 +00:00
Sebastian Ullrich
a244b06882 feat: use realizeConst for bv_decide helper constants (#7276)
This PR ensures helper constants generated by `bv_decide` are compatible
with parallelism.
2025-03-03 12:36:25 +00:00
Sebastian Ullrich
0a55f4bf36 fix: more realizeConst fixes (#7300)
Found and debugged while working on stage 2 of #7247
2025-03-03 12:10:40 +00:00
Kim Morrison
e7a411a66d chore: begin development cycle for v4.19.0 (#7299) 2025-03-03 11:01:21 +00:00
Henrik Böving
783671261d feat: bv_decide add rewrites around ite + operations (#7298)
This PR adds rewrites to bv_decide's preprocessing that concern
combinations of if-then-else and operation such as multiplication or
negation.
2025-03-03 10:51:19 +00:00
Sebastian Ullrich
01d951c3fc fix: cancel computations within command elaboration as soon as reuse is ruled out (#7241)
The other part of #7175
2025-03-03 10:37:10 +00:00
Eric Wieser
6cf3402f1c perf: use free_sized in mpz.cpp (#6825)
The performance win here is pretty negligible (and of course irrelevant
with the small allocator enabled), but this is consistent with it being
used elsewhere.

Follow-up to #6598
2025-03-03 08:47:15 +00:00
Kyle Miller
e3c6909ad5 chore: reimplement mk_projections in Lean (#7295)
This PR translates `lean::mk_projections` into Lean, adding
`Lean.Meta.mkProjections`. It also puts `hasLooseBVarInExplicitDomain`
back in sync with the kernel version. Deletes
`src/library/constructions/projection.{h,cpp}`.
2025-03-03 01:10:27 +00:00
Sean McLaughlin
255810db64 fix: Float32.ofInt (#7277)
This PR fixes a bug in Float32.ofInt, which previously returned a
Float(64).

Closes https://github.com/leanprover/lean4/issues/7264
2025-03-02 23:22:35 +00:00
Leonardo de Moura
f094652481 fix: Rat.floor and Rat.ceil (#7294)
This PR fixes bugs in `Std.Internal.Rat.floor` and
`Std.Internal.Rat.ceil`.
2025-03-02 22:50:36 +00:00
Leonardo de Moura
3eb07cac44 feat: cooper_right helper theorem for cutsat (#7293)
This PR adds support theorems for the Cooper-Right conflict resolution
rule used in the cutsat procedure. During model construction, when
attempting to extend the model to a variable x, cutsat may find a
conflict that involves two inequalities (the lower and upper bounds for
x). This is a special case of Cooper-Dvd-Right when there is no
divisibility constraint.
2025-03-02 19:21:08 +00:00
Mac Malone
58034bf237 feat: lake: display newest job in monitor (#7291)
This PR changes the Lake job monitor to display the last (i.e., newest)
running/unfinished job rather than the first. This avoids the monitor
focusing too long on any one job (e.g., "Running job computation").
2025-03-02 18:38:23 +00:00
Leonardo de Moura
7ba7ea4e16 feat: helper theorems for cooper_dvd_right (#7292)
This PR adds support theorems for the **Cooper-Dvd-Right** conflict
resolution rule used in the cutsat procedure. During model construction,
when attempting to extend the model to a variable `x`, cutsat may find a
conflict that involves two inequalities (the lower and upper bounds for
`x`) and a divisibility constraint.
2025-03-02 18:09:55 +00:00
Leonardo de Moura
4877e84031 feat: cooper_left helper theorem for cutsat (#7290)
This PR adds support theorems for the **Cooper-Left** conflict
resolution rule used in the cutsat procedure. During model
construction,when attempting to extend the model to a variable `x`,
cutsat may find a conflict that involves two inequalities (the lower and
upper bounds for `x`). This is a special case of Cooper-Dvd-Left when
there is no divisibility constraint.
2025-03-02 16:34:48 +00:00
Henrik Böving
9c47f395c8 refactor: change iff lowering rule in bv_decide (#7287)
This PR uses a better lowering rule for iff in bv_decide's
preprocessing.
2025-03-02 12:20:27 +00:00
Kim Morrison
3f98b4835c chore: add Fin.mk_eq_zero simp lemma (#7286) 2025-03-02 11:11:23 +00:00
Leonardo de Moura
a86145b6bb feat: non-chronological backtracking for cutsat (#7284)
This PR implements non-choronological backtracking for the cutsat
procedure. The procedure has two main kinds of case-splits:
disequalities and Cooper resolvents. This PR focus on the first kind.
2025-03-01 23:19:11 +00:00
dependabot[bot]
c4d3a74f32 chore: CI: bump dawidd6/action-download-artifact from 8 to 9 (#7285)
Bumps
[dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
from 8 to 9.
<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>v9</h2>
<h2>What's Changed</h2>
<ul>
<li>add merge_multiple option by <a
href="https://github.com/timostroehlein"><code>@​timostroehlein</code></a>
in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/327">dawidd6/action-download-artifact#327</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/timostroehlein"><code>@​timostroehlein</code></a>
made their first contribution in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/327">dawidd6/action-download-artifact#327</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v8...v9">https://github.com/dawidd6/action-download-artifact/compare/v8...v9</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="07ab29fd4a"><code>07ab29f</code></a>
add merge_multiple option (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/327">#327</a>)</li>
<li>See full diff in <a
href="https://github.com/dawidd6/action-download-artifact/compare/v8...v9">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=8&new-version=9)](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-03-01 20:47:28 +00:00
Leonardo de Moura
c74865fbe2 feat: helper theorems for cooper_dvd_left (#7279)
This PR adds support theorems for the **Cooper-Dvd-Left** conflict
resolution rule used in the cutsat procedure. During model construction,
when attempting to extend the model to a variable `x`, cutsat may find a
conflict that involves two inequalities (the lower and upper bounds for
`x`) and a divisibility constraint:

```lean
a * x + p ≤ 0
b * x + q ≤ 0
d ∣ c * x + s
```

We apply Cooper's quantifier elimination to produce:

```lean
OrOver (Int.lcm a (a * d / Int.gcd(a * d) c)) fun k =>
     b * p + (-a) * q + b * k ≤ 0 ∧
     a ∣ p + k ∧
     a * d ∣ c * p + (-a) * s + c * k
```

Here, `OrOver` is a "big-or" operator. This PR introduces the following
theorem, which encapsulates the above approach via reflection:

```lean
theorem cooper_dvd_left (ctx : Context) (p₁ p₂ p₃ : Poly) (d : Int) (n : Nat)
    : cooper_dvd_left_cert p₁ p₂ p₃ d n
      → p₁.denote' ctx ≤ 0
      → p₂.denote' ctx ≤ 0
      → d ∣ p₃.denote' ctx
      → OrOver n (cooper_dvd_left_split ctx p₁ p₂ p₃ d) :=
```

For each `0 <= k < n`, we generate the three implied facts using:

```lean
theorem cooper_dvd_left_split_ineq (ctx : Context) (p₁ p₂ p₃ : Poly) (d : Int) (k : Nat) (b : Int) (p' : Poly)
    : cooper_dvd_left_split ctx p₁ p₂ p₃ d k
      → cooper_dvd_left_split_ineq_cert p₁ p₂ k b p'
      → p'.denote ctx ≤ 0

theorem cooper_dvd_left_split_dvd1 (ctx : Context) (p₁ p₂ p₃ : Poly) (d : Int) (k : Nat) (a : Int) (p' : Poly)
    : cooper_dvd_left_split ctx p₁ p₂ p₃ d k
      → cooper_dvd_left_split_dvd1_cert p₁ p' a k
      → a ∣ p'.denote ctx

theorem cooper_dvd_left_split_dvd2 (ctx : Context) (p₁ p₂ p₃ : Poly) (d : Int) (k : Nat) (d' : Int) (p' : Poly)
    : cooper_dvd_left_split ctx p₁ p₂ p₃ d k
      → cooper_dvd_left_split_dvd2_cert p₁ p₃ d k d' p'
      → d' ∣ p'.denote ctx
```

Two helper `OrOver` theorems are used to process the `OrOver`:

```lean
theorem orOver_unsat {p} : ¬ OrOver 0 p

theorem orOver_resolve {n p} : OrOver (n+1) p → ¬ p n → OrOver n p
```

Where `p` is instantiated using `cooper_dvd_left_split ctx p₁ p₂ p₃ d`.
2025-03-01 02:18:12 +00:00
Leonardo de Moura
93a908469c feat: cutsat counterexamples (#7278)
This PR adds counterexamples for linear integer constraints in the
`grind` tactic. This feature is implemented in the cutsat procedure.
2025-02-28 19:05:27 +00:00
Joachim Breitner
903fe29863 chore: release_notes.py: report on all commit types (#7258)
I missed a few that we should not be shy of.
2025-02-28 17:39:18 +00:00
Henrik Böving
84da113355 feat: add all bitwuzla level 1 if rewrites to bv_decide (#7275)
This PR adds all level 1 rewrites from Bitwuzla to the preprocessor of
bv_decide.
2025-02-28 16:04:09 +00:00
Markus Himmel
75df4c0b52 fix: statement of a UIntX conversion lemma (#7273)
This PR fixes the statement of a `UIntX` conversion lemma.
2025-02-28 15:15:58 +00:00
Sebastian Ullrich
ad5a746cdd fix: realizeConst fixes (#7272)
Emerged and fixed while adding more `realizeConst` callers
2025-02-28 14:59:13 +00:00
Paul Reichert
2bd3ce5463 fix: harmonize foldr signature of the tree map with that of List (#7271)
This PR changes the order of arguments of the folding function expected
by the tree map's `foldr` and `foldrM` functions so that they are
consistent with the API of `List`.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-28 14:36:56 +00:00
Henrik Böving
2b752ec245 feat: add IntX and ISize support for bv_decide (#7269)
This PR implements support for `IntX` and `ISize` in `bv_decide`.
2025-02-28 10:33:11 +00:00
Paul Reichert
909ee719aa feat: tree map lemmas for keys and toList (#7260)
This PR provides lemmas about the tree map functions `keys` and `toList`
and their interactions with other functions for which lemmas already
exist. Moreover, a bug in `foldr` (calling `foldlM` instead of `foldrM`)
is fixed.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-28 10:14:13 +00:00
Markus Himmel
7dd5e957da feat: ToExpr IntX (#7268)
This PR implements `Lean.ToExpr` for finite signed integers.
2025-02-28 09:32:30 +00:00
Markus Himmel
d67e0eea47 feat: IntX theory for simprocs and bv_decide (#7259)
This PR contains theorems about `IntX` that are required for `bv_decide`
and the `IntX` simprocs.

A more comprehensive set of theorems about `IntX` will be part of future
PRs.
2025-02-28 07:04:52 +00:00
Kim Morrison
10bfeba2d9 chore: aligning Int.ediv/fdiv/tdiv theorems (#7266)
This PR begins the alignment of `Int.ediv/fdiv/tdiv` theorems.
2025-02-28 05:27:40 +00:00
Leonardo de Moura
4285f8ba05 feat: improve cutsat model search procedure (#7267)
This PR improves the cutsat search procedure. It adds support for find
an approximate rational solution, checks disequalities, and adds stubs
for all missing cases.
2025-02-28 04:26:53 +00:00
Leonardo de Moura
d8be3ef7a8 doc: cutsat procedure (#7262) 2025-02-27 21:15:34 +00:00
Paul Reichert
c924768879 fix: add @[specialize] annotations to helpers used in alter and modify of the hash map (#7245)
This PR adds missing `@[specialize]` annotations to the `alter` and
`modify` functions in `Std.Data.DHashMap.Internal.AssocList`, which are
used by the corresponding hash map functions.

Zulip thread:
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/.60Std.2EHashMap.2Emodify.60.20and.20.60alter.60.20do.20not.20inline.20the.20function

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-27 15:43:05 +00:00
Henrik Böving
c1e76e8976 perf: optimize LRAT trimming in bv_decide (#7257)
This PR improves performance of LRAT trimming in bv_decide.

The underlying idea is taken from LRAT trimming as implemented in
[`lrat-trim`](https://github.com/arminbiere/lrat-trim/t): As we only
filter about half to two thirds of the LRAT proof steps anyway, there is
no need to use tree or hash maps to store information about them and we
can instead use arrays indexed by the proof step directly. This does not
meaningfully increase the amount of memory required but makes the
trimming step basically disappear from profiles, e.g.
`smt/non-incremental/QF_BV/20210312-Bouvier/vlsat3_a72.smt2` [used
to](https://share.firefox.dev/41kJTle) have 8% of its time spent in
trimming [now](https://share.firefox.dev/3QAKI4w) 1.5%.
2025-02-27 13:47:21 +00:00
Paul Reichert
60a9f8e492 feat: well-formedness lemmas for raw tree map operations (#7237)
This PR provides proofs that the raw tree map operations are well-formed
and refactors the file structure of the tree map, introducing new
modules `Std.{DTreeMap,TreeMap,TreeSet}.Raw` and splittting
`AdditionalOperations` into separate files for bundled and raw types.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-27 13:08:41 +00:00
Kim Morrison
604133d189 chore: cleanup of remaining Array-specific material (#7253)
This PR takes Array-specific lemmas at the end of `Array/Lemmas.lean`
(i.e. material that does not have exact correspondences with
`List/Lemmas.lean`) and moves them to more appropriate homes. More to
come.
2025-02-27 10:51:30 +00:00
Kim Morrison
d3781bb787 fix: definition of Min (Option α), and basic lemmas (#7255)
This PR fixes the definition of `Min (Option α)`. This is a breaking
change. This treats `none` as the least element,
so `min none x = min x none = none` for all `x : Option α`. Prior to
nightly-2025-02-27, we instead had `min none (some x) = min (some x)
none = some x`. Also adds basic lemmas relating `min`, `max`, `≤` and
`<` on `Option`.
2025-02-27 10:44:44 +00:00
Sebastian Ullrich
87e8da5230 chore: temporarily disable Elab.async in the server (#7254)
...pending further testing of #7241 post-release
2025-02-27 08:31:54 +00:00
Kim Morrison
727c696d9f chore: add @[simp] to List.getElem_append_left|right (#7216)
Helps with confluence.
2025-02-27 03:01:33 +00:00
Mac Malone
cf2b7f4c1b feat: lake: builtin inits, elabs, & macros for DSL (#7171)
This PR changes the Lake DSL to use builtin elaborators, macros, and
initializers.

This works out of the box for the Lake executable and is supported in
interactive contexts through the Lake plugin.
2025-02-27 02:34:14 +00:00
Leonardo de Moura
cd4383b6f3 feat: refine inequalites using disequalities in cutsat (#7252)
This PR implements inequality refinement using disequalities. It
minimizes the number of case splits cutsat will have to perform.
2025-02-27 01:33:58 +00:00
Cameron Zwarich
0d9859370a fix: make extern decls evaluate as ⊤ instead of ⊥ in LCNF.elimDeadBranches (#6928)
This PR makes extern decls evaluate as ⊤ rather than the default value
of ⊥ in the LCNF elimDeadBranches analysis.
2025-02-27 01:24:47 +00:00
Cameron Zwarich
c292ae2e0e fix: don't create reduced arity LCNF decls with no params (#7086)
This PR makes the arity reduction pass in the new code generator match
the old one when it comes to the behavior of decls with no used
parameters. This is important, because otherwise we might create a
top-level decl with no params that contains unreachable code, which
would get evaluated unconditionally during initialization. This actually
happens when initializing Init.Core built with the new code generator.
2025-02-27 01:23:34 +00:00
Kim Morrison
3113847806 chore: reenable Vector variable name linters (#7251) 2025-02-26 23:59:28 +00:00
Kim Morrison
d275455674 chore: alignment of a List/Array/Vector.reverse lemma (#7250)
Minor lemma alignment missed earlier.
2025-02-26 23:59:06 +00:00
Kim Morrison
a4d10742d3 feat: align List/Array/Vector.any/all theorems (#7249)
This PR completes alignment of theorems about
`List/Array/Vector.any/all`.
2025-02-26 23:53:53 +00:00
Leonardo de Moura
777fba495a feat: cutsat implied equalities (#7248)
This PR implements simple equality propagation in cutsat `p <= 0 -> -p
<= 0 -> p = 0`
2025-02-26 22:52:37 +00:00
Sebastian Ullrich
2e66341f69 feat: Environment.realizeConst (#7076)
This PR introduces the central parallelism API for ensuring that helper
declarations can be generated lazily without duplicating work or
creating conflicts across threads.
2025-02-26 19:32:21 +00:00
Mac Malone
2e44585ce9 fix: set CP_UTF8 on Windows (#7213)
This PR adds `SetConsoleOutputCP(CP_UTF8)` during runtime initialization
to properly display Unicode on the Windows console. This effects both
the Lean executable itself and user executables (including Lake).

Closes #4291.
2025-02-26 18:36:32 +00:00
Leonardo de Moura
e2f0e14b04 feat: disequalities in cutsat (#7244)
This PR adds support for disequalities in the cutsat procedure used in
`grind`.
2025-02-26 17:26:59 +00:00
Henrik Böving
e801dc96ca chore: cleanup non terminal simps in LRAT (#7243)
This PR cleans up non terminal simps in the LRAT checking module.
2025-02-26 15:02:57 +00:00
Henrik Böving
56a3ac1814 feat: bv_decide structure projections and if (#7242)
This PR makes sure bv_decide can work with projections applied to `ite`
and `cond` in its structures pass.
2025-02-26 14:47:44 +00:00
Paul Reichert
6c62f720c8 feat: tree map lemmas for getThenInsertIfNew? (#7229)
This PR provides lemmas for the tree map function `getThenInsertIfNew?`.

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-26 10:29:51 +00:00
Eric Wieser
a57efd0a88 fix: free memory from lib_uv requests (#7151)
This PR fixes a memory leak in `IO.FS.createTempFile`
2025-02-26 07:52:34 +00:00
Paul Reichert
7e2d6e2254 feat: tree map lemmas for the getKey variants and insertIfNew functions (#7221)
This PR provides lemmas about the tree map functions `getKey?`,
`getKey`, `getKey!`, `getKeyD` and `insertIfNew` and their interaction
with other functions for which lemmas already exist.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-26 07:36:28 +00:00
Kim Morrison
4603e1a6ad feat: add Array/Vector.replace (#7235)
This PR adds `Array.replace` and `Vector.replace`, proves the
correspondences with `List.replace`, and reproduces the basic API. In
order to do so, it fills in some gaps in the `List.findX` APIs.
2025-02-26 06:03:45 +00:00
Mac Malone
550d2918b8 feat: Lake plugin w/ USE_LAKE (#7233)
This PR uses the Lake plugin when Lake is built with Lake via
`USE_LAKE`.
2025-02-26 04:05:15 +00:00
Leonardo de Moura
eb5ad2c03a feat: disequality propagation from grind core module to cutsat (#7234)
This PR implements dIsequality propagation from `grind` core module to
cutsat.
2025-02-26 03:34:39 +00:00
Leonardo de Moura
769fe4ebf6 feat: add Grind.mkDiseqProof? (#7231)
This PR implements functions for constructing disequality proofs in
`grind`.
2025-02-25 23:40:07 +00:00
Joachim Breitner
8130fdc474 feat: induction tactic to err on extra targets (#7224)
This PR make `induction … using` and `cases … using` complain if more
targets were given than expected by that eliminator.
2025-02-25 20:53:16 +00:00
Markus Himmel
41bba59868 feat: UIntX conversion lemmas (part 2/2) (#7210)
This PR adds the remaining lemmas about iterated conversions between
finite types starting with something of type `UIntX`.

In the near future, we will add similar lemmas when starting with
something of type `IntX`, `Nat`, `Int`, `BitVec` or `Fin`.
2025-02-25 18:52:17 +00:00
Eric Wieser
115f06c32a fix: missing indents in Try this message (#7191)
This PR fixes the indentation of "Try this" suggestions in widget-less
multiline messages, as they appear in `#guard_msgs` outputs.
2025-02-25 16:55:50 +00:00
Sebastian Ullrich
1e1e17cb35 fix: be consistent in not reporting newlines between trace nodes to info view (#7143)
This PR makes the server consistently not report newlines between trace
nodes to the info view, enabling it to render them on dedicates lines
without extraneous spacing between them in all circumstances.

The info view code will separately need to be adjusted to this new
behavior, until then this change will make adjacent trace node leafs
consistently be rendered *on the same line* if there is sufficient
space. The cmdline should be unaffected in any case.
2025-02-25 16:16:35 +00:00
Paul Reichert
831e8d768b feat: tree map lemmas for get, get! and getD (#7207)
This PR provides lemmas for the tree map functions `get`, `get!` and
`getD` in relation to the other operations for which lemmas already
exist.

Internally, the `simp_to_model` tactic was provided two new simp lemmas
to eliminate some common complications that require `rw`'ing before
using `simp_to_model`. However, it is still necessary to sometimes
`revert` some hypotheses.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-25 15:26:50 +00:00
jrr6
b4b878b2d0 fix: prevent exact? and apply? from suggesting invalid tactics (#7192)
This PR prevents `exact?` and `apply?` from suggesting tactics that
correspond to correct proofs but do not elaborate, and it allows these
tactics to suggest `expose_names` when needed.

These tactics now indicate that a non-compiling term was generated but
do not suggest that that term be inserted. `exact?` also no longer
suggests that the user try `apply?` if no partial suggestions were
found.

This addresses part of #5407 but does not achieve the exact expected
behavior therein (due to #6122).
2025-02-25 15:24:09 +00:00
Paul Reichert
2377f35426 fix: replace the compare_self simp lemma with a less generic one (#7222)
This PR removes the `simp` attribute from `ReflCmp.compare_self` because
it matches arbitrary function applications. Instead, a new `simp` lemma
`ReflOrd.compare_self` is introduced, which only matches applications of
`compare`.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-25 10:08:23 +00:00
Lean stage0 autoupdater
c7f706baeb chore: update stage0 2025-02-25 08:57:53 +00:00
Cameron Zwarich
c3402b85ab fix: make the stage2 Leanc build use stage2 oleans rather than stage1 oleans (#7190)
This PR makes the stage2 Leanc build use the stage2 oleans rather than
stage1 oleans. This was happening because Leanc's own OLEAN_OUT is at
the build root rather than the lib/lean subdirectory, so when the build
added this OLEAN_OUT to LEAN_PATH no oleans were found there and the
search fell back to the stage1 installation location.
2025-02-25 06:20:50 +00:00
Mac Malone
a68b986616 feat: lake: compute jobs asynchronously (#7211)
This PR changes the job monitor to perform run job computation itself as
a separate job. Now progress will be reported eagerly, even before all
outstanding jobs have been discovered. Thus, the total job number
reported can now grow while jobs are still being computed (e.g., the `Y`
in `[X/Y[` may increase).
2025-02-25 04:03:17 +00:00
Leonardo de Moura
a2dc17055b feat: missing cases for equality propagation from core to cutsat (#7220)
This PR implements the missing cases for equality propagation from the
`grind` core to the cutsat module.
2025-02-25 01:09:05 +00:00
Kim Morrison
c9c85c7d83 chore: List.leftpad typo (#7219) 2025-02-25 00:53:37 +00:00
Kim Morrison
d615e615d9 chore: align List.dropLast/Array.pop lemmas (#7208)
This PR aligns lemmas for `List.dropLast` / `Array.pop` / `Vector.pop`.
2025-02-25 00:13:00 +00:00
Leonardo de Moura
a84639f63e feat: improve equality support in cutsat (#7217)
This PR improves the support for equalities in cutsat.
2025-02-24 23:35:04 +00:00
Kim Morrison
d9ab758af5 chore: re-enable List variable linter (#7215)
Turns back on the variable names linters across List/Array/Vector.
2025-02-24 23:34:01 +00:00
Leonardo de Moura
5cbeb22564 feat: add ForIn instance for PHashSet (#7214)
This PR adds a `ForIn` instance for the `PersistentHashSet` type.
2025-02-24 20:37:45 +00:00
Tobias Grosser
77e0fa4efe chore: use getElem in RHS of getElem theorems (#7187)
This PR moves the RHS of getElem theorems to use getElem. This is a
cleanup after the recent move to getElem as simp normal form.

We also turn `((!decide (i < n)) && getLsbD x (i - n))` into `if h' : i
< n then false else x[i - n]` to preserve the bounds, but keep the
decide if the dependent if is not needed to maintain a getElem on the
RHS.
2025-02-24 18:32:48 +00:00
Mac Malone
69efb78319 fix: lake: MSYS2 OSTYPE change (#7209)
This PR fixes broken Lake tests on Windows' new MSYS2. As of MSYS2
0.0.20250221, `OSTYPE` is now reported as `cygwin` instead of `msys`,
which must be accounted for in a few Lake tests.

See https://www.msys2.org/news/#2025-02-14-moving-msys2-closer-to-cygwin
for more details.
2025-02-24 17:10:13 +00:00
Luisa Cicolini
32a9392a11 feat: add BitVec.toFin_abs (#7206)
This PR adds theorem `BitVec.toFin_abs`, completing the API for
`BitVec.*_abs`.

---------

Co-authored-by: Tobias Grosser <github@grosser.es>
2025-02-24 17:02:51 +00:00
Paul Reichert
af741abbf5 feat: TreeMap lemmas for 'get?' (#7167)
This PR provides tree map lemmas for the interaction of `get?` with the
other operations for which lemmas already exist.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-24 15:34:37 +00:00
Markus Himmel
36723d38b9 feat: UIntX conversion lemmas (part 1/n) (#7174)
This PR adds the first batch of lemmas about iterated conversions
between finite types starting with something of type `UIntX`.
2025-02-24 12:48:37 +00:00
Kim Morrison
3ebce4e190 feat: align lemmas about List.getLast(!?) with Array/Vector.back(!?) (#7205)
This PR completes alignment of
`List.getLast`/`List.getLast!`/`List.getLast?` lemmas with the
corresponding lemmas for Array and Vector.
2025-02-24 11:48:43 +00:00
Paul Reichert
c934e6c247 feat: tree map lemmas about containsThenInsert(IfNew) (#7165)
This PR provides tree map lemmas about the interaction of
`containsThenInsert(IfNew)` with `contains` and `insert(IfNew)`.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-24 09:01:45 +00:00
Eric Wieser
57c8ab269b feat: allow line-wrapping when printing DiscrTree.Keys (#7200)
This PR allows the debug form of DiscrTree.Key to line-wrap.
2025-02-24 07:52:47 +00:00
Leonardo de Moura
e7dc0d31f4 feat: improve support for equations in cutsat (#7203)
This PR improves the support for equalities in cutsat. It also
simplifies a few support theorems used to justify cutsat rules.
2025-02-24 04:48:14 +00:00
Leonardo de Moura
1819dc88ff feat: cutsat relevant-term internalization (#7202)
This PR adds support for internalizing terms relevant to the cutsat
module. This is required to implement equality propagation.
2025-02-24 01:49:51 +00:00
Kim Morrison
e1fade23ec feat: align List/Array/Vector.leftpad (#7201)
This PR adds `Array/Vector.left/rightpad`. These will not receive any
verification theorems; simp just unfolds them to an `++` operation.
2025-02-24 01:39:01 +00:00
Kim Morrison
27e1391e6d feat: complete comparison theorems for ediv/tdiv/fdiv and emod/tmod/fmod (#7199)
This PR adds theorems comparing `Int.ediv` with `tdiv` and `fdiv`, for
all signs of arguments. (Previously we just had the statements about the
cases in which they agree.)
2025-02-24 01:01:40 +00:00
Kim Morrison
da32bdd79c chore: additional newline before 'additional diagnostic information' message (#7169)
This PR adds an addition newline before the "Additional diagnostic
information may be available using the `set_option ... true` command."
messages, to provide better visual separation from the main error
message.
2025-02-23 23:27:33 +00:00
Kyle Miller
b863ca9ae9 chore: post-#7100 cleanup (#7196)
This PR does some stage0 cleanup after #7100, and enables a warning when
the old `structure S extends P : Type` syntax is used. It also updates
the library to put resulting types in the new correct place (`structure
S : Type extends P`).

The `structure` elaborator also has some additional docstrings, and
`StructFieldKind.fromParent` is renamed to
`StructFieldKind.fromSubobject`.
2025-02-23 22:46:22 +00:00
euprunin
c3b01fbd53 doc: remove Trepplein example (Lean 3) (#7197)
This PR removes a reference to Trepplein (Lean 3) in the documentation.

Co-authored-by: euprunin <euprunin@users.noreply.github.com>
2025-02-23 21:39:45 +00:00
Leonardo de Moura
ad1e04c826 feat: simp diagnostics in grind (#6902)
This PR ensures `simp` diagnostic information in included in the `grind`
diagnostic message.
2025-02-23 17:55:17 +00:00
Leonardo de Moura
c8dc66b6c1 feat: helper theorems for solving equality in cutsat (#7194)
This PR adds support theorems for solving equality in cutsat.
2025-02-23 03:26:12 +00:00
Leonardo de Moura
d234b78cc0 chore: cutsat equality infrastructure (#7193)
This PR adds basic infrastructure for adding support for equalities in
cutsat.
2025-02-23 02:27:53 +00:00
Leonardo de Moura
1ae084b5f8 chore: cutsat cleanup (#7189)
This PR also removes unnecessary `mkExpectedTypeHint`s.
2025-02-22 18:35:02 +00:00
Leonardo de Moura
ddeb5ac535 refactor: cutsat (#7186)
This PR simplifies the proofs and data structures used by cutsat.
2025-02-22 17:25:42 +00:00
Sebastian Ullrich
6ff5c4c278 chore: don't forget about namespace reservation for async-unsupported constant kinds (#6987) 2025-02-22 16:45:40 +00:00
Sebastian Ullrich
087f0b4a69 perf: optimize sorry detection in unused variables linter (#7129)
This PR optimizes the performance of the unused variables linter in the
case of a definition with a huge `Expr` representation
2025-02-22 16:43:39 +00:00
Marc Huisinga
a7bdc55244 fix: inlay hint race conditions (#7188)
This PR fixes several inlay hint race conditions that could result in a
violation of the monotonic progress assumption, introduced in #7149.

Specifically:
- In rare circumstances, it could happen that stateful LSP requests were
executed out-of-order with their `didChange` handlers, as both requests
and the `didChange` handlers waited on `lake setup-file` to complete,
with the latter running those handlers in a dedicated task afterwards.
This meant that a request could be added to the stateful LSP handler
request queue before the corresponding `didChange` call that actually
came before it. This PR resolves this issue by folding the task that
waits for `lake setup-file` into the `RequestContext`, which ensures
that we only need to wait for it when actually executing the request
handler.
- While #7164 fixed the monotonic progress assertion violation that was
caused by `$/cancelRequest`, it did not account for our internal notion
of silent request cancellation in stateful LSP requests, which we use to
cancel the inlay hint edit delay when VS Code fails to emit a
`$/cancelRequest` notification. This issue is resolved by always
producing the full finished prefix of the command snapshot queue, even
on cancellation. Additionally, this also fixes an issue where in the
same circumstances, the language server could produce an empty inlay
hint response when a request was cancelled by our internal notion of
silent request cancellation.
- For clients that use `fullChange` `didChange` notifications (e.g. not
VS Code), we would get several aspects of stateful LSP request
`didChange` state handling wrong, which is also addressed by this PR.
2025-02-22 16:35:30 +00:00
Cameron Zwarich
647573d269 feat: support LEAN_BACKTRACE on macOS (#7184)
This PR adds support for LEAN_BACKTRACE on macOS. This previously only
worked with glibc, but it can not be enabled for all Unix-like systems,
since e.g. Musl does not support it.
2025-02-22 15:29:37 +00:00
Sebastian Ullrich
788a7ec502 test: avoid re-elaboration of interactive runner (#7177)
Before/after:
```
make -C build/release test ARGS="-j$(nproc) -R interactive"  208.10s user 20.93s system 1982% cpu 11.552 total
make -C build/release test ARGS="-j$(nproc) -R interactive"  87.22s user 22.58s system 1454% cpu 7.548 total
```
2025-02-22 10:36:25 +00:00
Mac Malone
3aef45c45b fix: lake: setup-file on an invalid Lean config (#7182)
This PR makes `lake setup-file` succeed on an invalid Lean configuration
file.

The server will disable interactivity if `setup-file` fails. When
editing the workspace configuration file, this behavior has the prior
effect of making the configuration file noninteractive if saved with an
invalid configuration.
2025-02-22 04:48:48 +00:00
Leonardo de Moura
1f5c66db79 feat: improve cutsat model search procedure (#7183)
This PR improves the cutsat model search procedure.
2025-02-21 23:51:53 +00:00
Sebastian Ullrich
d42d6c5246 fix: do not cancel async elaboration tasks (#7175)
This PR fixes an `Elab.async` regression where elaboration tasks are
cancelled on document edit even though their result may be reused in the
new document version, reporting an incomplete result.

While this PR fixes the functional regression, it does so as an
over-approximation by never cancelling such tasks. A follow-up PR will
implement the correct behavior of only cancelling the tasks that are not
reused.
2025-02-21 17:24:36 +00:00
Leonardo de Moura
d1aba29b57 feat: model construction for divisibility constraints in cutsat (#7176)
This PR implements model construction for divisibility constraints in
the cutsat procedure.
2025-02-21 16:17:32 +00:00
Johannes Tantow
0c35ca2e39 feat: verify fold/for variants for Hashmaps (#7137)
This PR verifies the various fold and for variants for hashmaps.

---------

Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
2025-02-21 16:08:33 +00:00
Sebastian Ullrich
6e77bee098 feat: Elab.Deriving trace on applyDerivingHandlers (#7173)
This PR introduces a trace node for each deriving handlers invocation
for the benefit of `trace.profiler`
2025-02-21 09:27:41 +00:00
Mac Malone
1ee21c17fc feat: use Lake plugin for Lake imports (#7157)
This PR changes `lake setup-file` to now use Lake as a plugin for files
which import Lake (or one of its submodules). Thus, the server will now
load Lake as a plugin when editing a Lake configuration written in Lean.
This further enables the use of builtin language extensions in Lake.
2025-02-21 05:07:13 +00:00
Mac Malone
aea58113cb feat: run setup-file on lakefiles (#7153)
This PR changes the server to run `lake setup-file` on Lake
configuration files (e.g., `lakefile.lean`).

This is needed to support Lake passing the server its own Lake plugin to
load when elaborating the configuration file.
2025-02-21 04:04:10 +00:00
Mac Malone
36c798964e feat: staged CMake build with Lake as a plugin (#6929)
This PR passes the shared library of the previous stage's Lake as a
plugin to the next stage's Lake in the CMake build. This enables Lake to
use its own builtin elaborators / initializers at build time.
2025-02-21 04:03:50 +00:00
Kim Morrison
6c609028b3 feat: upgrade Int.tdiv_eq_ediv to an unconditional equivalence (#7163)
This PR gives an unconditional theorem expressing `Int.tdiv` in terms of
`Int.ediv`, not just for non-negative arguments.
2025-02-20 23:46:11 +00:00
Paul Reichert
a3a99d3875 feat: more tree map lemmas about empty, isEmpty, contains, size, insert, erase (#7161)
This PR adds all missing tree map lemmas about the interactions of the
functions `empty`, `isEmpty`, `contains`, `size`, `insert(IfNew)` and
`erase`.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-20 15:33:41 +00:00
Marc Huisinga
970732ea11 fix: inlay hint assertion violation (#7164)
This PR fixes an assertion violation introduced in #7149 where the
monotonic progress assumption was violated by request cancellation.
2025-02-20 13:03:44 +00:00
Kim Morrison
2eb478787f chore: split Int.DivModLemmas into Bootstrap and Lemmas (#7162)
This PR splits `Int.DivModLemmas` into a `Bootstrap` and `Lemmas` file,
where it is possible to use `omega` in `Lemmas`.

I'm going to add more theory, particularly about `fdiv` and `tdiv` to
the `Lemmas` file, and would prefer to have access to `omega`.
2025-02-20 12:05:09 +00:00
Marc Huisinga
b49ec19167 feat: more robust server parallelism (#7087)
This PR ensures that all tasks in the language server either use
dedicated tasks or reuse an existing thread from the thread pool. This
ensures that elaboration tasks cannot prevent language server tasks from
being scheduled. This is especially important with parallelism right
around the corner and elaboration becoming more likely to starve the
language server of computation, which could drive up language server
latencies significantly on machines with few cores.

Specifically, all language server tasks are refactored to use a new thin
`ServerTask` API wrapper with a single "costly" vs "cheap" dimension,
where costly tasks are always scheduled as dedicated tasks, and cheap
tasks are always made to either run on the calling thread or to reuse
the thread of the task being mapped on by using the `sync` flag.

ProofWidgets4 adaption PR:
https://github.com/leanprover-community/ProofWidgets4/pull/106

### Other changes
- This PR makes several tasks dedicated that weren't dedicated before,
and uses `sync := true` for some others. The rules for this are
described in the module docstring of `ServerTask.lean`.
- Most notably, the reporting task in the file worker was *not* a
dedicated task before this PR, which could easily lead to thread pool
starvation on successive changes. It also did not support cancellation.
This PR ensures that it does.

### Breaking changes

- `RequestTask` and the request-oriented snapshot API are refactored to
use `ServerTask` instead of `Task`. All functions in `Task` have close
analogues in `ServerTask`, and functions on `RequestTask` now need to
distinguish between whether a `map` or a `bind` is cheap or costly. This
affects all downstream users of `RequestM`, e.g. tools that extend the
language server with their own requests, or some users of the RPC
mechanism.
- The following unused functions of the `AsyncList` API have been
deleted: `append`, `unfoldAsync`, `getAll`, `waitHead?`, `cancel`
2025-02-20 10:54:22 +00:00
Paul Reichert
adcba851f0 feat: modify and alter functions for the tree map (#7118)
This PR implements the functions `modify` and `alter` on the tree map.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-20 09:50:10 +00:00
Marc Huisinga
cc94cff735 feat: fast path for inlay hints (#7149)
This PR adds a fast path to the inlay hint request that makes it re-use
already computed inlay hints from previous requests instead of
re-computing them. This is necessary because for some reason VS Code
emits an inlay hint request for every line you scroll, so we need to be
able to respond to these requests against the same document state
quickly. Otherwise, every single scrolled line would result in a request
that can take a few dozen ms to be responded to in long files, putting
unnecessary pressure on the CPU.
It also filters the result set by the inlay hints that have been
requested.
2025-02-20 09:26:16 +00:00
Kim Morrison
2960b384af feat: strengthen Int.tdiv_eq_ediv (#7158)
This PR strengthens `Int.tdiv_eq_ediv`, by dropping an unnecessary
hypothesis, in preparation for further work on `ediv`/`tdiv`/`fdiv`
lemmas.
2025-02-20 05:57:47 +00:00
Leonardo de Moura
2c2b3641f1 feat: helper theorem for cutsat (#7156)
This PR adds a helper theorem that will be used in divisibility
constraint conflict resolution during model construction.
2025-02-20 05:39:49 +00:00
Leonardo de Moura
746e3a9f42 feat: model search skeleton for cutsat (#7155)
This PR implements some infrastructure for the model search procedure in
cutsat.
2025-02-20 03:41:39 +00:00
Kim Morrison
6a4225bf04 chore: complete variable name linting for Vector (#7154) 2025-02-20 02:42:50 +00:00
Leonardo de Moura
c86073830f feat: infrastructure for inequalities constraints in cutsat (#7152)
This PR implements the infrastructure for supporting integer inequality
constraints in the cutsat procedure.
2025-02-19 23:09:12 +00:00
Joachim Breitner
8672186a4e refactor: use more fun_induction in Init.Data.Int.Linear (#7142)
This uses the improved functional induction theorems from #7140.
2025-02-19 22:56:23 +00:00
Joachim Breitner
5bee3288ac refactor: update proofs after stage0 update for #7140 2025-02-19 20:59:01 +01:00
Joachim Breitner
eeb74ecf4d chore: update stage0 2025-02-19 20:59:01 +01:00
Joachim Breitner
36704e33bd feat: FunInd to split on bif as well
This PR treats `bif` (aka `cond`) like `if` in functional induction principles. It
introduces the `Bool.dcond` definition, with a docstring indicating that
this is for internal use.
2025-02-19 20:59:01 +01:00
Kim Morrison
8a2e21cfc4 chore: linting variable names in List/Array (#7146) 2025-02-19 12:45:02 +00:00
Lean stage0 autoupdater
3deda3c6df chore: update stage0 2025-02-19 12:38:31 +00:00
Joachim Breitner
e288e9c57e test: add f91 definition using partial_fixpoint (#7144) 2025-02-19 11:13:53 +00:00
Marc Huisinga
26dba92ce9 feat: faster auto-completion (#7134)
This PR significantly improves the performance of auto-completion by
optimizing individual requests by a factor of ~2 and by giving language
clients like VS Code the opportunity to reuse the state of previous
completion requests, thus greatly reducing the latency for the
auto-completion list to update when adding more characters to an
identifier.

In my testing: 
- The latency of completing `C` in a file with `import Mathlib` was
reduced from ~1650ms to ~800ms
- The latency of completing `Cat` in a file with `import Mathlib` was
reduced from ~800ms to ~430ms
- The latency of completing dot notation was mostly unaffected
- Successive completions are now practically instant, e.g. if we were to
complete `C` and then type it out to `Cat`, before it would take roughly
~1650ms + ~800ms, whereas now there is only a significant latency for
completing `C` (~800ms) and the completion list is updated practically
instantly when typing out `Cat`.

<details> 
  <summary>(Video) Auto-completion latency before this PR</summary>

![Auto-completion latency before this
PR](https://github.com/user-attachments/assets/125bc1ba-b14c-477b-9580-d8067c641342)
</details>

<details> 
  <summary>(Video) Auto-completion latency after this PR</summary>

![Auto-completion latency after this
PR](https://github.com/user-attachments/assets/43d4b587-d51f-4877-aaef-424ecc771490)
</details>

In detail, this PR makes the following changes:
- Set `isIncomplete` to `false` in non-synthetic completion responses so
that the client can re-use these completion states.
- Replace the server side fuzzy matching with a simple and fast check
that all characters in the identifier thus far are present in the same
order in the declaration to match against. There are some examples where
the simple and fast check yields a completion item that the fuzzy
matching would filter, but since VS Code filters the completion items
with its own fuzzy matching after that anyways, these extra completion
items are never actually displayed to the user.
- Remove all notions of scoring and sorting completion items from the
language server. We now rely entirely on the client to sort the
completion items as it sees fit. In my testing, the only significant
change as a result of this is that while the language server would
sometimes penalize namespaces with lots of components, VS Code instead
uses a strictly alphabetic order. Even before this change, we never
actually really prioritized local variables over global variables, so
the penalty wasn't very helpful in practice. We might add some small
form of local variable prioritization in the future, though.
- Remove the empty completion list hack that was introduced in #1885. It
does not appear to be necessary anymore.
2025-02-19 10:05:18 +00:00
Leonardo de Moura
1cbd2bd199 feat: create a let-expression for storing the context in cutsat proofs (#7139)
This PR uses a `let`-expression for storing the (shared) context in
proofs produced by the cutsat procedure in `grind`.
2025-02-19 03:36:13 +00:00
Mac Malone
a41fb49e25 feat: smarter plugin loading (#7090)
This PR strips `lib` prefixes and `_shared` suffixes from plugin names.
It also moves most of the dynlib processing code to Lean to make such
preprocessing more standard.
2025-02-18 23:03:52 +00:00
Leonardo de Moura
dfce31e2a2 feat: proof production for divisibility constraint solver in grind (#7138)
This PR implements proof generation for the divisibility constraint
solver in `grind`.
2025-02-18 22:38:30 +00:00
Kim Morrison
1d9b19189a chore: deprecate Array.get
fix test
2025-02-19 08:48:33 +11:00
Kim Morrison
d3c36bd7cf chore: use as[i] instead of as.get i 2025-02-19 08:48:33 +11:00
Kim Morrison
950fbc9d8f chore: update stage0 2025-02-19 08:48:33 +11:00
Kim Morrison
167e0ab301 chore: add Array.getInternal, also @[extern] 2025-02-19 08:48:33 +11:00
Joachim Breitner
2fed93462d feat: try? to use fun_induction (#7082)
This PR makes `try?` use `fun_induction` instead of `induction … using
foo.induct`. It uses the argument-free short-hand `fun_induction foo` if
that is unambiguous. Avoids `expose_names` if not necessary by simply
trying without first.
2025-02-18 16:06:58 +00:00
Kyle Miller
2d4c0017b8 chore: review uses of generalize (#7126)
This PR looks at some uses of the `generalize` tactic, especially when
used in conjunction with `induction`.
2025-02-18 14:07:40 +00:00
Markus Himmel
3a22035dad feat: IntX.abs (#7131)
This PR adds `IntX.abs` functions. These are specified by `BitVec.abs`,
so they map `IntX.minValue` to `IntX.minValue`, similar to Rust's
`i8::abs`. In the future we might also have versions which take values
in `UIntX` and/or `Nat`.
2025-02-18 13:16:30 +00:00
Johannes Tantow
010c6c36f1 feat: verify toList for hash maps (#6954)
This PR verifies the `toList`function for hash maps and dependent hash
maps.
2025-02-18 13:10:03 +00:00
Joachim Breitner
a3b76aa825 feat: fun_induction foo (no arguments) (#7101)
This PR implements `fun_induction foo`, which is like `fun_induction foo
x y z`, only that it picks the arguments to use from a unique suitable
call to `foo` in the goal.
2025-02-18 12:27:21 +00:00
Lean stage0 autoupdater
9d5f565119 chore: update stage0 2025-02-18 12:15:21 +00:00
Joachim Breitner
f3baff8dce fix: fun_induction to generalize like induction does (#7127)
This PR follows up on #7103 which changes the generaliziation behavior
of `induction`, to keep `fun_induction` in sync. Also fixes a `Syntax`
indexing off-by-one error.
2025-02-18 11:03:56 +00:00
Markus Himmel
a26c937650 feat: Repr and Hashable for IntX (#7128)
This PR adds `Repr` and `Hashable` instances for `IntX`.
2025-02-18 11:03:53 +00:00
Marc Huisinga
0929cb3902 chore: remove semantic highlighting timeout (#7130)
Shot in the dark to resolve semantic highlighting issues. We don't
really need the timeout for semantic tokens anyways.
2025-02-18 10:24:49 +00:00
Paul Reichert
403e942f37 feat: getKey functions for the tree map (#7116)
This PR implements the `getKey` functions on the tree map. It also fixes
the naming of the `entryAtIdx` function on the tree set, which should
have been called `atIdx`.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-18 09:29:57 +00:00
Paul Reichert
d9e7ded5af feat: getThenInsertIfNew? and partition functions for the tree map (#7109)
This PR implements the `getThenInsertIfNew?` and `partition` functions
on the tree map.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-18 08:29:24 +00:00
Eric Wieser
4e10e4e02e feat: make linter names clickable in trace messages (#7119)
This PR makes linter names clickable in the `trace.profiler` output.
2025-02-18 07:58:47 +00:00
Kyle Miller
7557542bc2 feat: make structure parent projections nameable (#7100)
This PR modifies the `structure` syntax so that parents can be named,
like in
```lean
structure S extends toParent : P
```
**Breaking change:** The syntax is also modified so that the resultant
type comes *before* the `extends` clause, for example `structure S :
Prop extends P`. This is necessary to prevent a parsing ambiguity, but
also this is the natural place for the resultant type. Implements RFC
#7099.

Will need followup PRs for cleanup after a stage0 update.
2025-02-18 07:38:13 +00:00
Kyle Miller
219f36f499 chore: cleanup after stage0 update for #7103 (#7125)
This PR cleans up the bootstrapping workarounds introduced in #7103
(`induction` target generalization equation names).
2025-02-18 05:55:49 +00:00
Leonardo de Moura
b5bf7d4b87 feat: cutsat divisibility constraint solver proof by reflection theorems (#7124)
This PR adds the helper theorems for justifying the divisibility
constraint solver in the cutsat procedure used by the `grind` tactic.
2025-02-18 04:30:09 +00:00
Lean stage0 autoupdater
d6b3da5e72 chore: update stage0 2025-02-18 04:53:24 +00:00
Kyle Miller
6a59926592 feat: add generalization hypotheses to induction tactic (#7103)
This PR gives the `induction` tactic the ability to name hypotheses to
use when generalizing targets, just like in `cases`. For example,
`induction h : xs.length` leads to goals with hypotheses `h : xs.length
= 0` and `h : xs.length = n + 1`. Target handling is also slightly
modified for multi-target induction principles: it used to be that if
any target was not a free variable, all of the targets would be
generalized (thus causing free variables to lose their connection to the
local hypotheses they appear in); now only the non-free-variable targets
are generalized.

This gives `induction` the last basic feature of the mathlib
`induction'` tactic, which has been long-requested. Recent Zulip
discussion:
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/To.20replace.20.60induction'.20h.20.3A.20f.20x.60/near/499482173
2025-02-18 03:46:23 +00:00
Kim Morrison
b5b407343a chore: make internal List getters private (#7123) 2025-02-18 03:24:25 +00:00
Leonardo de Moura
97fb0b82bb feat: add divisibility constraint solver to grind (#7122)
This PR implements the divisibility constraint solver for the cutsat
procedure in the `grind` tactic.
2025-02-18 02:43:35 +00:00
Kim Morrison
ca253ae4cf chore: repair defeqs for List GetElem instances (#7121)
This PR repairs some defeq breakages from #7059.
2025-02-18 02:19:08 +00:00
Kim Morrison
4b307914fc chore: cleanup duplicate theorems (#7113) 2025-02-18 01:46:12 +00:00
Joachim Breitner
2cdf4b14e1 chore: update code after #7110 2025-02-17 18:21:10 +01:00
Joachim Breitner
1a374ceab2 chore: update stage0 2025-02-17 18:21:10 +01:00
Joachim Breitner
2a7b1162af fix: FunInd to clear match discriminants if possible
This PR tries to remove from functional induction principles hypotheses
that have been matched, as we expect the corresponding pattern to be
more useful. This avoids duplicate hypotheses due to the way `match`
refines hypotheses. Fixes #6281.
2025-02-17 18:21:10 +01:00
Paul Reichert
16e9700224 feat: values and valuesArray functions for the tree map (#7114)
This PR implements the methods `values` and `valuesArray` on the tree
map.

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-17 15:57:11 +00:00
Markus Himmel
5a8b4459c8 feat: conversions between Float and finite integers (#7083)
This PR adds (value-based, not bitfield-based) conversion functions
between `Float`/`Float32` and `IntX`/`UIntX`.
2025-02-17 15:42:10 +00:00
Marc Huisinga
3825c48405 feat: auto-implicit inlay hint tooltip & instance inlay hints (#7112)
This PR adds a tooltip describing what the auto-implicit inlay hints
denote, as well as auto-implicit inlay hints for instances.
2025-02-17 15:34:35 +00:00
Kim Morrison
f07e72fad7 chore: linting variable names for List (#7107) 2025-02-17 14:50:43 +00:00
Paul Reichert
3599e43284 feat: min, max, minKey, maxKey, atIndex, getEntryLE, getKeyLE, ... functions for the tree map (#7070)
This PR implements the methods `min`, `max`, `minKey`, `maxKey`,
`atIndex`, `getEntryLE`, `getKeyLE` and consorts on the tree map.

In order to implement the proof-based functions such as `min` and
`getEntryLT` in `Queries.lean`, it was necessary to extract `Balanced`
and `Ordered` into new files so that they can be used from
`Queries.lean`.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-17 14:00:42 +00:00
Markus Himmel
88fb7c0199 doc: style guide additions (#7111)
This PR extends the standard library style guide with guidance on
universe variables, notations and Unicode usage, and structure
definitions.
2025-02-17 11:57:22 +00:00
Sebastian Ullrich
2649d1510e fix: race condition led to (sync := true) tasks being spawned as separate dedicated tasks (#7089)
If the first task finished between the first check and taking the task
manager lock, the second task would be enqueued as if given
`Priority.max` instead of being run inline.
2025-02-17 09:52:40 +00:00
Paul Reichert
5d7cf08260 feat: tree map lemmas about empty, isEmpty, insert, contains (#6850)
This PR adds some lemmas about the new tree map. These lemmas are about
the interactions of `empty`, `isEmpty`, `insert`, `contains`. Some
lemmas about the interaction of `contains` with the others will follow
in a later PR.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-17 08:44:52 +00:00
Kim Morrison
88664e4a99 feat: complete aligning List/Array/Vector.finRange (#7106)
This PR completes the alignment of `List/Array/Vector.finRange` lemmas.
2025-02-17 06:11:43 +00:00
Kim Morrison
9d1fb9f4fa feat: align Array/Vector.extract lemmas with List (#7105)
This PR completes aligning `Array/Vector.extract` lemmas with the lemmas
for `List.take` and `List.drop`.
2025-02-17 04:56:04 +00:00
Luisa Cicolini
6a17e62523 feat: add BitVec.[(getMsbD, msb)_extractLsb', (getLsbD, getMsbD, msb)_extractLsb] , add and_eq_decide, or_eq_decide, decide_eq_true_iff to bool_to_prop (#6792)
This PR adds theorems `BitVec.(getMsbD, msb)_(extractLsb', extractLsb),
getMsbD_extractLsb'_eq_getLsbD`.

---------

Co-authored-by: Siddharth <siddu.druid@gmail.com>
Co-authored-by: Alex Keizer <alex@keizer.dev>
Co-authored-by: Kim Morrison <kim@tqft.net>
Co-authored-by: Tobias Grosser <tobias@grosser.es>
Co-authored-by: Tobias Grosser <github@grosser.es>
2025-02-17 03:02:37 +00:00
Kim Morrison
1ce7047bf5 feat: cleanup of get and back functions on List/Array (#7059)
This PR moves away from using `List.get` / `List.get?` / `List.get!` and
`Array.get!`, in favour of using the `GetElem` mediated getters. In
particular it deprecates `List.get?`, `List.get!` and `Array.get?`. Also
adds `Array.back`, taking a proof, matching `List.getLast`.
2025-02-17 01:43:45 +00:00
Leonardo de Moura
ef759d874f fix: grind using reducible transparency setting (#7102)
This PR modifies `grind` to run with the `reducible` transparency
setting. We do not want `grind` to unfold arbitrary terms during
definitional equality tests. This PR also fixes several issues
introduced by this change. The most common problem was the lack of a
hint in proofs, particularly in those constructed using proof by
reflection. This PR also introduces new sanity checks when `set_option
grind.debug true` is used.
2025-02-16 22:30:04 +00:00
Kitamado
6f5bb3e896 fix: allow trailing comma in array syntax (#7055)
This PR improves array and vector literal syntax by allowing trailing
commas. For example, `#[1, 2, 3,]`.

see: [Why Are Trailing Commas Not Allowed in Array
Literals?](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Why.20Are.20Trailing.20Commas.20Not.20Allowed.20in.20Array.20Literals.3F)

Note: we need to preserve the current name for the array syntax
(`«term#[_,]»`) to avoid a bootstrapping issue. The `FromJson`/`ToJson`
deriving handlers use array syntax in macros, and the stage0 version is
used in most of the prelude.
2025-02-16 19:26:23 +00:00
Joachim Breitner
96c6f9dc96 feat: fun_induction and fun_cases tactics (#7069)
This PR adds the `fun_induction` and `fun_cases` tactics, which add
convenience around using functional induction and functional cases
principles.

```
fun_induction foo  x y z
```
elaborates `foo x y z`, then looks up `foo.induct`, and then essentially
does
```
induction z using foo.induct y
```
including and in particular figuring out which arguments are parameters,
targets or dropped. This only works for non-mutual functions so far.

Likewise there is the `fun_cases` tactic using `foo.fun_cases`.
2025-02-16 10:59:56 +00:00
Leonardo de Moura
f50b863868 feat: cutsat helper functions (#7098)
This PR adds some helper functions for cutsat in the `grind` tactic.
2025-02-16 05:32:46 +00:00
Leonardo de Moura
dd3652ecdc feat: cutsat preparations (#7097)
This PR implements several modifications for the cutsat procedure in
`grind`.
- The maximal variable is now at the beginning of linear polynomials. 
- The old `LinearArith.Solver` was deleted, and the normalizer was moved
to `Simp`.
- cutsat first files were created, and basic infrastructure for
representing divisibility constraints was added.
2025-02-16 02:52:14 +00:00
Tobias Grosser
a9efbf04f4 feat: make BitVec.getElem the simp normal form and use it in ext (#5498)
This PR makes `BitVec.getElem` the simp normal form in case a proof is
available and changes `ext` to return `x[i]` + a hypothesis that proves
that we are in-bounds. This aligns `BitVec` further with the API
conventions of the Lean standard datatypes.

We move our proofs to this new normal form, which results in slightly
smaller proofs. With the exception of `getElem_ofFin`, no new API
surface is added as the `getElem` API has already been completed over
the previous months. We also move `getElem_shiftConcat_*` a bit higher
as they are needed in earlier proofs. To keep the changeset small, we do
not update the API of `BVDecide` but insert `←
BitVec.getLsbD_eq_getElem` at the few locations where it is needed.
Finally, we add a simproc for getElem, mirroring the existing ones for
getLsbD/getMsdD.

---------

Co-authored-by: Alex Keizer <alex@keizer.dev>
2025-02-16 00:04:56 +00:00
Leonardo de Moura
3a76ac5620 chore: cleanup and missing grind normalization rules (#7095)
This PR adds missing `grind` normalization rules, and removes dead
theorems.
2025-02-15 23:45:35 +00:00
Leonardo de Moura
747ea91c3a refactor: add denote' functions to Int/Linear.lean (#7094)
This PR adds the functions `Poly.denote'`, `RelCnstr.denote'`, and
`DvdCnstr.denote'`. These functions are useful for representing the
denotation of normalized results in `simp +arith` and the `grind`
preprocessor. This PR also adjusts all auxiliary normalization theorems
to use them to represent the normalized constraints. Previously, we were
converting `RelCnstr` and `DvdCnstr` back into raw constraints. While
this overhead was reasonable for `simp +arith`, it is not for the cutsat
procedure, which has no need for raw constraints. All constraints have
already been normalized by the time they reach cutsat.
2025-02-15 22:10:23 +00:00
Leonardo de Moura
ecdc2d57f2 refactor: Int.Linear module (#7093)
This PR cleans up the `Int.Linear` module by normalizing function and
type names and adding documentation strings. We will use it to implement
cutsat in the `grind` tactic.
2025-02-15 19:20:18 +00:00
Leonardo de Moura
f4afcfc923 feat: divisibility constraint normalizer (#7092)
This PR implements divisibility constraint normalization in `simp
+arith`.
2025-02-15 04:20:40 +00:00
jrr6
9cce0ce8d9 fix: ensure get_elem_tactic works in absence of goals (#7088)
This PR fixes the behavior of the indexed-access notation `xs[i]` in
cases where the proof of `i`'s validity is filled in during unification.

Closes #6999.
2025-02-15 03:00:36 +00:00
Leonardo de Moura
57aadf8af9 feat: add helper theorems for normalizing divisibility constraints (#7091)
This PR adds helper theorems for normalizing divisibility constraints.
They are going to be used to implement the cutsat procedure in the
`grind` tactic.
2025-02-15 02:44:49 +00:00
Kyle Miller
1babe9fc67 feat: make binders in #check be hoverable (#7074)
This PR modifies the signature pretty printer to add hover information
for parameters in binders. This makes the binders be consistent with the
hovers in pi types.

Suggested by @david-christiansen
2025-02-14 17:28:54 +00:00
Markus Himmel
dd1a4188a0 feat: Fin.toNat (#7079)
This PR introduces `Fin.toNat` as an alias for `Fin.val`. We add this
function for discoverability and consistency reasons. The normal form
for proofs remains `Fin.val`, and there is a `simp` lemma rewriting
`Fin.toNat` to `Fin.val`.
2025-02-14 11:59:44 +00:00
Markus Himmel
ed42d068d4 feat: UIntX.ofNatTruncate (#7080)
This PR adds the functions `UIntX.ofNatTruncate` (the version for
`UInt32` already exists).
2025-02-14 11:59:41 +00:00
Markus Himmel
784444c7a9 feat: IntX.minValue, IntX.maxValue, IntX.ofIntLE, IntX.ofIntTruncate (#7081)
This PR adds functions `IntX.ofIntLE`, `IntX.ofIntTruncate`, which are
analogous to the unsigned counterparts `UIntX.ofNatLT` and
`UInt.ofNatTruncate`.
2025-02-14 11:59:37 +00:00
Marc Huisinga
05fb67af90 feat: request cancellation (#7054)
This PR adds language server support for request cancellation to the
following expensive requests: Code actions, auto-completion, document
symbols, folding ranges and semantic highlighting. This means that when
the client informs the language server that a request is stale (e.g.
because it belongs to a previous state of the document), the language
server will now prematurely cancel the computation of the response in
order to reduce the CPU load for requests that will be discarded by the
client anyways.
2025-02-14 11:55:43 +00:00
Marc Huisinga
22d1d04059 fix: incremental goal state requests select incomplete snapshot (#6887)
This PR fixes a bug where the goal state selection would sometimes
select incomplete incremental snapshots on whitespace, leading to an
incorrect "no goals" response. Fixes #6594, a regression that was
originally introduced in 4.11.0 by #4727.

The fundamental cause of #6594 was that the snapshot selection would
always select the first snapshot with a range that contains the cursor
position. For tactics, whitespace had to be included in this range.
However, in the test case of #6594, this meant that the snapshot
selection would also sometimes pick a snapshot before the cursor that
still contains the cursor in its whitespace, but which also does not
necessarily contain all the information needed to produce a correct goal
state. Specifically, at the `InfoTree`-level, when the cursor is in
whitespace, we distinguish competing goal states by their level of
indentation. The snapshot selection did not have access to this
information, so it necessarily had to do the wrong thing in some cases.

This PR fixes the issue by adjusting the snapshot selection for goals to
explicitly account for whitespace and indentation, and refactoring the
language processor architecture to thread enough information through to
the snapshot selection so that it can decide which snapshots to use
without having to force too many tasks, which would destroy
incrementality in goal state requests.

Specifically, this PR makes the following adjustments:
- Refactor `SnapshotTask` to contain both a `Syntax` and a `Range`.
Before, `SnapshotTask`s had a single range that was used both for
displaying file progress information and for selecting snapshots in
server requests. For most snapshots, this range did not include
whitespace, though for tactics it did. Now, the `reportingRange` field
of `SnapshotTask` is intended exclusively for reporting file progress
information, and the `Syntax` is used for selecting snapshots in server
requests. Importantly, the `Syntax` contains the full range information
of the snapshot, i.e. its regular range and its range including
whitespace.
- Adjust all call-sites of `SnapshotTask` to produce a reasonable
`Syntax`.
- Adjust the goal snapshot selection to account for whitespace and
indentation, as the `InfoTree` goal selection does.
- Fix a bug in the snapshot tree tracing that would cause it to render
the `Info` of a snapshot at the wrong location when `trace.Elab.info`
was also set.

This PR is based on #6329.
2025-02-14 11:53:24 +00:00
Paul Reichert
36ac6eb912 feat: insertMany, ofList, ofArray, foldr, foldM functions for the tree map (#7051)
This PR implements the methods `insertMany`, `ofList`, `ofArray`,
`foldr` and `foldrM` on the tree map.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-14 08:24:33 +00:00
Markus Himmel
47548aa171 chore: rename UIntX.ofNatCore, UIntX.ofNat' -> UIntX.ofNatLT (#7071)
This PR unifies the existing functions `UIntX.ofNatCore` and
`UIntX.ofNat'` under a new name, `UIntX.ofNatLT`.
2025-02-14 06:58:15 +00:00
Leonardo de Moura
b26b781992 feat: simprocs for Int and Nat divides predicates (#7078)
This PR implements simprocs for `Int` and `Nat` divides predicates.
2025-02-14 05:43:38 +00:00
Mac Malone
c9c3366521 feat: lake: support plugins (#7001)
This PR adds support for plugins to Lake. Precompiled modules are now
loaded as plugins rather than via `--load-dynlib`.

Additional plugins can be added through an experimental `plugins`
configuration option. The syntax for specifying this is not yet
convenient, and will be improved in future changes. A parallel `dynlibs`
configuration option has been added for specifying additional dynamic
libraries to build and pass to `--load-dynlib`.

This PR also changes the default directory for `.olean`, `.ilean`, and
module dynamic libraries (i.e., `leanLibDir`) to `lib/lean` instead of
the previous default of `lib`. This avoids potential name clashes
between single module shared libraries and the shared libraries of a
full `lean_lib`.

On non-Windows systems, module dynamic libraries are no longer linked to
their imports or external symbols. Symbols from those libraries are left
unresolved until load time. This avoids nesting these dependencies
within the shared library and means Lake no longer needs to augment the
shared library path to allow Lean to resolve such nested dependencies on
load.
2025-02-14 04:57:31 +00:00
Leonardo de Moura
2c2a3a65b2 feat: support theorems for cutsat Div-Solve rule (#7077)
This PR proves the helper theorems for justifying the "Div-Solve" rule
in the cutsat procedure.
2025-02-14 04:55:58 +00:00
Kim Morrison
8cefb2cf65 feat: premise selection API (#7061)
This PR provides a basic API for a premise selection tool, which can be
provided in downstream libraries. It does not implement premise
selection itself!
2025-02-14 04:08:18 +00:00
Lean stage0 autoupdater
80c8837f49 chore: update stage0 2025-02-13 16:00:29 +00:00
Markus Himmel
40c6dfa3ae chore: dsimproc for UIntX.ofNatLT (#7068)
This PR is a follow-up to #7057 and adds a builtin dsimproc for
`UIntX.ofNatLT` which it turns out we need in stage0 before we can get
the deprecation of `UIntX.ofNatCore` in favor of `UIntX.ofNatLT` off the
ground.
2025-02-13 14:51:42 +00:00
Bulhwi Cha
cc76c46244 doc: fix typo (#7067) 2025-02-13 13:21:18 +00:00
Markus Himmel
b38da34db2 chore: rename BitVec.ofNatLt -> BitVec.ofNatLT (#7064)
This PR renames `BitVec.ofNatLt` to `BitVec.ofNatLT` and sets up
deprecations for the old name.
2025-02-13 12:52:31 +00:00
Markus Himmel
4a900cc65c chore: rename IntX.toNat -> IntX.toNatClampNeg (#7066)
This PR renames `IntX.toNat` to `IntX.toNatClampNeg` (to reduce
surprises) and sets up a deprecation.
2025-02-13 12:14:28 +00:00
Markus Himmel
a3fd2eb0fe chore: make IntX constructor private, provide UIntX.toIntX (#7062)
This PR introduces the functions `UIntX.toIntX` as the public API to
obtain the `IntX` that is 2's complement equivalent to a given `UIntX`.
2025-02-13 11:29:31 +00:00
Paul Reichert
6ac530aa1a feat: deprecated find, fold, foldM, mergeBy functions for the tree map (#7036)
This PR adds some deprecated function aliases to the tree map in order
to ease the transition from the `RBMap` to the tree map.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-13 11:12:22 +00:00
Markus Himmel
04fe72fee0 feat: missing conversion functions for ISize (#7063)
This PR adds `ISize.toInt8`, `ISize.toInt16`, `Int8.toISize`,
`Int16.toISize`.
2025-02-13 11:02:00 +00:00
Joachim Breitner
a833afa935 feat: binderNameHint in congr (#7053)
This PR makes `simp` heed the `binderNameHint` also in the assumptions
of congruence rules. Fixes #7052.
2025-02-13 09:38:42 +00:00
Markus Himmel
7c9454edd2 feat: UIntX.ofFin (#7056)
This PR adds the `UIntX.ofFin` conversion functions.
2025-02-13 08:45:01 +00:00
Markus Himmel
1ecb4a43ae chore: rename UIntX.val -> UIntX.toFin (#7050)
This PR renames the functions `UIntX.val` to `UIntX.toFin`.
2025-02-13 07:50:47 +00:00
Kim Morrison
ae9d12aeaa chore: upstream an Int lemma (#7060) 2025-02-13 03:19:02 +00:00
Leonardo de Moura
e617ce7e4f refactor: move grind offset constraint module to Grind/Arith/Offset (#7058)
This PR moves the `grind` offset constraint module to the
`Grind/Arith/Offset` subdirectory in preparation to the full linear
integer arithmetic module.
2025-02-12 23:16:07 +00:00
Lean stage0 autoupdater
b9894b40af chore: update stage0 2025-02-12 17:09:23 +00:00
Markus Himmel
9ff4d53d0b chore: rename UIntX.mk -> UIntX.ofBitVec (#7046)
This PR renames `UIntX.mk` to `UIntX.ofBitVec` and adds deprecations.
2025-02-12 16:08:03 +00:00
Markus Himmel
1e262c2c0e chore: add UIntX.ofNatLT (#7057)
This PR adds the function `UIntX.ofNatLT`. This is supposed to be a
replacement for `UIntX.ofNatCore` and `UIntX.ofNat'`, but for
bootstrapping reasons we need this function to exist in stage0 before we
can proceed with the renaming and deprecations, so this PR just adds the
function.
2025-02-12 15:12:29 +00:00
Markus Himmel
b08fc5dfda feat: IntX.ofBitVec (#7048)
This PR adds the functions `IntX.ofBitVec`.
2025-02-12 14:49:31 +00:00
Joachim Breitner
761c88f10e feat: propagate wfParam through let (#7039)
This PR improves the well-founded definition preprocessing to propagate
`wfParam` through let expressions.

Fixes #7038.
2025-02-12 13:22:08 +00:00
Sebastian Ullrich
07b0e5b7fe chore: compile against glibc 2.26 (#7037)
This PR relaxes the minimum required glibc version for Lean and Lean
executables to 2.26 on x86-64 Linux
2025-02-12 09:29:51 +00:00
Sebastian Ullrich
f7e207a824 chore: remove save tactic (#7047)
This PR removes the `save` and `checkpoint` tactics that have been
superseded by incremental elaboration
2025-02-12 09:19:30 +00:00
Cameron Zwarich
f61e2989a2 fix: make several LCNF environment extensions have asyncMode of .sync (#7041)
This PR marks several LCNF-specific environment extensions as having an
asyncMode of .sync rather than the default of .mainOnly, so they work
correctly even in async contexts.
2025-02-12 09:13:49 +00:00
Joachim Breitner
bdf4b792a8 feat: wf_preprocess for {List,Array}.Monadic functions (#7034)
This PR adds `wf_preprocess` theorems for
`{List,Array}.{foldlM,foldrM,mapM,filterMapM,flatMapM}`
2025-02-12 09:06:12 +00:00
Sebastian Ullrich
d3af1268a7 test: fix simp_arith1 benchmark (#7049) 2025-02-12 10:22:32 +00:00
Lean stage0 autoupdater
01be97309e chore: update stage0 2025-02-12 09:15:43 +00:00
Kim Morrison
3cf6fb2405 chore: fix linter.listVariables naming (#7044) 2025-02-12 05:17:39 +00:00
Leonardo de Moura
2a67a49f31 chore: simp_arith has been deprecated (#7043)
This PR deprecates the tactics `simp_arith`, `simp_arith!`,
`simp_all_arith` and `simp_all_arith!`. Users can just use the `+arith`
option.
2025-02-12 03:55:45 +00:00
Leonardo de Moura
fb2e5e5555 chore: remove dead code from Nat/Linear.lean (#7042) 2025-02-12 02:14:00 +00:00
Leonardo de Moura
b87c01b1c0 feat: simp +arith sorts linear atoms (#7040)
This PR ensures that terms such as `f (2*x + y)` and `f (y + x + x)`
have the same normal form when using `simp +arith`
2025-02-11 23:37:30 +00:00
Paul Reichert
0f1133fe69 feat: tree map data structures and operations (#6914)
This PR introduces ordered map data structures, namely `DTreeMap`,
`TreeMap`, `TreeSet` and their `.Raw` variants, into the standard
library. There are still some operations missing that the hash map has.
As of now, the operations are unverified, but the corresponding lemmas
will follow in subsequent PRs. While the tree map has already been
optimized, more micro-optimization will follow as soon as the new code
generator is ready.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-11 14:47:47 +00:00
Henrik Böving
f348a082da feat: present bv_decide counter examples for UIntX and enums better (#7033)
This PR improves presentation of counter examples for UIntX and enum
inductives in bv_decide.
2025-02-11 11:01:40 +00:00
Leonardo de Moura
befee896b3 feat: linear integer inequality normalization using gcd of coefficients (#7030)
This PR adds completes the linear integer inequality normalizer for
`grind`. The missing normalization step replaces a linear inequality of
the form `a_1*x_1 + ... + a_n*x_n + b <= 0` with `a_1/k * x_1 + ... +
a_n/k * x_n + ceil(b/k) <= 0` where `k = gcd(a_1, ..., a_n)`.
`ceil(b/k)` is implemented using the helper `cdiv b k`.
2025-02-11 03:45:25 +00:00
Mac Malone
e7fa5891ea feat: lake: provide help on Elan's + option (#7024)
This PR documents how to use Elan's `+` option with `lake new|init`. It
also provides an more informative error message if a `+` option leaks
into Lake (e.g., if a user provides the option to a Lake run without
Elan).
2025-02-11 00:43:38 +00:00
Sebastian Ullrich
3927445973 chore: build Lean with Elab.async (#6989) 2025-02-10 18:16:20 +00:00
Henrik Böving
7d1d761148 feat: bv_decide rewrite multiplication with power of two to shift (#7029)
This PR adds simprocs to bv_decide's preprocessor that rewrite
multiplication with powers of two to constant shifts.
2025-02-10 17:42:59 +00:00
Sebastian Ullrich
7790420cae chore: trivial changes from async-proofs branch (#7028) 2025-02-10 16:44:05 +00:00
Joachim Breitner
4016a80f66 feat: nested well-founded recursion via automatic preprocessing (#6744)
This PR extend the preprocessing of well-founded recursive definitions
to bring assumptions like `h✝ : x ∈ xs` into scope automatically.

This fixes #5471, and follows (roughly) the design written there.
See the module docs at `src/Lean/Elab/PreDefinition/WF/AutoAttach.lean`
for details on the implementation.

This only works for higher-order functions that have a suitable setup.
See for example section “Well-founded recursion preprocessing setup” in
`src/Init/Data/List/Attach.lean`.

This does not change the `decreasing_tactic`, so in some cases there is
still the need for a manual termination proof some cases. We expect a
better termination tactic in the near future.
2025-02-10 16:43:41 +00:00
Lean stage0 autoupdater
feb8cc2d4a chore: update stage0 2025-02-10 16:30:51 +00:00
Markus Himmel
5eed373feb doc: misc. style guide and naming scheme additions (#7026)
This PR clarifies the styling of `do` blocks, and enhanes the naming
conventions with information about the `ext` and `mono` name components
as well as advice about primed names and naming of simp sets.
2025-02-10 15:27:30 +00:00
Sebastian Ullrich
895cdce9bc fix: codegen was allowed improper env ext accesses (#7023) 2025-02-10 15:08:02 +00:00
Kim Morrison
3411518548 chore: rename simp sets (#7017)
This PR renames the simp set `boolToPropSimps` to `bool_to_prop` and
`bv_toNat` to `bitvec_to_nat`. I'll be adding more similarly named simp
sets.
2025-02-10 14:20:18 +00:00
Kim Morrison
13b4b11657 chore: deprecated compile_time_search_path% (#7022)
This PR deprecates `compile_time_search_path%`; it didn't prove useful,
and we've shot ourselves in the foot with it more than once.
2025-02-10 13:49:17 +00:00
Henrik Böving
fa05bccd58 feat: add basic extract theorems for bv_decide (#7021)
This PR adds theorems for interactions of extractLsb with `&&&`, `^^^`,
`~~~` and `bif` to bv_decide's preprocessor.
2025-02-10 13:48:20 +00:00
Kim Morrison
c307e8a04f feat: improvements to simp confluence (#7013)
This PR makes improvements to the simp set for List/Array/Vector/Option
to improve confluence, in preparation for `simp_lc`.
2025-02-10 12:17:44 +00:00
Henrik Böving
2aca375cd9 fix: correct trace nodes in bv_decide (#7019)
This PR properly spells out the trace nodes in bv_decide so they are
visible with just `trace.Meta.Tactic.bv` and `trace.Meta.Tactic.sat`
instead of always having to enable the profiler.
2025-02-10 11:24:52 +00:00
Lean stage0 autoupdater
46ae4c0d7c chore: update stage0 2025-02-10 11:58:06 +00:00
Sebastian Ullrich
6f445a1c05 chore: Task.get block profiling (#7016)
* `--profile` now reports `blocking` time spent in `Task.get` inside
other profiling categories
* environment variable `LEAN_TRACE_TASK_GET_BLOCKED` when set makes
`lean` dump stack traces of `Task.get` blocks
2025-02-10 10:56:49 +00:00
Kim Morrison
80cf782bc6 chore: rename simp sets (#7018)
This is preliminary to #7017; we'll need an update-stage0 before the
actual rename can take place.
2025-02-10 10:56:20 +00:00
Kim Morrison
1622f578c9 chore: replace HashMap.get_ lemmas with getElem_ versions (#7004)
This PR replaces various `HashMap.get_X` with `getElem_X` versions. Now
the left hand sides are in simp normal form (and this fixes some
confluence problems).
2025-02-10 10:37:21 +00:00
Kim Morrison
47814f9da1 chore: add @[simp] to List.flatten_toArray (#7014) 2025-02-10 10:30:41 +00:00
Henrik Böving
0d95bf68cc feat: basic support for handling enum inductives in bv_decide (#6946)
This PR implements basic support for handling of enum inductives in
`bv_decide`. It now supports equality on enum inductive variables (or
other uninterpreted atoms) and constants.
2025-02-10 10:00:20 +00:00
Leonardo de Moura
d61f506da2 feat: simp +arith normalizes coefficient in linear integer polynomials (#7015)
This PR makes sure `simp +arith` normalizes coefficients in linear
integer polynomials. There is still one todo: tightening the bound of
inequalities.
2025-02-10 06:13:28 +00:00
Kim Morrison
7f3e170509 chore: unprotect List.foldlM (#7003) 2025-02-09 22:54:51 +00:00
Leonardo de Moura
bcffbdd3a1 chore: improve withAbstractAtoms (#7012)
We should not abstract free variables
2025-02-09 22:46:09 +00:00
Leonardo de Moura
e14c593003 feat: simp +arith for integers (#7011)
This PR adds `simp +arith` for integers. It uses the new `grind`
normalizer for linear integer arithmetic. We still need to implement
support for dividing the coefficients by their GCD. It also fixes
several bugs in the normalizer.
2025-02-09 21:41:58 +00:00
Leonardo de Moura
bcde913a96 chore: improve expose_names doc string (#7010) 2025-02-09 17:24:07 +00:00
Leonardo de Moura
33b45132a4 feat: bv_decide hint (#7009)
This PR ensures users get an error message saying which module to import
when they try to use `bv_decide`.
2025-02-09 17:11:28 +00:00
Kim Morrison
ef4c6ed83c chore: remove unused Int simp lemmas (#7005) 2025-02-09 16:20:38 +00:00
Leonardo de Moura
cd3eb9125c feat: linear integer arith normalizer (#7002)
This PR implements the normalizer for linear integer arithmetic
expressions. It is not connect to `simp +arith` yet because of some
spurious `[simp]` attributes.
2025-02-09 04:32:54 +00:00
Leonardo de Moura
f6c5aed7ef feat: add Int.Linear normalization support (#7000)
This PR adds helper theorems for justifying the linear integer
normalizer.
2025-02-08 23:01:01 +00:00
Kyle Miller
dd293d1fbd doc: mention Props are equal to True or False (#6998)
This PR modifies the `Prop` docstring to point out that every
proposition is propositionally equal to either `True` or `False`. This
will help point users toward seeing that `Prop` is like `Bool`.

I considered mentioning `Classical.propComplete`, but it's probably
better not making it seem like that's how you should work with
propositions.
2025-02-08 18:11:26 +00:00
Bolton Bailey
4989a60af3 chore: change Lake configuration error message (#6829)
This PR changes the error message for Lake configuration failure to
reflect that issues do not always arise from an invalid lakefile, but
sometimes arise from other issues like network errors. The new error
message encompasses all of these possibilities.

Closes #6827
2025-02-08 15:04:39 +00:00
Joachim Breitner
7c809a94af refactor: elaborate forIn notation without extra let (#6977)
This PR avoids a `let` in the elaboration of `forIn`. It was introduced
in https://github.com/leanprover/lean4/commit/f51328ff112 but nothing
seems to break when I simplify the code. This removes an unexpected `let
col✝ :=…` from the “Expected type” view in the Info View and from the
termination proofs.
2025-02-08 10:32:34 +00:00
Leonardo de Moura
5eca093a89 feat: exact? in try? (#6995)
This PR implements support for `exact?` in the `try?` tactic.
2025-02-07 22:43:30 +00:00
Leonardo de Moura
6d46e31ad8 feat: compress try? suggestions (#6994)
This PR adds the `Try.Config.merge` flag (`true` by default) to the
`try?` tactic. When set to `true`, `try?` compresses suggestions such
as:
```lean
· induction xs, ys using bla.induct
    · grind only [List.length_reverse]
    · grind only [bla]
```
into:
```lean
induction xs, ys using bla.induct <;> grind only [List.length_reverse, bla]
```

This PR also ensures `try?` does not generate suggestions that mixes
`grind` and `grind only`, or `simp` and `simp only` tactics.

This PR also adds the `try? +harder` option (previously called `lib`),
but it has not been fully implemented yet.
2025-02-07 19:17:25 +00:00
Leonardo de Moura
605b9e63c9 chore: disable broken test
It is timing out on OSX, and `master` is failing to build.
This is a temporary "fix."
2025-02-07 11:13:50 -08:00
Sebastian Ullrich
0d1907c1df feat: parallel progress notifications (#6329)
This PR enables the language server to present multiple disjoint line
ranges as being worked on. Even before parallelism lands, we make use of
this feature to show post-elaboration tasks such as kernel checking on
the first line of a declaration to distinguish them from the final
tactic step.


![image](https://github.com/user-attachments/assets/f6170689-6835-40c0-baba-df067a60b605)
2025-02-07 16:50:31 +00:00
Leonardo de Moura
2b67ef451a feat: improve try? suggestion (#6991)
This PR improves how suggestions for the `<;>` combinator are generated.
2025-02-07 16:33:25 +00:00
Sebastian Ullrich
bfe2d28c50 chore: re-enable Elab.async in the server (#6990) 2025-02-07 16:12:31 +00:00
Sebastian Ullrich
de24063c4b fix: convert kernel interrupt into elab interrupt (#6988)
This PR ensures interrupting the kernel does not lead to wrong, sticky
error messages in the editor
2025-02-07 15:55:32 +00:00
Sebastian Ullrich
7c79f05cd4 feat: API to avoid deadlocks from dropped promises (#6958)
This PR improves the `Promise` API by considering how dropped promises
can lead to never-finished tasks.
2025-02-07 15:33:10 +00:00
Sebastian Ullrich
1248a55d32 perf: avoid taking mutex on already-resolved promises (#6984) 2025-02-07 10:14:35 +00:00
Sebastian Ullrich
ac9708051a feat: respect Task.map/bind (sync := true) after waiting (#6976)
This PR extends the behavior of the `sync` flag for `Task.map/bind` etc.
to encompass synchronous execution even when they first have to wait on
completion of the first task, drastically lowering the overhead of such
tasks. Thus the flag is now equivalent to e.g. .NET's
`TaskContinuationOptions.ExecuteSynchronously`.
2025-02-07 09:06:57 +00:00
Kim Morrison
af385d7c10 feat: improve monadic Array lemmas (#6982)
This PR improves some lemmas about monads and monadic operations on
Array/Vector, using @Rob23oa's work in
https://github.com/leanprover-community/batteries/pull/1109, and
adding/generalizing some additional lemmas.
2025-02-07 04:02:02 +00:00
Kim Morrison
92f0d31ed7 chore: linting List (#6970) 2025-02-07 01:44:51 +00:00
Leonardo de Moura
0376cae739 feat: try? tactic improvements (#6981)
This PR adds new configuration options to `try?`.
- `try? -only` omits `simp only` and `grind only` suggestions
- `try? +missing` enables partial solutions where some subgoals are
"solved" using `sorry`, and must be manually proved by the user.
- `try? (max:=<num>)` sets the maximum number of suggestions produced
(default is 8).
2025-02-07 01:35:41 +00:00
Leonardo de Moura
c92425f98d feat: try? validation and cleanup (#6980)
This PR improves the `try?` tactic runtime validation and error
messages. It also simplifies the implementation, and removes unnecessary
code.
2025-02-06 23:59:38 +00:00
Sofia Rodrigues
52198837df feat: improve some files separation and standardize error messages in UV modules (#6830)
This PR improves some files separation and standardize error messages in
UV modules
2025-02-06 23:24:42 +00:00
Leonardo de Moura
eab09084a3 feat: try? composite suggestions (#6979)
This PR adds support for more complex suggestions in `try?`. Example:
```lean
example (as : List α) (a : α) : concat as a = as ++ [a] := by
  try?
```
suggestion
```
Try this: · induction as, a using concat.induct
  · rfl
  · simp_all
```
2025-02-06 21:56:14 +00:00
Marc Huisinga
45d39422bc fix: inlay hints in untitled files (#6978)
This PR fixes a bug where both the inlay hint change invalidation logic
and the inlay hint edit delay logic were broken in untitled files.
Thanks to @Julian for spotting this!
2025-02-06 19:26:11 +00:00
Lean stage0 autoupdater
06d022b9c0 chore: update stage0 2025-02-06 17:39:42 +00:00
Marc Huisinga
dcd70cbfba feat: inlay hint refinements (#6959)
This PR implements a number of refinements for the auto-implicit inlay
hints implemented in #6768.
Specifically:
- In #6768, there was a bug where the inlay hint edit delay could
accumulate on successive edits, which meant that it could sometimes take
much longer for inlay hints to show up. This PR implements the basic
infrastructure for request cancellation and implements request
cancellation for semantic tokens and inlay hints to resolve the issue.
With this edit delay bug fixed, it made more sense to increase the edit
delay slightly from 2000ms to 3000ms.
- In #6768, we applied the edit delay to every single inlay hint request
in order to reduce the amount of inlay hint flickering. This meant that
the edit delay also had a significant effect on how far inlay hints
would lag behind the file progress bar. This PR adjusts the edit delay
logic so that it only affects requests sent directly after a
corresponding `didChange` notification. Once the edit delay is used up,
all further semantic token requests are responded to without delay, so
that the only latency that affects how far the inlay hints lag behind
the progress bar is how often we emit refresh requests and how long VS
Code takes to respond to them.
- For inlay hints, refresh requests are now emitted 500ms after a
response to an inlay hint request, not 2000ms, which means that after
the edit delay, inlay hints should only lag behind the progress bar by
about up to 500ms. This is justifiable for inlay hints because the
response should be much smaller than e.g. is the case for semantic
tokens.
- In #6768, 'Restart File' did not prompt a refresh, but it does now.
- VS Code does not immediately remove old inlay hints from the document
when they are applied. In #6768, this meant that inlay hints would
linger around for a bit once applied. To mitigate this issue, this PR
adjusts the inlay hint edit delay logic to identify edits sent from the
client as being inlay hint applications, and sets the edit delay to 0ms
for the inlay hint requests following it. This means that inlay hints
are now applied immediately.
- In #6768, hovering over single-letter auto-implicit inlay hints was a
bit finicky because VS Code uses the regular cursor icon on inlay hints,
not the thin text cursor icon, which means that it is easy to put the
cursor in the wrong spot. We now add the separation character (` ` or
`{`) preceding an auto-implicit to the hover range as well, which makes
hovering over inlay hints much smoother.
2025-02-06 16:43:56 +00:00
Lean stage0 autoupdater
07c880f7ff chore: update stage0 2025-02-06 12:27:11 +00:00
Joachim Breitner
2e6206bbeb refactor: rename auto_attach attribute to wf_preprocess (#6972)
As per dicussion with team colleages, the feature shouldn’t be called
“auto attach” but rather “well-founded recursion preprocessing” to avoid
(imprecise) jargon.
2025-02-06 11:28:23 +00:00
Henrik Böving
4540a6436f refactor: bv_decide's type analysis to prepare for enum support (#6971)
This PR does some refactoring on bv_decide's type analysis in
preparation for enum support in #6946.
2025-02-06 11:16:57 +00:00
Joachim Breitner
dc001a01e5 feat: binderNameHint (#6947)
This PR adds the `binderNameHint` gadget. It can be used in rewrite and
simp rules to preserve a user-provided name where possible.

The expression `binderNameHint v binder e` defined to be `e`.

If it is used on the right-hand side of an equation that is applied by a
tactic like `rw` or `simp`,
and `v` is a local variable, and `binder` is an expression that (after
beta-reduction) is a binder
(so `fun w => …` or `∀ w, …`), then it will rename `v` to the name used
in the binder, and remove
the `binderNameHint`.

A typical use of this gadget would be as follows; the gadget ensures
that after rewriting, the local
variable is still `name`, and not `x`:
```
theorem all_eq_not_any_not (l : List α) (p : α → Bool) :
    l.all p = !l.any fun x => binderNameHint x p (!p x) := sorry

example (names : List String) : names.all (fun name => "Waldo".isPrefixOf name) = true := by
  rw [all_eq_not_any_not]
  -- ⊢ (!names.any fun name => !"Waldo".isPrefixOf name) = true
```

This gadget is supported by `simp`, `dsimp` and `rw` in the
right-hand-side of an equation, but not
in hypotheses or by other tactics.
2025-02-06 11:03:27 +00:00
Kim Morrison
a00cc12436 chore: rename Nat.not_eq_zero_of_lt (#6968)
Renames a lemma.

Closes #6714
2025-02-06 10:20:17 +00:00
Markus Himmel
947cd742bf doc: style guide and naming convention for the standard library (#6950)
This PR adds a style guide and a naming convention for the standard
library.
2025-02-06 08:33:48 +00:00
Lean stage0 autoupdater
ee42e8cf24 chore: update stage0 2025-02-06 08:27:23 +00:00
Leonardo de Moura
b01ca8ee23 feat: use expose_names in try? (#6967)
This PR ensures `try?` can suggest tactics that need to reference
inaccessible local names.
Example: 
```lean
/--
info: Try these:
• · expose_names; induction as, bs_1 using app.induct <;> grind [= app]
• · expose_names; induction as, bs_1 using app.induct <;> grind only [app]
-/
#guard_msgs (info) in
example : app (app as bs) cs = app as (app bs cs) := by
  have bs := 20 -- shadows `bs` in the target
  try?
```
2025-02-06 05:44:25 +00:00
Kim Morrison
fd4599fd7a feat: add internal linter for List/Array/Vector variable names (#6966)
This PR adds an internal-use-only strict linter for the variable names
of `List`/`Array`/`Vector` variables, and begins cleaning up.
2025-02-06 04:49:21 +00:00
Leonardo de Moura
fbeec32c2b feat: implement try? using evalAndSuggest (#6965)
This PR re-implements the `try?` tactic using the new `evalAndSuggest`
infrastructure.
2025-02-06 04:47:26 +00:00
Kim Morrison
de99c8015a feat: #info_trees in command (#6964)
This PR adds a convenience command `#info_trees in`, which prints the
info trees generated by the following command. It is useful for
debugging or learning about `InfoTree`.
2025-02-06 03:11:53 +00:00
Kim Morrison
49297f12a5 chore: further cleanup of index variable naming in List (#6963) 2025-02-06 02:39:06 +00:00
Kim Morrison
8fd107c10f doc: improve List.toArray doc-string (#6962)
This PR improves the doc-string for `List.toArray`.

Thanks to @jt0202 for pointing this out.
2025-02-06 01:56:47 +00:00
Leonardo de Moura
13b1f56f88 feat: evalAndSuggest helper tactic (#6961)
This PR adds the auxiliary tactic `evalAndSuggest`. It will be used to
refactor `try?`.
2025-02-05 22:13:47 +00:00
Lean stage0 autoupdater
20e67945ea chore: update stage0 2025-02-05 16:42:25 +00:00
jrr6
60aeb79a75 feat: allow updating binders to and from strict- and instance-implicit (#6634)
This PR adds support for changing the binder annotations of existing
variables to and from strict-implicit and instance-implicit using the
`variable` command.

This PR requires a stage0 update to fully take effect.

Closes #6078
2025-02-05 15:43:54 +00:00
Lean stage0 autoupdater
f1ed830b9a chore: update stage0 2025-02-05 14:42:28 +00:00
Joachim Breitner
255d931e0c feat: add auto_attach simp set (no functionality yet) (#6956)
this PR helps with bootstrapping #6744.
2025-02-05 13:33:35 +00:00
Kim Morrison
53ed233f38 chore: fix variable names in List lemmas (#6953)
This PR starts on the process of cleaning up variable names across
List/Array/Vector. For now, we just rename "numerical index" variables
in one file. This is driven by a custom linter.
2025-02-05 09:49:14 +00:00
Luisa Cicolini
0ed493e748 feat: add SMT-LIB overflow on addition for bitvectors BitVec.(uadd_overflow, sadd_overflow, uadd_overflow_eq, sadd_overflow_eq) and support theorems (#6628)
This PR adds SMT-LIB operators to detect overflow
`BitVec.(uadd_overflow, sadd_overflow)`, according to the definitions
[here](https://github.com/SMT-LIB/SMT-LIB-2/blob/2.7/Theories/FixedSizeBitVectors.smt2),
and the theorems proving equivalence of such definitions with the
`BitVec` library functions (`uaddOverflow_eq`, `saddOverflow_eq`).
Support theorems for these proofs are `BitVec.toNat_mod_cancel_of_lt,
BitVec.toInt_lt, BitVec.le_toInt, Int.bmod_neg_iff`. The PR also
includes a set of tests.

---------

Co-authored-by: Tobias Grosser <github@grosser.es>
Co-authored-by: Alex Keizer <alex@keizer.dev>
Co-authored-by: Tobias Grosser <tobias@grosser.es>
Co-authored-by: Siddharth Bhat <siddu.druid@gmail.com>
2025-02-05 09:36:56 +00:00
jrr6
1f956ad1af fix: show error messages on name conflicts in mutual blocks (#6939)
This PR adds error messages for `inductive` declarations with
conflicting constructor names and `mutual` declarations with conflicting
names.

Closes #6694.
2025-02-05 04:23:24 +00:00
Mac Malone
ebba1e04d0 feat: frontend & server support for plugins (#6893)
This PR adds support for plugins to the frontend and server.

Implementation-wise, this adds a `plugins` argument to `runFrontend`,
`processHeader`, amd `importModules`, a `plugins` field to
`SetupImportsResult` and `FileSetupResult`. and a `pluginsPath` field to
`LeanPaths`, and then threads the value through these.
2025-02-04 23:36:18 +00:00
Joachim Breitner
33baaccb20 test: more equational theorem generation tests (#6952)
This includes the examples from issues #2961, #3219 and #5667 in our
test suite, so that we know when (accidentially) fix them.

In fact this closes #3219, which (judging from the nightlies) was fixed
last week by #6901.
2025-02-04 22:18:35 +00:00
Cameron Zwarich
63ac27e9b9 chore: restore example after stage0 update (#6942) 2025-02-04 18:02:59 +00:00
Lean stage0 autoupdater
897e9c5388 chore: update stage0 2025-02-04 18:30:41 +00:00
Marc Huisinga
95aee36fab feat: inlay hints for auto-implicits (#6768)
This PR adds preliminary support for inlay hints, as well as support for
inlay hints that denote the auto-implicits of a function. Hovering over
an auto-implicit displays its type and double-clicking the auto-implicit
inserts it into the text document.

![Inlay hints for
auto-implicits](https://github.com/user-attachments/assets/fb204c42-5997-4f10-9617-c65f1042d732)

This PR is an extension of #3910.

### Known issues

- In VS Code, when inserting an inlay hint, the inlay hint may linger
for a couple of seconds before it disappears. This is a defect of the VS
Code implementation of inlay hints and cannot adequately be resolved by
us.
- When making a change to the document, it may take a couple of seconds
until the inlay hints respond to the change. This is deliberate and
intended to reduce the amount of inlay hint flickering while typing. VS
Code has a mechanism of its own for this, but in my experience it is
still far too sensitive without additional latency.
- Inserting an auto-implicit inlay hint that depends on an auto-implicit
meta-variable causes a "failed to infer binder type" error. We can't
display these meta-variables in the inlay hint because they don't have a
user-displayable name, so it is not clear how to resolve this problem.
- Inlay hints are currently always resolved eagerly, i.e. we do not
support the `textDocument/inlayHint/resolve` request yet. Implementing
support for this request is future work.

### Other changes
- Axioms did not support auto-implicits due to an oversight in the
implementation. This PR ensures they do.
- In order to reduce the amount of inlay hint flickering when making a
change to the document, the language server serves old inlay hints for
parts of the file that have not been processed yet. This requires LSP
request handler state (that sometimes must be invalidated on
`textDocument/didChange`), so this PR introduces the notion of a
stateful LSP request handler.
- The partial response mechanism that we use for semantic tokens, where
we simulate incremental LSP responses by periodically emitting refresh
requests to the client, is generalized to accommodate both inlay hints
and semantic tokens. Additionally, it is made more robust to ensure that
we never emit refresh requests while a corresponding request is in
flight, which causes VS Code to discard the respond of the request, as
well as to ensure that we keep prompting VS Code to send another request
if it spuriously decides not to respond to one of our refresh requests.
- The synthetic identifier of an `example` had the full declaration as
its (non-canonical synthetic) range. Since we need a reasonable position
for the identifier to insert an inlay hint for the auto-implicits of an
`example`, we change the (canonical synthetic) range of the synthetic
identifier to that of the `example` keyword.
- The semantic highlighting request handling is moved to a separate
file.

### Breaking changes
- The semantic highlighting request handler is not a pure request
handler anymore, but a stateful one. Notably, this means that clients
that extend the semantic highlighting of the Lean language server with
the `chainLspRequestHandler` function must now use the
`chainStatefulLspRequestHandler` function instead.
2025-02-04 17:36:49 +00:00
jrr6
8304bfe237 feat: allow anonymous equality proofs in match expressions (#6853)
This PR adds support for anonymous equality proofs in `match`
expressions of the form `match _ : e with ...`.

Closes #6759.
2025-02-04 16:09:21 +00:00
Luisa Cicolini
3b41e43264 feat: add BitVec.(getElem_umod_of_lt, getElem_umod, getLsbD_umod, getMsbD_umod) (#6795)
This PR adds theorems `BitVec.(getElem_umod_of_lt, getElem_umod,
getLsbD_umod, getMsbD_umod)`. For the defiition of these theorems we
rely on `divRec`, excluding the case where `d=0#w`, which is treated
separately because there is no infrastructure to reason about this case
within `divRec`. In particular, our implementation follows the mathlib
standard [where division by 0 yields
0](c7c1e091c9/src/Init/Data/BitVec/Basic.lean (L217)),
while in [SMTLIB this yields
`allOnes`](c7c1e091c9/src/Init/Data/BitVec/Basic.lean (L237)).

Co-authored by @bollu.

---------

Co-authored-by: Siddharth <siddu.druid@gmail.com>
2025-02-04 16:07:29 +00:00
Joachim Breitner
da2b91558e feat: improve simp trace formatting (#6951)
This PR adds line breaks and indentations to simp's trace messages to
make them easier to read (IMHO).
2025-02-04 15:47:01 +00:00
Jakob von Raumer
6d63f6305e feat: add Hashable instances for PUnit and PEmpty (#6866)
This PR adds missing `Hashable` instances for `PUnit` and `PEmpty`.
2025-02-04 14:40:31 +00:00
Kyle Miller
23bd9dfb09 fix: make rewrite/rw tactic abort on elaboration errors (#6891)
This PR modifies `rewrite`/`rw` to abort rewriting if the elaborated
lemma has any immediate elaboration errors (detected by presence of
synthetic sorries). Rewriting still proceeds if there are elaboration
issues arising from pending synthetic metavariables, like instance
synthesis failures. The purpose of the change is to avoid obscure
"tactic 'rewrite' failed, equality or iff proof expected ?m.5" errors
when for example a lemma does not exist.

This helps error reporting for the natural number game.
https://leanprover.zulipchat.com/#narrow/channel/113489-new-members/topic/Why.20doesn't.20add_left_comm.20work.20here.3F/near/497060022
2025-02-04 14:40:11 +00:00
Luisa Cicolini
ba2b9f63ad feat: add BitVec.(getMsbD, msb)_replicate, replicate_one (#6326)
This PR adds `BitVec.(getMsbD, msb)_replicate, replicate_one` theorems,
corrects a non-terminal `simp` in `BitVec.getLsbD_replicate` and
simplifies the proof of `BitVec.getElem_replicate` using the `cases`
tactic.

Co-authored with @bollu.

---------

Co-authored-by: Alex Keizer <alex@keizer.dev>
2025-02-04 13:55:53 +00:00
Eric Wieser
0d7e126a01 chore: re-land "perf: use C23's free_sized when available" (#6844)
Unreverts #6598

I'll combine #6825 into this before merging.
2025-02-04 12:43:56 +00:00
Kim Morrison
2385abc282 feat: align List/Array/Vector.insertIdx lemmas (#6948)
This PR completes the alignment of `List/Array/Vectors` lemmas for
`insertIdx`.
2025-02-04 12:23:27 +00:00
dependabot[bot]
baeb325611 chore: CI: bump dawidd6/action-download-artifact from 7 to 8 (#6903)
Bumps
[dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
from 7 to 8.
<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>v8</h2>
<h2>New features</h2>
<ul>
<li><code>use_unzip</code> boolean input (defaulting to false) - if set
to true, the action will use system provided <code>unzip</code> utility
for unpacking downloaded artifact(s) (note that the action will first
download the .zip artifact file, then unpack it and remove the .zip
file)</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>README: v7 by <a
href="https://github.com/haines"><code>@​haines</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/318">dawidd6/action-download-artifact#318</a></li>
<li>Unzip by <a
href="https://github.com/dawidd6"><code>@​dawidd6</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/325">dawidd6/action-download-artifact#325</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/haines"><code>@​haines</code></a> made
their first contribution in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/318">dawidd6/action-download-artifact#318</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v7...v8">https://github.com/dawidd6/action-download-artifact/compare/v7...v8</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="20319c5641"><code>20319c5</code></a>
README: v8</li>
<li><a
href="e58a9e5d14"><code>e58a9e5</code></a>
Unzip (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/325">#325</a>)</li>
<li><a
href="6d05268723"><code>6d05268</code></a>
node_modules: update</li>
<li><a
href="c03fb0c928"><code>c03fb0c</code></a>
README: v7 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/318">#318</a>)</li>
<li>See full diff in <a
href="https://github.com/dawidd6/action-download-artifact/compare/v7...v8">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=7&new-version=8)](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-02-04 10:41:44 +00:00
JovanGerb
2c6eacee30 fix: #discr_tree_simp_key shouldn't look into lhs of (#6936)
This PR fixes the `#discr_tree_simp_key` command, because it displays
the keys for just `lhs` in `lhs ≠ rhs`, but it should be `lhs = rhs`,
since that is what simp indexes.
2025-02-04 08:43:12 +00:00
Johan Commelin
412389f71f chore: add commit hash to error message in script/release_notes.py (#6944)
This PR adds a commit hash to the message that `script/release_notes.py`
prints when it can not find a PR number.
2025-02-04 06:10:08 +00:00
Johan Commelin
b385949dd4 chore: begin development cycle for v4.18.0 (#6943)
This PR begins the development cycle for v4.18.0.
2025-02-04 05:47:20 +00:00
Kim Morrison
80f824ce6b chore: more updates to release_checklist.py (#6941) 2025-02-04 05:38:42 +00:00
Leonardo de Moura
cd722567ed feat: improve grind case-split on Iff (#6940)
This PR improves how the `grind` tactic performs case splits on `p <->
q`.
2025-02-04 04:41:04 +00:00
Leonardo de Moura
6f8c13ba39 feat: improve grind error messages (#6937)
This PR improves `grind` error and trace messages by cleaning up local
declaration names.
2025-02-04 03:44:17 +00:00
Cameron Zwarich
cb6adb0259 fix: don't strip macro scopes in names of specialized LCNF decls (#6930)
This PR changes the name generation of specialized LCNF decls so they
don't strip macro scopes. This avoids name collisions for
specializations created in distinct macro scopes. Since the normal
Name.append function checks for the presence of macro scopes, we need to
use appendCore.
2025-02-04 03:43:18 +00:00
Kim Morrison
8b2a9cd74d chore: release_checklist.py checks if 'begin dev cycle' PR is needed (#6934)
This PR adds a check to `release_checklist.py`, to check whether
`CMakeLists.txt` on `master` has been updated, and if not reminds that a
"begin dev cycle" PR (as documented in `release_checklist.md` is needed.
2025-02-04 00:59:26 +00:00
Leonardo de Moura
b81dd3e7ad feat: expose_names tactic (#6935)
This PR adds the tactic `expose_names`. It creates a new goal whose
local context has been "exposed" so that every local declaration has a
clear, accessible name. If no local declarations require renaming, the
original goal is returned unchanged.

This tactic will be used to improve `try?`.
2025-02-04 00:53:31 +00:00
Kim Morrison
2477bb9705 chore: fix simp lemmas with bad keys 2025-02-04 11:47:08 +11:00
Kim Morrison
99f514dc5e chore: release_checklist.py checks for bump/v4.X.0 branches (#6933)
Some downstream repositories require a `bump/v4.X.0` branch to exist for
their integration CI. This PR updates `release_checklist.py` to check
for the existence of these branches, when needed.
2025-02-03 23:46:26 +00:00
Kim Morrison
838dcc496f chore: release notes use more paragraphs when needed (#6932)
Often PR descriptions end with a colon, followed by a new paragraph
containing a code block. Currently in the release notes these get
dropped. This PR attempts to include them. It's not particularly robust,
but I'll review during the next release.
2025-02-03 23:26:46 +00:00
Kim Morrison
800c60d77a chore: report total commits by category in release notes (#6931)
This PR reports a sentence like:

```quote
For this release, 201 changes landed. In addition to the 74 feature additions and 44 fixes listed below there were 7 refactoring changes, 5 documentation improvements and 62 chores.
```

in the automatically generated release notes.
2025-02-03 23:24:33 +00:00
Violetta Sim
a40bcee14f doc: add highlights section to v4.16.0 release notes (#6925)
This PR adds the highlights section to v4.16.0 release notes.

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
Co-authored-by: David Thrane Christiansen <david@davidchristiansen.dk>
Co-authored-by: Kim Morrison <kim@tqft.net>
2025-02-03 23:18:08 +00:00
Henrik Böving
142874d863 feat: bv_decide lower ||| to &&& and add and_eq_allOnes (#6741)
This PR implements two rules for bv_decide's preprocessor, lowering
`|||` to `&&&` in order to enable more term sharing + application of
rules about `&&&` as well as rewrites of the form `(a &&& b == -1#w) =
(a == -1#w && b == -1#w)` in order to preserve rewriting behavior that
already existed before this lowering.
2025-02-03 22:10:31 +00:00
Henrik Böving
c6cb2f52f0 feat: bv_decide implement BV_EQUAL_CONST_NOT rules (#6926)
This PR adds the BV_EQUAL_CONST_NOT rules from Bitwuzla to the
preprocessor of bv_decide.

Stacked on top of #6924
2025-02-03 18:19:34 +00:00
Sebastian Ullrich
d01e038210 feat: asynchronous code generation (#6770)
This PR enables code generation to proceed in parallel to further
elaboration.

It does not aim to make further refinements such as generating code for
different declarations in parallel or removing the dependency on kernel
checking.
2025-02-03 17:17:18 +00:00
Henrik Böving
a4ad409ae0 feat: bv_decide implement EQUAL_ITE rules (#6924)
This PR adds the EQUAL_ITE rules from Bitwuzla to the preprocessor of
bv_decide.
2025-02-03 15:51:03 +00:00
Joachim Breitner
a0776c33f0 refactor: FunInd: erase, not clear (#6923)
previously we did not include the “old” IH in the local context, so that
creating a MVar would not pick it up. But this always felt like a hack,
and prevented us from inferring types. So lets's try keeping them in the
context and using `withErasedFVars` only when creating metavariables.
2025-02-03 15:47:30 +00:00
Markus Himmel
ffa1e9e9ae doc: add recommended spellings for many term notations (#6886)
This PR adds recommended spellings for many notations defined in Lean
core, using the `recommended_spelling` command from #6869.
2025-02-03 13:46:39 +00:00
Kim Morrison
030daffba6 feat: LawfulBEq instances for Array and Vector (#6922)
This PR adds `LawfulBEq` instances for `Array` and `Vector`.

(Note this replaces a contribution of @mehbark to Batteries for the
LawfulBEq instance for Vector, which was dropped during the release
process due to conflicts. Thanks for that contribution!)
2025-02-03 13:44:25 +00:00
Kim Morrison
8f5418dbda chore: update release_checklist.md (#6919)
This PR updates the release checklist, reflecting changes noted while
@jcommelin has been releasing v4.16.0.

---------

Co-authored-by: Johan Commelin <johan@commelin.net>
2025-02-03 12:31:52 +00:00
Lean stage0 autoupdater
5930f430f4 chore: update stage0 2025-02-03 12:12:03 +00:00
Markus Himmel
0f5dceda4b feat: recommended_spelling command (#6869)
This PR adds a `recommended_spelling` command, which can be used for
recording the recommended spelling of a notation (for example, that the
recommended spelling of `∧` in identifiers is `and`). This information
is then appended to the relevant docstrings for easy lookup.

The function `Lean.Elab.Term.Doc.allRecommendedSpellings` may be used to
obtain a list of all recommended spellings, for example to create a
table that is part of a style guide. In the future, it might be
desirable to be able to partition such a table into smaller tables by
category. This can be added in a future PR.

The implementation is heavily inspired by #4490.
2025-02-03 11:15:52 +00:00
Johan Commelin
13e2a0291c chore: split RELEASES.md into releases/ folder (#6918)
This will make it more straightforward to check automatically that the
release notes in the repository match the release notes on github.
2025-02-03 11:04:09 +00:00
Joachim Breitner
8edaddd70c refactor: post-stage0 clean-up for #6898 (#6920) 2025-02-03 11:04:07 +00:00
Lean stage0 autoupdater
eab91e68c5 chore: update stage0 2025-02-03 10:10:49 +00:00
Joachim Breitner
a5a525f6a1 refactor: WF: create unfold theorems eagerly (#6898)
This PR changes how the unfold theorems for well-founded recursion are
created. They are created eagerly (anticipating that the behaivor may be
affected by simp sets soon), and without the detour of going through
equational theorems.
2025-02-03 09:05:22 +00:00
Vlad Tsyrklevich
bc54db2af1 chore: undo small change (#6917)
In #6818, I removed this small section of reductions from BitVec to Nat
since it seemed unnecessary. Since then, I saw that there are equivalent
sections for shiftLeft/sshiftRight that are more substantial and that I
should have not made this change.
2025-02-03 08:39:13 +00:00
Paul Reichert
6e7b76c097 feat: builtin as_aux_lemma tactic and tree_tac simp attribute (#6823)
This PR adds a builtin tactic and a builtin attribute that are required
for the tree map. The tactic, `as_aux_lemma`, can generally be used to
wrap the proof term generated by a tactic sequence into a separate
auxiliary lemma in order to keep the proof term small. This can, in rare
cases, be necessary if the proof term will appear multiple times in the
encompassing term. The new attribute, `Std.Internal.tree_tac`, is
internal and should not be used outside of `Std`.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-02-03 08:34:29 +00:00
Johan Commelin
a1d522ab14 chore: add a few lines to the v4.16.0 release notes (#6916) 2025-02-03 08:22:33 +00:00
Kim Morrison
809ae9aac3 chore: use --since in release_notes.py (#6915)
The semantics of `release_notes.py` was slightly confusing. It is meant
to be run a `script/release_notes.py v4.15.0` on the `releases/v4.16.0`
branch. To help, I've changed the usage to `script/release_notes.py
--since v4.15.0`.
2025-02-03 08:03:40 +00:00
Kim Morrison
832d7c500d chore: fix release_checklist.py tag lookup bug (#6913) 2025-02-03 06:07:53 +00:00
Kim Morrison
f6df23f2a7 feat: align findX theorems across List/Array/Vector (#6912)
This PR aligns current coverage of `find`-type theorems across
`List`/`Array`/`Vector`. There are still quite a few holes in this API,
which will be filled later.
2025-02-03 04:36:20 +00:00
Leonardo de Moura
1abac9aca6 chore: improve grind case-split trace (#6911) 2025-02-03 04:00:45 +00:00
Leonardo de Moura
40d9f49d68 chore: improve grind pattern pretty printer (#6910) 2025-02-03 03:04:33 +00:00
Leonardo de Moura
15f1aeed6e test: grind_guide.lean (#6908) 2025-02-03 02:11:41 +00:00
Kim Morrison
c193195a05 chore: fixing short-circuiting issue in Ordering.then (#6907)
Thanks to @PatrickMassot for noticing the bug, and @digama0 for
diagnosing, fixing, and testing.
2025-02-03 00:44:45 +00:00
Kyle Miller
1f6abcaf6c feat: make all app unexpanders respond to pp.tagAppFns (#6730)
This PR changes how app unexpanders are invoked. Before the ref was
`.missing`, but now the ref is the head constant's delaborated syntax.
This way, when `pp.tagAppFns` is true, then tokens in app unexpanders
are annotated with the head constant. The consequence is that in docgen,
tokens will be linkified. This new behavior is consistent with how
`notation` defines app unexpanders.

In a followup PR we can slightly simplify the `notation` unexpander
macro to not set the ref.
2025-02-02 23:29:12 +00:00
Kyle Miller
89d897a34d feat: make coeFun delaborator respect pp.tagAppFns (#6729)
This PR makes the pretty printer for `.coeFun`-tagged functions respect
`pp.tagAppFns`. The effect is that in docgen, when an expression pretty
prints as `f x y z` with `f` a coerced function, then if `f` is a
constant it will be linkified.
2025-02-02 22:54:23 +00:00
Kyle Miller
3fb264b569 feat: modify delaborator to tag generalized field notation (#6703)
This PR modifies the delaborator so that in `pp.tagAppFns` mode,
generalized field notation is tagged with the head constant. The effect
is that docgen documentation will linkify dot notation. Internal change:
now formatted `rawIdent` can be tagged.
2025-02-02 21:34:49 +00:00
Sebastian Ullrich
d68c2ce28b chore: remove stray profiler option from test 2025-02-02 09:54:57 +01:00
Leonardo de Moura
64b5bedc8c feat: try? tactic (#6905)
This PR adds the `try?` tactic. This is the first draft, but it can
already solve examples such as:
```lean
example (e : Expr) : e.simplify.eval σ = e.eval σ := by
  try?
```
in `grind_constProp.lean`. In the example above, it suggests:
```lean
induction e using Expr.simplify.induct <;> grind?
``` 
In the same test file, we have
```lean
example (σ₁ σ₂ : State) : σ₁.join σ₂ ≼ σ₂ := by
  try?
```
and the following suggestion is produced
```lean
induction σ₁, σ₂ using State.join.induct <;> grind? 
```
2025-02-02 06:37:49 +00:00
Leonardo de Moura
38086a83cb feat: add Grind.Config.verbose and reportIssue! macro (#6904)
This PR adds the `grind` configuration option `verbose`. For example,
`grind -verbose` disables all diagnostics. We are going to use this flag
to implement `try?`.
2025-02-01 21:12:00 +00:00
Joachim Breitner
deb3299263 refactor: simpMatch to not etaStruct (#6901)
This PR changes the `simpMatch` function, used inside the equation
generator for WF-rec functions, to not do eta-expansion.

This makes the process a bit more robust and disciplined, and avoids
removing match-statements (and introduce projections and dependencies)
that we'd rather split instead.

Also adds more tracing to the equational theorem generator.

Extracted from #6898.
2025-02-01 19:04:05 +00:00
Malvin Gattinger
2b0e75748b doc: correct docstring for TransGen.tail and TransGen.trans (#6900)
This PR only modifies docstrings and should fix issue #6899
2025-02-01 13:52:52 +00:00
Vlad Tsyrklevich
ca96ea331e feat: teach bv_normalize to rewrite subtractions to additions (#6890)
This PR teaches bv_normalize to replace subtractions on one side of an
equality with an addition on the other side, this re-write eliminates a
not + addition in the normalized form so it is easier on the solver.

Note that I also make a point to normalize (1 + ~~~x) to (~~~x + 1) to
limit the amount of boilerplate symmetry theorems we require.
2025-02-01 10:56:54 +00:00
Leonardo de Moura
66471ba6e2 feat: attributes [grind =>] and [grind <=] (#6897)
This PR adds the new attributes `[grind =>]` and `[grind <=]` for
controlling pattern selection and minimizing the number of places where
we have to use verbose `grind_pattern` command. It also fixes a bug in
the new pattern selection procedure, and improves the automatic pattern
selection for local lemmas.

The tests `grind_constProp.lean` and `no_grind_constProp.lean` are the
same use case with and without `grind`.
2025-02-01 04:41:19 +00:00
Leonardo de Moura
425c7a12d0 fix: grind issues exposed by grind_constProp (#6895)
This PR fixes a few `grind` issues exposed by the `grind_constProp.lean`
test.
- Support for equational theorem hypotheses created before invoking
`grind`. Example: applying an induction principle.s
- Support of `Unit`-like types. 
- Missing recursion depth checks.
2025-02-01 01:35:12 +00:00
Henrik Böving
1776758971 perf: inline a few functions in the bv_decide circuit cache (#6889)
This PR inlines a few functions in the `bv_decide` circuit cache.
2025-01-31 22:25:15 +00:00
Leonardo de Moura
5286b21126 feat: bug in pattern selection heuristic in grind (#6892)
This PR fixes a bug in the pattern selection heuristic used in `grind`.
It was unfolding definitions/abstractions that were not supposed to be
unfolded. See `grind_constProp.lean` for examples affected by this bug.
2025-01-31 20:22:49 +00:00
Leonardo de Moura
5900f39638 feat: add [grind intro] attribute (#6888)
This PR adds the `[grind intro]` attribute. It instructs `grind` to mark
the introduction rules of an inductive predicate as E-matching theorems.
2025-01-31 17:03:54 +00:00
Sebastian Ullrich
b3a8d5b04e feat: async modes for environment access (#6852)
This PR allows environment extensions to opt into access modes that do
not block on the entire environment up to this point as a necessary
prerequisite for parallel proof elaboration.
2025-01-31 16:35:50 +00:00
Vlad Tsyrklevich
a3f7d44593 chore: small clean-up in DivModLemmas (#6877)
As a follow-up to #6718, refactor a few bmod proofs to be shorter and
exactly match their emod* equivalents for uniformity.
2025-01-31 16:17:16 +00:00
Vlad Tsyrklevich
7bd12c71c8 feat: add or/and/xor lemmas for BitVec/bv_normalize (#6872)
This PR adds lemmas for xor injectivity and when and/or/xor equal
allOnes or zero. Then I plumb support for the new lemmas through to
bv_normalize.
2025-01-31 13:27:43 +00:00
François G. Dorais
9b5813eeda feat: add BitVec lemmas about msb and shiftConcat (#6875)
This PR adds a lemma relating `msb` and `getMsbD`, and three lemmas
regarding `getElem` and `shiftConcat`. These lemmas were needed in
[Batteries#1078](https://github.com/leanprover-community/batteries/pull/1078)
and the request to upstream was made in the review of that PR.

---------

Co-authored-by: Siddharth <siddu.druid@gmail.com>
2025-01-31 12:07:57 +00:00
Markus Himmel
fe3a78d262 fix: name of Int.tdiv in HDiv.hDiv docstring (#6885)
This PR fixes the name of the truncating integer division function in
the `HDiv.hDiv` docstring (which is shown when hovering over `/`). It
was changed from `Int.div` to `Int.tdiv` in #5301.
2025-01-31 08:52:22 +00:00
Kim Morrison
6c2573fc38 feat: alignment of lemmas about monadic functions on List/Array/Vector (#6883)
This PR completes the alignment of lemmas about monadic functions on
`List/Array/Vector`. Amongst other changes, we change the simp normal
form from `List.forM` to `ForM.forM`, and correct the definition of
`List.flatMapM`, which previously was returning results in the incorrect
order. There remain many gaps in the verification lemmas for monadic
functions; this PR only makes the lemmas uniform across
`List/Array/Vector`.
2025-01-31 07:25:24 +00:00
Paul Reichert
ad48761032 feat: add simple Ordering lemmas (#6821)
This PR adds basic lemmas about `Ordering`, describing the interaction
of `isLT`/`isLE`/`isGE`/`isGT`, `swap` and the constructors.
Additionally, it refactors the instance derivation code such that a
`LawfulBEq Ordering` instance is also derived automatically.

Some of these lemmas are helpful for the `TreeMap` verification.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-01-31 06:32:53 +00:00
Johan Commelin
0a42a47ea8 chore: mark Mul.mul and HMul.hMul as match_pattern (#6863)
This PR allows fixing regressions in mathlib introduced in
nightly-2024-02-25 by allowing the use of `x * y` in match patterns.
There are currently 11 instances in mathlib explicitly flagging the lack
of this match pattern.

This issue was previously pointed out in the following Zulip threads:

-
https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Algebra.2EFree/near/321482426
-
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/match_pattern.20attribute.20on.20Mul.2Emul/near/321505298
-
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/.40.5Bmatch_pattern.5D.20for.20basic.20binary.20operators/near/423734085
-
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Mul.20match_pattern/near/430635623
2025-01-31 05:39:33 +00:00
Leonardo de Moura
d70a596887 feat: hide grind auxiliary gadgets in messages (#6882)
This PR ensures `grind` auxiliary gadgets are "hidden" in error and
diagnostic messages.
2025-01-31 05:10:59 +00:00
Cameron Zwarich
3331ed9bb1 fix: add Float32 to LCNF.builtinRuntimeTypes list (#6837)
This PR adds Float32 to the LCNF builtinRuntimeTypes list. This was
missed during the initial Float32 implementation, but this omission has
the side effect of lowering Float32 to obj in the IR.
2025-01-31 04:53:49 +00:00
Leonardo de Moura
b3be4ea66e feat: include Case analyses trace in the grind error message (#6881)
This PR improves the `grind` error message by including a trace of the
terms on which `grind` applied `cases`-like operations.
2025-01-31 04:22:50 +00:00
Leonardo de Moura
b329c4b5db feat: improve pattern selection heuristic in grind (#6880)
This PR improves the E-matching pattern selection heuristic used in
`grind`.
2025-01-31 02:16:15 +00:00
Leonardo de Moura
a2155e0741 fix: bug in mkMatchCondProf? in grind (#6879)
This PR fixes a bug in `mkMatchCondProf?` used by the `grind` tactic.
This bug was introducing a failure in the test `grind_constProp.lean`.
2025-01-31 01:18:49 +00:00
Kim Morrison
40eefb1df6 feat: alignment of List/Array/Vector lemmas about range, range', zipIdx (#6878)
This PR completes alignments of `List/Array/Vector` lemmas about
`range`, `range'`, and `zipIdx`.
2025-01-31 00:06:51 +00:00
Leonardo de Moura
146f6e6b2f feat: use profileitM in grind (#6876) 2025-01-30 22:15:27 +00:00
Kim Morrison
52a27697be feat: Cooper resolution (#6862)
This PR defines Cooper resolution with a divisibility constraint as
formulated in
"Cutting to the Chase: Solving Linear Integer Arithmetic" by Dejan
Jovanović and Leonardo de Moura,
DOI 10.1007/s10817-013-9281-x.
2025-01-30 18:47:14 +00:00
Leonardo de Moura
270934cbb6 test: constProp using grind (#6873)
It has many TODOs
2025-01-30 18:28:54 +00:00
Leonardo de Moura
731551d670 chore: cleanup grind tests (#6871) 2025-01-30 17:51:45 +00:00
Leonardo de Moura
2fedd7144a feat: normalize != and == in grind (#6870)
This PR adds two new normalization steps in `grind` that reduces `a !=
b` and `a == b` to `decide (¬ a = b)` and `decide (a = b)`,
respectively.
2025-01-30 16:00:18 +00:00
Kim Morrison
5bd75695f4 feat: align List/Array/Vector eraseP/erase/eraseIdx lemmas (#6868)
This PR completes the alignment across `List/Array/Vector` of lemmas
about the `eraseP/erase/eraseIdx` operations.
2025-01-30 12:29:55 +00:00
Joachim Breitner
cd62b8cd80 refactor: WF.Eqns: rewrite fix without duplicating F (#6859)
This PR changes how WF.Eqns unfolds the fixpoint. Instead of delta'ing
until we have `fix`, and then blindly applying `fix_eq`, we delta one
step less and preserve the function on the right hand side. This leads
to smaller terms in the next step, so easier to debug, possibly faster,
possibly more robust.
2025-01-30 10:23:18 +00:00
Vlad Tsyrklevich
dc445d7af6 feat: add BitVec multiplication simp lemmas (#6718)
This PR adds BitVec lemmas required to cancel multiplicative negatives,
and plumb support through to bv_normalize to make use of this result in
the normalized twos-complement form.

I include some bmod lemmas I found useful to prove this result, the two
helper lemmas I add use the same naming/proofs as their emod
equivalents.
2025-01-30 08:24:18 +00:00
Kim Morrison
e7d8948fa6 feat: lemmas relating findIdx?/findFinIdx?/idxOf?/findIdxOf?/eraseP/erase on List and Array (#6864)
This PR adds lemmas relating the operations on
findIdx?/findFinIdx?/idxOf?/findIdxOf?/eraseP/erase on List and on
Array. It's preliminary to aligning the verification lemmas for
`find...` and `erase...`.
2025-01-30 07:04:50 +00:00
Leonardo de Moura
e922edfc21 feat: Bool.and, Bool.or, and Bool.not propagation in grind (#6861)
This PR adds propagation rules for `Bool.and`, `Bool.or`, and `Bool.not`
to the `grind` tactic.
2025-01-30 02:47:06 +00:00
Kim Morrison
5b1c6b558a feat: align take/drop/extract across List/Array/Vector (#6860)
This PR makes `take`/`drop`/`extract` available for each of
`List`/`Array`/`Vector`. The simp normal forms differ, however: in
`List`, we simplify `extract` to `take+drop`, while in `Array` and
`Vector` we simplify `take` and `drop` to `extract`. We also provide
`Array/Vector.shrink`, which simplifies to `take`, but is implemented by
repeatedly popping. Verification lemmas for `Array/Vector.extract` to
follow in a subsequent PR.
2025-01-30 01:24:25 +00:00
Kim Morrison
21e8a99eff feat: refactor of find functions on List/Array/Vector (#6833)
This PR makes the signatures of `find` functions across
`List`/`Array`/`Vector` consistent. Verification lemmas will follow in
subsequent PRs.

We were previously quite inconsistent about the signature of
`indexOf`/`findIdx` functions across `List` and `Array`. Moreover, there
are still quite large gaps in the verification lemma coverage for these
even at the `List` level.

My intention is to make the signatures consistent by providing:
`findIdx` / `findIdx?` / `findFinIdx?` (these all take a predicate, and
return respectively a `Nat`, `Option Nat`, `Option (Fin l.length)`) and
similarly `idxOf` / `idxOf?` / `finIdxOf?` (which look for an element)
for each of List/Array/Vector. I've seen enough examples by now where
each variant is genuinely the most convenient at the call-site, so I'm
going to accept the cost of having many closely related functions.
*Hopefully* for the verification lemmas we can simp all of these into
"projections" of the `Option (Fin l.length)` versions, and then only
have to specify that.

However, I will not plan on immediately either filling in the missing
verification lemmas (or even deciding what the simp normal forms
relating these operations are), and just reach parity amongst
List/Array/Vector for what is already there.
2025-01-30 01:14:21 +00:00
Leonardo de Moura
49fe87e0d1 feat: missing propagation rules in grind (#6858)
This PR adds new propagation rules for `decide` and equality in `grind`.
It also adds new tests and cleans old ones
2025-01-29 23:40:33 +00:00
Henrik Böving
61c843a3c7 refactor: pull out some LRAT functionality from bv_decide (#6856)
This PR refactors a bit of the functionality in bv_decide's frontend to
make it accessible for external users.
2025-01-29 20:47:47 +00:00
Lean stage0 autoupdater
ca3c7571e5 chore: update stage0 2025-01-29 19:45:27 +00:00
Leonardo de Moura
5075153c15 feat: better support for inductive predicates in grind (#6854)
This PR adds a convenience for inductive predicates in `grind`. Now,
give an inductive predicate `C`, `grind [C]` marks `C` terms as
case-split candidates **and** `C` constructors as E-matching theorems.
Here is an example:
```lean
example {B S T s t} (hcond : B s) : (ifThenElse B S T, s) ==> t → (S, s) ==> t := by
  grind [BigStep]
```
Users can still use `grind [cases BigStep]` to only mark `C` as a case
split candidate.
2025-01-29 18:17:34 +00:00
Henrik Böving
c7dec60428 feat: support UIntX and USize in bv_decide (#6711)
This PR adds support for `UIntX` and `USize` in `bv_decide` by adding a
preprocessor that turns them into `BitVec` of their corresponding size.
2025-01-29 15:41:38 +00:00
Henrik Böving
41fe7bc71a feat: bv_normalize rewrite shifts by BitVec const to shift by Nat const (#6851)
This PR makes `bv_normalize` rewrite shifts by `BitVec` constants to
shifts by `Nat` constants. This is part of the greater effort in
providing good support for constant shift simplification in
`bv_normalize`.
2025-01-29 15:17:39 +00:00
Arthur Adjedj
2c00f8fe2f fix: consume mdata in casesOnStuckLHS when checking that major is fvar (#6791)
This PR fixes #6789 by ensuring metadata generated for inaccessible
variables in pattern-matches is consumed in `casesOnStuckLHS`
accordingly.

Closes #6789
2025-01-29 14:32:11 +00:00
Sebastian Ullrich
68653297d1 chore: re-enable Lake 2025-01-29 15:59:05 +01:00
Sebastian Ullrich
729d6e5d5c chore: update stage0 2025-01-29 15:59:05 +01:00
Sebastian Ullrich
c6677e0b6f perf: avoid environment extension indirection 2025-01-29 15:59:05 +01:00
Vlad Tsyrklevich
0c43f05047 feat: add BitVec add_self/self_add lemmas (#6848)
This PR adds simp lemmas proving `x + y = x ↔ x = 0` for BitVec, along
with symmetries, and then adds these to the bv_normalize simpset.
2025-01-29 13:52:57 +00:00
Kim Morrison
3c8cf7a905 chore: remove unneeded LawfulBEq hypotheses (#6847) 2025-01-29 12:24:36 +00:00
Kim Morrison
51b56b20ec feat: missing monadic functions on List/Array/Vector (#6845)
This PR adds missing monadic higher order functions on
`List`/`Array`/`Vector`. Only the most basic verification lemmas
(relating the operations on the three container types) are provided for
now.
2025-01-29 12:19:30 +00:00
Vlad Tsyrklevich
5c0231f508 feat: add BitVec add/sub injectivity lemmas (#6828)
This PR adds add/sub injectivity lemmas for BitVec, and then adds
specialized forms with additional symmetries for the `bv_normalize`
normal form.

Since I need `neg_inj`, I add `not_inj`/`neg_inj` at once, and use it in
`BitVec.not_beq_not` instead of re-proving it.
2025-01-29 10:35:44 +00:00
Sebastian Ullrich
a35bf7ee4c chore: revert "perf: use C23's free_sized when available" (#6841)
Reverts leanprover/lean4#6598, which broke Windows CI
2025-01-29 09:11:23 +00:00
Kim Morrison
bc234f9f8d feat: align List/Array/Vector.zip/zipWith/zipWithAll/unzip (#6840)
This PR completes the alignment of
`List/Array/Vector.zip/zipWith/zipWithAll/unzip` lemmas.
2025-01-29 07:58:17 +00:00
Leonardo de Moura
08ec2541c7 feat: add support for constructors and axioms to the grind E-matching module (#6839)
This PR ensures `grind` can use constructors and axioms for heuristic
instantiation based on E-matching. It also allows patterns without
pattern variables for theorems such as `theorem evenz : Even 0`.
2025-01-29 05:22:05 +00:00
Kim Morrison
e05131122b feat: finish aligning List/Array/Vector.ofFn lemmas (#6838)
This PR completes aligning the (limited) verification API for
`List/Array/Vector.ofFn`.
2025-01-29 04:53:33 +00:00
Kim Morrison
e4749eb6b5 chore: preparation for Array.erase lemmas (#6836)
This PR rearranges some material, and adds some missing lemmas, in
preparation for aligning `List/Array/Vector.erase(P)`.
2025-01-29 04:07:51 +00:00
Kim Morrison
84311122ac feat: align List/Array/Vector lemmas for isEqv and == (#6831)
This PR completes the alignment of `List/Array/Vector` lemmas about
`isEqv` and `==`.
2025-01-29 03:12:02 +00:00
Kim Morrison
c93012faa1 feat: add Vector.mapM, ForIn/ToStream instances (#6835)
This PR fills some gaps in the `Vector` API, adding `mapM`, `zip`, and
`ForIn'` and `ToStream` instances.
2025-01-29 02:58:40 +00:00
Leonardo de Moura
aa65107523 feat: "performance" counters for grind (#6834)
This PR adds "performance" counters (e.g., number of instances per
theorem) to `grind`. The counters are always reported on failures, and
on successes when `set_option diagnostics true`.
2025-01-29 02:12:31 +00:00
Kim Morrison
07e2b7d913 chore: update some Array doc-strings (#6832) 2025-01-29 01:32:41 +00:00
Kim Morrison
9b5fadd275 chore: remove unnecessary simp priorities (#6812)
This PR remove simp priorities that are not needed. Some of these will
probably cause complaints from the `simpNF` linter downstream in
Batteries, which I will re-address separately.
2025-01-28 23:50:33 +00:00
Kim Morrison
7e8af0fc9d feat: rename List.enum(From) to List.zipIdx, and Array/Vector.zipWithIndex to zipIdx (#6800)
This PR uniformizes the naming of `enum`/`enumFrom` (on `List`) and
`zipWithIndex` (on `Array` on `Vector`), replacing all with `zipIdx`. At
the same time, we generalize to add an optional `Nat` parameter for the
initial value of the index (which previously existed, only for `List`,
as the separate function `enumFrom`).
2025-01-28 23:34:30 +00:00
Kim Morrison
f10d0d07d9 feat: lemmas about BitVec.setWidth (#6808)
This PR adds simp lemmas replacing `BitVec.setWidth'` with `setWidth`,
and conditionally simplifying `setWidth v (setWidth w v)`.

---------

Co-authored-by: Tobias Grosser <tobias@grosser.es>
2025-01-28 23:33:45 +00:00
Joachim Breitner
312759e369 fix: injectivity theorems for more prelude inductives (#6826)
This PR adds injectivity theorems for inductives that did not get them
automatically (because they are defined too early) but also not yet
manuall later.

It also adds a test case to notice when new ones fall through.o

It does not add them for clearly meta-programming related types that are
not yet defined in `Init/Core.lean`, and uses `#guard_msgs` as an
allowlist.

---------

Co-authored-by: Kim Morrison <scott.morrison@gmail.com>
2025-01-28 23:09:28 +00:00
Vlad Tsyrklevich
1d9439752c feat: teach bv_normalize that (x >> x) = 0 (#6818)
This PR adds a BitVec lemma that `(x >> x) = 0` and plumbs it through to
bv_normalize. I also move some theorems I found useful to the top of the
ushiftRight section.
2025-01-28 20:56:21 +00:00
Leonardo de Moura
9f5a9a071a feat: add %reset_grind_attrs (#6824)
This PR introduces the auxiliary command `%reset_grind_attrs` for
debugging purposes. It is particularly useful for writing self-contained
tests.
2025-01-28 18:29:02 +00:00
Leonardo de Moura
26bc8c5b2a feat: builtin case splits for grind (#6822)
This PR adds a few builtin case-splits for `grind`. They are similar to
builtin `simp` theorems. They reduce the noise in the tactics produced
by `grind?`.
2025-01-28 17:30:36 +00:00
Kim Morrison
eea2d49078 chore: lower List/Array/Vector.mem_map simp priority (#6815)
This PR lowers the simp priority of `List/Array/Vector.mem_map`, as
downstream in Mathlib many lemmas currently need their priority raised
to fire before this.
2025-01-28 12:23:24 +00:00
Markus Himmel
f9d3deaafe perf: improve elaboration performance of Std.Data.DHashMap.Internal.RawLemmas (#6814)
This PR optimizes the proofs in the internal file
`Std/Data/DHashMap/Internal/RawLemmas.lean` so that the file is quicker
to elaborate.
2025-01-28 11:04:42 +00:00
Sebastian Ullrich
e4364e747f chore: temporarily disable async in server (#6813)
... pending an interruption bug fix and further testing
2025-01-28 10:42:17 +00:00
Eric Wieser
6aa6407af1 perf: use C23's free_sized when available (#6598)
See https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2699.htm for an
explanation of this feature.

---------

Co-authored-by: Chris Kennelly <ckennelly@google.com>
2025-01-28 10:17:15 +00:00
Eric Wieser
9247206c0e doc: clarify that lean_initialize_runtime_module is implied by lean_initialize (#6677)
Calling both runs the initializers twice, resulting in a memory leak
2025-01-28 10:12:59 +00:00
Vlad Tsyrklevich
c7c1e091c9 feat: add BitVec comparison lemmas to bv_normalize (#6799)
This PR adds a number of simple comparison lemmas to the top/bottom
element for BitVec. Then they are applied to teach bv_normalize that
`(a<1) = (a==0)` and to remove an intermediate proof that is no longer
necessary along the way.
2025-01-28 08:48:11 +00:00
Leonardo de Moura
20c616503a feat: add grind? (#6810)
This PR implements a basic `grind?` tactic companion for `grind`. We
will add more bells and whistles later.
2025-01-28 04:17:25 +00:00
Kim Morrison
104b3519d7 feat: add Fin.ofNat'_zero (#6806)
This PR adds a simp lemma for `Fin.ofNat'`.
2025-01-28 02:00:01 +00:00
Kim Morrison
d8fcfead97 feat: add LawfulMonad helper simp lemmas (#6805)
This PR adds to helper lemmas in the `LawfulMonad` namespace, which
sometimes fire via `simp` when the original versions taking
`LawfulApplicative` or `Functor` do not fire.
2025-01-28 01:59:55 +00:00
Kim Morrison
d0b947bf52 chore: add @[simp] to Option.not_mem_none (#6804)
This PR improves simp lemma confluence.
2025-01-28 01:59:47 +00:00
Mac Malone
5f0fea60a6 refactor: lake: deprecate -U (#6798)
This PR deprecates the `-U` shorthand for the `--update` option.

It is likely the `-U` option will be used for something different in the
future, so deprecating it now seems wise.
2025-01-28 01:54:55 +00:00
Mac Malone
3e54597db4 feat: lake query (#6323)
This PR adds a new Lake CLI command, `lake query`, that both builds
targets and outputs their results. It can produce raw text or JSON
-formatted output (with `--json` / `-J`).

This PR removes the `lean.` prefix from the module import facets (for
ease-of-use in the `lake query` CLII). It also renames the package
`deps` facet, `transDeps`. The new `deps` facet just returns the
package's direct dependencies.
2025-01-28 01:43:03 +00:00
Kim Morrison
eb1c9b9ab2 chore: two BitVec lemmas that help simp confluence (#6807)
This PR adds two simple `BitVec` lemmas which improve `simp` local
confluence.
2025-01-28 01:12:05 +00:00
Kim Morrison
4d66e7bdc0 feat: add List.modifyHead_dropLast (#6803)
This PR adds the simp lemma `List.modifyHead_dropLast`. This is one of
many small PRs that will improve simp lemma confluence.
2025-01-28 00:25:58 +00:00
Kim Morrison
f8660485d7 feat: Option.elim_pmap, improving simp confluence (#6802)
This PR adds the simp lemma `Option.elim_pmap`. This is one of many
small PRs that will improve simp lemma confluence.
2025-01-28 00:21:10 +00:00
Leonardo de Moura
64766f8724 fix: offset constraint propagation in grind (#6801)
This PR fixes a bug in the exhaustive offset constraint propagation
module used in `grind`.
2025-01-27 23:43:31 +00:00
Marc Huisinga
f64bce6ef1 fix: auto-completion performance regression (#6794)
This PR fixes a significant auto-completion performance regression that
was introduced in #5666, i.e. v4.14.0.

#5666 introduced tactic docstrings, which were attempted to be collected
for every single completion item. This is slow for hundreds of thousands
of completion items. To fix this, this PR moves the docstring
computation into the completion item resolution, which is only called
when users select a specific completion item in the UI.

A downside of this approach is that we currently can't test completion
item resolution, so we lose a few tests that cover docstrings in
completions in this PR.
2025-01-27 21:15:09 +00:00
Marc Huisinga
0160aa1a89 test: identifier completion benchmark (#6796)
Adds a basic identifier completion benchmark so that bugs like the one
in #6794 are caught earlier.
2025-01-27 19:31:32 +00:00
Joachim Breitner
3418d6db8e fix: more robust equational theorems generation for partial_fixpoint (#6790)
This PR fixes an issue with the generation of equational theorems from
`partial_fixpoint` when case-splitting is necessary. Fixes #6786.
2025-01-27 14:00:55 +00:00
Vlad Tsyrklevich
3aea0fd810 feat: add comparison lemmas to bv_normalize (#6788)
This PR teaches bv_normalize that !(x < x) and !(x < 0).
2025-01-27 13:44:44 +00:00
Joachim Breitner
4ca98dcca2 doc: typos in partial_fixpoint related docstrings (#6787)
H'T David
2025-01-27 09:43:09 +00:00
Markus Himmel
55b0bed5df doc: standard library vision and call for contributions (#6762) 2025-01-27 09:07:02 +00:00
Henrik Böving
d86a408944 feat: bv_decide can reason about equality of structures (#6740)
This PR extends `bv_decide`'s structure reasoning support for also
reasoning about equalities of supported structures.
2025-01-27 08:11:43 +00:00
Leonardo de Moura
69a73a18fb feat: grind? infrastructure (#6785)
This PR adds infrastructure for the `grind?` tactic. It also adds the
new modifier `usr` which allows users to write `grind only [usr
thmName]` to instruct `grind` to only use theorem `thmName`, but using
the patterns specified with the command `grind_pattern`.
2025-01-27 01:31:25 +00:00
Leonardo de Moura
98bd162ad4 feat: close goals using match-expression conditions in grind (#6783)
This PR adds support for closing goals using `match`-expression
conditions that are known to be true in the `grind` tactic state.
`grind` can now solve goals such as:
```lean
def f : List Nat → List Nat → Nat
  | _, 1 :: _ :: _ => 1
  | _, _ :: _ => 2
  | _, _  => 0

example : z = a :: as → y = z → f x y > 0
```
Without `grind`, we would use the `split` tactic. The first two goals,
corresponding to the first two alternatives, are closed using `simp`,
and the the third using the `match`-expression condition produced by
`split`. The proof would proceed as follows.
```lean
example : z = a :: as → y = z → f x y > 0 := by
  intros
  unfold f
  split
  next => simp
  next => simp
  next h =>
    /-
    ...
    _ : z = a :: as
    _ : y = z
    ...
    h : ∀ (head : Nat) (tail : List Nat), y = head :: tail → False
    |- 0 > 0
    -/
    subst_vars
    /-
    ...
    h : ∀ (head : Nat) (tail : List Nat), a :: as = head :: tail → False
    |- 0 > 0
    -/
    have : False := h a as rfl
    contradiction
```
Here is the same proof using `grind`.
```lean
example : z = a :: as → y = z → f x y > 0 := by
  grind [f.eq_def]
```
2025-01-26 17:13:11 +00:00
Joachim Breitner
ba95dbc36b feat: zetaUnused option (implementation) (#6755)
This PR implements the `zetaUnused` simp and reduction option (added in
#6754).

True by default, and implied by `zeta`, this can be turned off to make
simp even more careful about preserving the expression structure,
including unused let and have expressions.

Breaking change: The `split` tactic no longer removes unused let and
have expressions as a side-effect, in rare cases this may break proofs.
`dsimp only` can be used to remove unused have and let expressions.
2025-01-26 11:14:12 +00:00
Mac Malone
6278839534 refactor: lake: all targets produce jobs (#6780)
This PR makes all targets and all `fetch` calls produce a `Job` of some
value. As part of this change, facet definitions (e.g., `library_data`,
`module_data`, `package_data`) and Lake type families (e.g.,
`FamilyOut`) should no longer include `Job` in their types (as this is
now implicit).
2025-01-26 05:03:07 +00:00
Leonardo de Moura
849a252b20 fix: case split on data in grind (#6781)
This PR fixes the support for case splitting on data in the `grind`
tactic. The following example works now:
```lean
inductive C where
  | a | b | c

def f : C → Nat
  | .a => 2
  | .b => 3
  | .c => 4

example : f x > 1 := by
  grind [
      f, -- instructs `grind` to use `f`-equation theorems, 
      C -- instructs `grind` to case-split on free variables of type `C`
  ]
```
2025-01-26 02:14:08 +00:00
Leonardo de Moura
ca56c5ecc0 feat: improve support for match-expressions in grind (#6779)
This PR improves the support for `match`-expressions in the `grind`
tactic.
2025-01-26 00:50:29 +00:00
Leonardo de Moura
d10666731c fix: assignment for offset constraints in grind (#6778)
This PR fixes the assignment produced by `grind` to satisfy the offset
constraints in a goal.
2025-01-25 23:21:53 +00:00
Leonardo de Moura
6dbb54d221 fix: offset terms internalization (#6777)
This PR fixes a bug in the internalization of offset terms in the
`grind` tactic. For example, `grind` was failing to solve the following
example because of this bug.
```lean
example (f : Nat → Nat) : f (a + 1) = 1 → a = 0 → f 1 = 1 := by
  grind
```
2025-01-25 21:14:48 +00:00
Cameron Zwarich
cc260dd231 feat: support for csimp theorems in toLCNF (#6757)
This PR adds support for applying crimp theorems in toLCNF.
2025-01-25 21:07:08 +00:00
Leonardo de Moura
9565334c0e fix: Grind.MatchCond in checkParents (#6776)
This PR fixes the `checkParents` sanity checker used in `grind`. It did
not have support for checking the auxiliary gadget `Grind.MatchCond`.
2025-01-25 19:53:26 +00:00
Markus Himmel
2fa38e6ceb fix: suggest correct trace option name in partial_fixpoint error message (#6774)
This PR fixes a `partial_fixpoint` error message to suggest the option
`trace.Elab.Tactic.monotonicity` rather than the nonexistent
`trace.Elab.Tactic.partial_monotonicity`.
2025-01-25 14:42:15 +00:00
Markus Himmel
056d1dbeef fix: typo in partial_fixpoint docstring (#6775)
This PR fixes a typo in the `partial_fixpoint` hover docstring.
2025-01-25 14:41:52 +00:00
Rob23oba
e8bbba06b7 fix: fix builtin simproc Nat.reduceAnd (#6773)
This PR fixes a typo that prevented `Nat.reduceAnd` from working
correctly.

Closes #6772
2025-01-25 12:57:24 +00:00
Mac Malone
58c7a4f15e feat: lake: lift FetchM into JobM (and vice versa) (#6771)
This PR enables `FetchM` to be run from `JobM` / `SpawnM` and
vice-versa. This allows calls of `fetch` to asynchronously depend on the
outputs of other jobs.
2025-01-25 03:59:47 +00:00
Mac Malone
c8be581bc8 refactor: lake: use Job for all builtin facets (#6418)
This PR alters all builtin Lake facets to produce `Job` objects.
2025-01-25 02:53:21 +00:00
Siddharth
c6e244d811 feat: BitVec.shift x (n#w) -> shift x (n % 2^w) (#6767)
This PR adds lemmas to rewrite
`BitVec.shiftLeft,shiftRight,sshiftRight'` by a `BitVec.ofNat` into a
shift-by-natural number. This will be used to canonicalize shifts by
constant bitvectors into shift by constant numbers, which have further
rewrites on them if the number is a power of two.
2025-01-24 17:12:34 +00:00
Siddharth
044bf85fe9 feat: commute BitVec.extractLsb(')? with bitwise ops (#6747)
This PR adds the ability to push `BitVec.extractLsb` and
`BitVec.extractLsb'` with bitwise operations. This is useful for
constant-folding extracts.
2025-01-24 15:23:30 +00:00
Siddharth
1059e25ca2 feat: BitVec.shiftLeft in terms of extractLsb' (#6743)
This PR adds rewrites that normalizes left shifts by extracting bits and
concatenating zeroes. If the shift amount is larger than the bit-width,
then the resulting bitvector is zero.

```lean
theorem shiftLeft_eq_zero {x : BitVec w} {n : Nat} (hn : w ≤ n) : x <<< n = 0#w

theorem shiftLeft_eq_concat_of_lt {x : BitVec w} {n : Nat} (hn : n < w) :
    x <<< n = ((x.extractLsb' 0 (w-n)).append (BitVec.zero n)).cast (by omega)
```
2025-01-24 15:14:50 +00:00
Leonardo de Moura
c70f4064b4 fix: heterogenenous equality support in match conditions within grind (#6761)
This PR fixes issues in `grind` when processing `match`-expressions with
indexed families.
2025-01-24 04:08:29 +00:00
Sebastian Ullrich
757899a7d1 chore: run test suite with Elab.async for more coverage 2025-01-23 19:07:31 -07:00
Sebastian Ullrich
a901e34362 perf: avoid cross-thread environment extension state synchronization for now 2025-01-23 19:07:31 -07:00
Sebastian Ullrich
bab10cc2b5 feat: asynchronous kernel checking 2025-01-23 19:07:31 -07:00
Sebastian Ullrich
d26dbe73d5 fix: do not double-report snapshotTasks after wrapAsyncAsSnapshot 2025-01-23 19:07:31 -07:00
Sebastian Ullrich
214093e6c4 fix: prevent Task.get deadlocks from threadpool starvation (#6758)
This PR prevents deadlocks from non-cyclical task waits that may
otherwise occur during parallel elaboration with small threadpool sizes.
2025-01-23 23:01:39 +00:00
Lean stage0 autoupdater
ebda2d4d25 chore: update stage0 2025-01-23 15:28:44 +00:00
Joachim Breitner
7e03920bbb feat: zetaUnused option (option only) (#6754)
This PR adds the `+zetaUnused` option.

Implementation to follow after the stage0 update.
2025-01-23 14:37:41 +00:00
Jon Eugster
d033804190 doc: remove duplicated sentense in Lean.Syntax.node (#6752) 2025-01-23 11:43:48 +00:00
Joachim Breitner
56733b953e refactor: TerminationArgument → TerminationMeasure (#6727)
this PR aligns the terminology of the code with the one use in the
reference manual, as developed with and refined by @david-christiansen.
2025-01-23 10:41:38 +00:00
Lean stage0 autoupdater
c073da20ce chore: update stage0 2025-01-23 08:33:17 +00:00
damiano
d8bcd6a32e doc: correspondence ModuleIdx <--> Environment.moduleNames (#6749)
This PR documents the equality between the `ModuleIdx` of an module and
the index in the array of `moduleNames` of the same module.

I asked about this in the Office hours and it was confirmed that this is
a current feature and one that is likely not to change!
2025-01-23 07:47:38 +00:00
Leonardo de Moura
f35a602070 feat: use cast to "fix" types in the E-matching module within grind (#6750)
This PR adds support for fixing type mismatches using `cast` while
instantiating quantifiers in the E-matching module used by the grind
tactic.
2025-01-23 03:36:20 +00:00
Leonardo de Moura
14841ad1ed fix: bugs in grind (#6748)
This PR fixes a few bugs in the `grind` tactic: missing issues, bad
error messages, incorrect threshold in the canonicalizer, and bug in the
ground pattern internalizer.
2025-01-22 21:59:58 +00:00
Siddharth
5f3c0daf3d feat: BitVec.ushiftRight in terms of extractLsb' (#6745)
This PR supports rewriting `ushiftRight` in terms of `extractLsb'`. This
is the companion PR to #6743 which adds the similar lemmas about
`shiftLeft`.


```lean
theorem ushiftRight_eq_zero {x : BitVec w} {n : Nat} (hn : w ≤ n) :
    x >>> n = 0#w

theorem ushiftRight_eq_extractLsb'_of_lt {x : BitVec w} {n : Nat} (hn : n < w) :
    x >>> n = ((0#n) ++ (x.extractLsb' n (w - n))).cast (by omega)
```
2025-01-22 19:14:20 +00:00
Siddharth
6befda831d feat: add twoPow multiplication lemmas (#6742)
This PR adds the lemmas that show what happens when multiplying by
`twoPow` to an arbitrary term, as well to another `twoPow`.

This will be followed up by a PR that uses these to build a simproc to
canonicalize `twoPow w i * x` and `x * twoPow w i`.
2025-01-22 19:05:17 +00:00
Leonardo de Moura
6595ca8f29 feat: improve equation theorem support in grind (#6746)
This PR ensures that conditional equation theorems for function
definitions are handled correctly in `grind`. We use the same
infrastructure built for `match`-expression equations. Recall that in
both cases, these theorems are conditional when there are overlapping
patterns.
2025-01-22 18:41:09 +00:00
Sebastian Ullrich
91e261da38 chore: disable Elab.async on the cmdline for now (#6722)
Avoids build time overhead until the option is proven to speed up
average projects. Adds Init.Prelude (many tiny declarations, "worst
case") and Init.List.Sublist (many nontrivial theorems, "best case")
under -DElab.async=true as new benchmarks for tracking.
2025-01-22 18:25:47 +00:00
Henrik Böving
6ebce42142 perf: fast path for multiplication with constants in bv_decide (#6739)
This PR adds a fast path for bitblasting multiplication with constants
in `bv_decide`.

While the circuit generated is the same (as the AIG already performs
constant folding) this avoids calling out to the shift and addition
bitblaster unless required. Thus the overall time to generate the
circuit is reduced. Inspired by
[bitwuzla](25d77f819c/src/lib/bitblast/bitblaster.h (L454)).
2025-01-22 10:32:47 +00:00
Henrik Böving
b6db90a316 doc: mention subscript j in the lexical structure (#6738)
This PR updates our lexical structure documentation to mention the newly
supported ⱼ which lives in a separate unicode block and is thus not
captured by the current ranges.
2025-01-22 09:10:31 +00:00
Henrik Böving
7706b876f6 feat: bv_decide support for structures of supported types (#6724)
This PR adds support for `bv_decide` to automatically split up
non-recursive structures that contain information about supported types.
It can be controlled using the new `structures` field in the `bv_decide`
config.
2025-01-22 09:01:43 +00:00
Leonardo de Moura
9b74c07767 feat: lazy ite branch internalization in grind (#6737)
This PR ensures that the branches of an `if-then-else` term are
internalized only after establishing the truth value of the condition.
This change makes its behavior consistent with the `match`-expression
and dependent `if-then-else` behavior in `grind`.
This feature is particularly important for recursive functions defined
by well-founded recursion and `if-then-else`. Without lazy
`if-then-else` branch internalization, the equation theorem for the
recursive function would unfold until reaching the generation depth
threshold, and before performing any case analysis. See new tests for an
example.
2025-01-22 05:22:31 +00:00
Leonardo de Moura
533af01dab feat: improve grind canonicalizer (#6736)
This PR ensures the canonicalizer used in `grind` does not waste time
checking whether terms with different types are definitionally equal.
2025-01-22 03:59:45 +00:00
Leonardo de Moura
de31faa470 feat: case splitting match-expressions with overlapping patterns in grind (#6735)
This PR adds support for case splitting on `match`-expressions with
overlapping patterns to the `grind` tactic. `grind` can now solve
examples such as:
```
inductive S where
  | mk1 (n : Nat)
  | mk2 (n : Nat) (s : S)
  | mk3 (n : Bool)
  | mk4 (s1 s2 : S)

def g (x y : S) :=
  match x, y with
  | .mk1 a, _ => a + 2
  | _, .mk2 1 (.mk4 _ _) => 3
  | .mk3 _, .mk4 _ _ => 4
  | _, _ => 5

example : g a b > 1 := by
  grind [g.eq_def]
```
2025-01-22 02:59:42 +00:00
Leonardo de Moura
3881f21df1 fix: redundant information in the offset constraint module (#6734)
This PR ensures there are no redundant entries in the offset constraint
model produced by `grind`
2025-01-21 22:19:24 +00:00
Leonardo de Moura
c9a03c7613 feat: overlapping match patterns in grind (#6733)
This PR adds better support for overlapping `match` patterns in `grind`.
`grind` can now solve examples such as
```lean
inductive S where
  | mk1 (n : Nat)
  | mk2 (n : Nat) (s : S)
  | mk3 (n : Bool)
  | mk4 (s1 s2 : S)

def f (x y : S) :=
  match x, y with
  | .mk1 _, _ => 2
  | _, .mk2 1 (.mk4 _ _) => 3
  | .mk3 _, _ => 4
  | _, _ => 5

example : b = .mk2 y1 y2 → y1 = 2 → a = .mk4 y3 y4 → f a b = 5 := by
  unfold f
  grind (splits := 0)
```

---------

Co-authored-by: Leonardo de Moura <leodemoura@amazon.com>
2025-01-21 22:05:15 +00:00
Luisa Cicolini
0c2fb34c82 chore: remove useless Nat.mul_one from proof (#6728)
This PR removes theorems `Nat.mul_one` to simplify a rewrite in the
proof of `BitVec.getMsbD_rotateLeft_of_lt`
2025-01-21 17:00:19 +00:00
Martin Dvořák
eb30249b11 doc: make description of pp.analyze more precise (#6726)
As @nomeata told me, it should be "try to (...)" because even with
`pp.analyze` roundtripping often fails.
2025-01-21 15:03:48 +00:00
Paul Reichert
31929c0acd feat: lemmas for HashMap.alter and .modify (#6620)
This PR adds lemmas about HashMap.alter and .modify. These lemmas
describe the interaction of alter and modify with the read methods of
the HashMap. The additions affect the HashMap, the DHashMap and their
respective raw versions. Moreover, the raw versions of alter and modify
are defined.

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-01-21 12:34:19 +00:00
Joachim Breitner
3569797377 feat: functional cases theorem for non-recursive functions (#6261)
This PR adds `foo.fun_cases`, an automatically generated theorem that
splits the goal according to the branching structure of `foo`, much like
the Functional Induction Principle, but for all functions (not just
recursive ones), and without providing inductive hypotheses.

The design isn't quite final yet as to which function parameters should
become targets of the motive, and which parameters of the theorem, but
the current version is already proven to be useful, so start with this
and iterate later.
2025-01-21 10:16:42 +00:00
Joachim Breitner
7b813d4f5d feat: partial_fixpoint: partial functions with equations (#6355)
This PR adds the ability to define possibly non-terminating functions
and still be able to reason about them equationally, as long as they are
tail-recursive or monadic.

Typical uses of this feature are
```lean4
def ack : (n m : Nat) → Option Nat
  | 0,   y   => some (y+1)
  | x+1, 0   => ack x 1
  | x+1, y+1 => do ack x (← ack (x+1) y)
partial_fixpiont

def whileSome (f : α → Option α) (x : α) : α :=
  match f x with
  | none => x
  | some x' => whileSome f x'
partial_fixpiont

def computeLfp {α : Type u} [DecidableEq α] (f : α → α) (x : α) : α :=
  let next := f x
  if x ≠ next then
    computeLfp f next
  else
    x
partial_fixpiont

noncomputable def geom : Distr Nat := do
  let head ← coin
  if head then
    return 0
  else
    let n ← geom
    return (n + 1)
partial_fixpiont
```

This PR contains

* The necessary fragment of domain theory, up to (a variant of)
Knaster–Tarski theorem (merged as
https://github.com/leanprover/lean4/pull/6477)
* A tactic to solve monotonicity goals compositionally (a bit like
mathlib’s `fun_prop`) (merged as
https://github.com/leanprover/lean4/pull/6506)
* An attribute to extend that tactic (merged as
https://github.com/leanprover/lean4/pull/6506)
* A “derecursifier” that uses that machinery to define recursive
function, including support for dependent functions and mutual
recursion.
* Fixed-point induction principles (technical, tedious to use)
* For `Option`-valued functions: Partial correctness induction theorems
that hide all the domain theory

This is heavily inspired by [Isabelle’s `partial_function`
command](https://isabelle.in.tum.de/doc/codegen.pdf).
2025-01-21 09:54:30 +00:00
Luisa Cicolini
edeae18f5e feat: add Bitvec reverse definition, getLsbD_reverse, getMsbD_reverse, reverse_append, reverse_replicate and Nat.mod_sub_eq_sub_mod (#6476)
This PR defines `reverse` for bitvectors and implements a first subset
of theorems (`getLsbD_reverse, getMsbD_reverse, reverse_append,
reverse_replicate, reverse_cast, msb_reverse`). We also include some
necessary related theorems (`cons_append, cons_append_append,
append_assoc, replicate_append_self, replicate_succ'`) and deprecate
theorems`replicate_zero_eq` and `replicate_succ_eq`.

---------

Co-authored-by: Alex Keizer <alex@keizer.dev>
Co-authored-by: Kim Morrison <kim@tqft.net>
2025-01-21 08:44:50 +00:00
Kim Morrison
91bae2e064 feat: align {List/Array/Vector}.{attach,attachWith,pmap} lemmas (#6723)
This PR completes the alignment of
{List/Array/Vector}.{attach,attachWith,pmap} lemmas. I had to fill in a
number of gaps in the List API.
2025-01-21 06:36:36 +00:00
Luisa Cicolini
f9e904af50 feat: add BitVec.[getMsbD_mul, getElem_udiv, getLsbD_udiv, getMsbD_udiv] (#6674)
This PR adds theorems `BitVec.[getMsbD_mul, getElem_udiv, getLsbD_udiv,
getMsbD_udiv]`

---------

Co-authored-by: Siddharth <siddu.druid@gmail.com>
2025-01-21 03:59:27 +00:00
Henrik Böving
8375d00d8c fix: allow ⱼ in identifiers (#6679)
This PR changes the identifier parser to allow for the ⱼ unicode
character which was forgotten as it lives by itself in a codeblock with
coptic characters.
2025-01-21 03:51:51 +00:00
Kim Morrison
16bd7ea455 chore: deprecate List.iota (#6708)
This PR deprecates `List.iota`, which we make no essential use of. `iota
n` can be replaced with `(range' 1 n).reverse`. The verification lemmas
for `range'` already have better coverage than those for `iota`.
Any downstream projects using it (I am not aware of any) are encouraged
to adopt it.
2025-01-21 02:32:35 +00:00
Cameron Zwarich
c54287fb0d feat: add proper erasure of type dependencies in LCNF (#6678)
This PR modifies LCNF.toMonoType to use a more refined type erasure
scheme, which distinguishes between irrelevant/erased information
(represented by lcErased) and erased type dependencies (represented by
lcAny). This corresponds to the irrelevant/object distinction in the old
code generator.
2025-01-21 02:07:16 +00:00
Cameron Zwarich
e3771e3ad6 fix: don't generate code for decls with an implemented_by attribute (#6680)
This PR makes the new code generator skip generating code for decls with
an implemented_by decl, just like the old code generator.
2025-01-21 02:06:41 +00:00
Sebastian Ullrich
4935829abe feat: generalize infoview.maxTraceChildren to the cmdline (#6716)
This PR renames the option `infoview.maxTraceChildren` to
`maxTraceChildren` and applies it to the cmdline driver and language
server clients lacking an info view as well. It also implements the
common idiom of the option value `0` meaning "unlimited".
2025-01-21 02:06:24 +00:00
Leonardo de Moura
778333c667 fix: match equality generation (#6719)
This PR fixes a bug in the equational theorem generator for
`match`-expressions. See new test for an example.

Signed-off-by: Leonardo de Moura <leodemoura@amazon.com>
Co-authored-by: Leonardo de Moura <leodemoura@amazon.com>
2025-01-21 02:05:37 +00:00
Leonardo de Moura
189f5d41fb feat: case splitting in grind (#6717)
This PR introduces a new feature that allows users to specify which
inductive datatypes the `grind` tactic should perform case splits on.
The configuration option `splitIndPred` is now set to `false` by
default. The attribute `[grind cases]` is used to mark inductive
datatypes and predicates that `grind` may case split on during the
search. Additionally, the attribute `[grind cases eager]` can be used to
mark datatypes and predicates for case splitting both during
pre-processing and the search.

Users can also write `grind [HasType]` or `grind [cases HasType]` to
instruct `grind` to perform case splitting on the inductive predicate
`HasType` in a specific instance. Similarly, `grind [-Or]` can be used
to instruct `grind` not to case split on disjunctions.

Co-authored-by: Leonardo de Moura <leodemoura@amazon.com>
2025-01-20 22:44:56 +00:00
Vlad Tsyrklevich
c07f64a621 doc: Fix (and expand) docstrings for bmod/bdiv (#6713)
The current text is missing a negative sign on the bottom of the
interval that `Int.bmod` can return. While I'm here, I added
illustrative example outputs to match docs for tdiv/ediv/fdiv/etc.
2025-01-20 13:03:34 +00:00
Kim Morrison
22117f21e3 feat: align List/Array/Vector.count theorems (#6712)
This PR aligns `List`/`Array`/`Vector` theorems for `countP` and
`count`.
2025-01-20 10:20:16 +00:00
Sofia Rodrigues
1d03cd6a6b fix: negative timestamps and PlainDateTimes before 1970 (#6668)
This PR fixes negative timestamps and `PlainDateTime`s before 1970.
2025-01-20 07:52:13 +00:00
Kim Morrison
ac6a29ee83 feat: complete alignment of {List,Array,Vector}.{mapIdx,mapFinIdx} (#6701)
This PR completes aligning `mapIdx` and `mapFinIdx` across
`List/Array/Vector`.
2025-01-20 04:06:37 +00:00
Kim Morrison
57f0006c9b feat: align {List/Array/Vector}.{foldl, foldr, foldlM, foldrM} lemmas (#6707)
This PR completes aligning lemmas for `List` / `Array` / `Vector` about
`foldl`, `foldr`, and their monadic versions.
2025-01-20 04:05:31 +00:00
Lean stage0 autoupdater
e40e0892c1 chore: update stage0 2025-01-20 03:43:04 +00:00
Leonardo de Moura
1fcdd7ad9a feat: add [grind cases] and [grind cases eager] attributes (#6705)
This PR adds the attributes `[grind cases]` and `[grind cases eager]`
for controlling case splitting in `grind`. They will replace the
`[grind_cases]` and the configuration option `splitIndPred`.

After update stage0, we will push the second part of this PR.
2025-01-20 03:01:40 +00:00
Leonardo de Moura
9b7bd58c14 feat: add [grind ←=] attribute (#6702)
This PR adds support for equality backward reasoning to `grind`. We can
illustrate the new feature with the following example. Suppose we have a
theorem:
```lean
theorem inv_eq {a b : α} (w : a * b = 1) : inv a = b
```
and we want to instantiate the theorem whenever we are tying to prove
`inv t = s` for some terms `t` and `s`
The attribute `[grind ←]` is not applicable in this case because, by
default, `=` is not eligible for E-matching. The new attribute `[grind
←=]` instructs `grind` to use the equality and consider disequalities in
the `grind` proof state as candidates for E-matching.
2025-01-20 01:16:01 +00:00
Leonardo de Moura
a062eea204 feat: beta reduction in grind (#6700)
This PR adds support for beta reduction in the `grind` tactic. `grind`
can now solve goals such as
```lean
example (f : Nat → Nat) : f = (fun x : Nat => x + 5) → f 2 > 5 := by
  grind
```
2025-01-19 21:29:24 +00:00
Sebastian Ullrich
645bdea23c perf: optimize setImportedEntries (#6698)
A small boost before #6691 made `modifyState` more complex, a larger
boost after.
2025-01-19 14:27:18 +00:00
Kim Morrison
35bbb48916 feat: refactor List/Array.mapFinIdx to unbundle the Fin argument (#6697)
This PR changes the arguments of `List/Array.mapFinIdx` from `(f : Fin
as.size → α → β)` to `(f : (i : Nat) → α → (h : i < as.size) → β)`, in
line with the API design elsewhere for `List/Array`.
2025-01-19 10:30:18 +00:00
Kim Morrison
b289b660c7 chore: remove deprecations from 2024-06 (#6696)
This PR removes deprecations in the standard library from June 2024.
2025-01-19 08:46:24 +00:00
Kim Morrison
75c104ce06 feat: align List/Array/Vector.reverse lemmas (#6695)
This PR aligns `List/Array/Vector.reverse` lemmas.
2025-01-19 08:40:06 +00:00
Lean stage0 autoupdater
74bd40d34d chore: update stage0 2025-01-19 03:03:18 +00:00
Leonardo de Moura
4213862b0e chore: remove [grind_norm] attribute (#6692)
This PR removes the `[grind_norm]` attribute. The normalization theorems
used by `grind` are now fixed and cannot be modified by users. We use
normalization theorems to ensure the built-in procedures receive term
wish expected "shapes". We use it for types that have built-in support
in grind. Users could misuse this feature as a simplification rule. For
example, consider the following example:

```lean
def replicate : (n : Nat) → (a : α) → List α
  | 0,   _ => []
  | n+1, a => a :: replicate n a

-- I want `grind` to instantiate the equations theorems for me.
attribute [grind] replicate

-- I want it to use the equation theorems as simplication rules too.
attribute [grind_norm] replicate

/--
info: [grind.assert] n = 0
[grind.assert] ¬replicate n xs = []
[grind.ematch.instance] replicate.eq_1: replicate 0 xs = []
[grind.assert] True
-/
set_option trace.grind.ematch.instance true in
set_option trace.grind.assert true in
example (xs : List α) : n = 0 → replicate n xs = [] := by
  grind -- fails :(
```

In this example, `grind` starts by asserting the two propositions as
expected: `n = 0`, and `¬replicate n xs = []`. The normalizer cannot
reduce `replicate n xs` as expected.
Then, the E-matching module finds the instance `replicate 0 xs = []` for
the equation theorem `replicate.eq_1` also as expected. But, then the
normalizer kicks in and reduces the new instance to `True`. By removing
`[grind_norm]` we elimninate this kind of misuse. Users that want to
preprocess a formula before invoking `grind` should use `simp` instead.
2025-01-19 02:12:01 +00:00
Sebastian Ullrich
4d8bc22228 feat: Environment.addConstAsync (#6691)
This PR introduces the central API for making parallel changes to the
environment
2025-01-19 02:00:16 +00:00
Lean stage0 autoupdater
7ee938290b chore: update stage0 2025-01-19 01:04:01 +00:00
Leonardo de Moura
478d42105f feat: init_grind_norm elaborator (#6690)
Motivation: we will remove the `[grind_norm]` attribute.
2025-01-19 00:15:13 +00:00
Kim Morrison
5998ba545b feat: regression tests for grind adapted from lean-egg (#6688)
Adapts, with permission, unit tests from `lean-egg` written by Marcus
Rossel as regression tests for `grind`.
2025-01-18 23:46:55 +00:00
Sebastian Ullrich
8a8417f6e1 refactor: getUnfoldableConst*? (#5997)
Continuation from #5429: eliminates uses of these two functions that
care about something other than reducible defs/theorems, then restricts
the function definition to these cases to be more true to its name.
2025-01-18 23:30:40 +00:00
Lean stage0 autoupdater
26941793ff chore: update stage0 2025-01-18 23:46:01 +00:00
Leonardo de Moura
70050c3798 chore: init_grind_norm command parser (#6689) 2025-01-18 23:07:54 +00:00
Sebastian Ullrich
50a0a97b49 refactor: move registration of namespaces on kernel add into elaborator (#6214)
Kernel checking will be moved to a different thread but namespace
registration should stay on the elaboration thread
2025-01-18 23:01:29 +00:00
Lean stage0 autoupdater
5fb2e892c8 chore: update stage0 2025-01-18 19:28:20 +00:00
Sebastian Ullrich
3770808b58 feat: split Lean.Kernel.Environment from Lean.Environment (#5145)
This PR splits the environment used by the kernel from that used by the
elaborator, providing the foundation for tracking of asynchronously
elaborated declarations, which will exist as a concept only in the
latter.

Minor changes:
* kernel diagnostics are moved from an environment extension to a direct
environment as they are the only extension used directly by the kernel
* `initQuot` is moved from an environment header field to a direct
environment as it is the only header field used by the kernel; this also
makes the remaining header immutable after import
2025-01-18 18:42:57 +00:00
Andrés Goens
5e63dd292f chore: fix typo in docstring of mkMVar (#6687)
This PR fixes a very small typo in the docstring of `mkMVar` that
misspelled the function it recommends to use instead.
2025-01-18 12:28:33 +00:00
Kitamado
98e3d6f663 fix: make #check_failure's output be info (#6685)
This PR fixes the issue that `#check_failure`'s output is warning

Closes #6684
2025-01-18 07:27:44 +00:00
Leonardo de Moura
d4070d4bfb fix: grind parameter issues and configuration (#6686)
This PR fixes parameter processing, initialization, and attribute
handling issues in the `grind` tactic.
2025-01-18 03:15:59 +00:00
Leonardo de Moura
4d4c0941be feat: extensionality theorems in grind (#6682)
This PR adds support for extensionality theorems (using the `[ext]`
attribute) to the `grind` tactic. Users can disable this functionality
using `grind -ext` . Below are examples that demonstrate problems now
solvable by `grind`.

```lean
open List in
example : (replicate n a).map f = replicate n (f a) := by
  grind only [Option.map_some', Option.map_none', getElem?_map, getElem?_replicate]
```

```lean
@[ext] structure S where
  a : Nat
  b : Bool

example (x y : S) : x.a = y.a → y.b = x.b → x = y := by
  grind
```
2025-01-17 23:59:36 +00:00
Leonardo de Moura
9b629cc81f chore: update stage0
Manual update stage0 is required to get the test suite green.
2025-01-17 12:31:14 -08:00
Leonardo de Moura
f374ef154e refactor: move ext environment extension to Lean.Meta.Tactic 2025-01-17 12:31:14 -08:00
Lean stage0 autoupdater
e3fd954318 chore: update stage0 2025-01-17 04:30:58 +00:00
Cameron Zwarich
b7815b5684 feat: add lcAny constant to Prelude (#6665)
This PR adds a new lcAny constant to Prelude, which is meant for use in
LCNF to represent types whose dependency on another term has been erased
during compilation. This is in addition to the existing lcErased
constant, which represents types that are irrelevant.
2025-01-17 01:33:35 +00:00
Cameron Zwarich
7f0ae22e43 fix: don't filter out local instances in LCNF toMono pass (#6664)
This PR changes the toMono pass to longer filter out type class
instances, because they may actually be needed for later compilation.
2025-01-17 01:32:49 +00:00
Leonardo de Moura
35a4da28ac feat: add simp-like parameters to grind (#6675)
This PR adds `simp`-like parameters to `grind`, and `grind only` similar
to `simp only`.
2025-01-17 01:08:45 +00:00
Henrik Böving
60142c967c chore: remove unneeded instance (#6671)
This PR removes an `Inhabited` instance from the imported LRAT checker
code that is unneeded but also potentially triggers for each `Inhabited`
query.
2025-01-16 18:32:37 +00:00
Leonardo de Moura
17c0187252 fix: add workaround for MessageData limitations (#6669)
This PR adds a workaround for the discrepancy between Terminal/Emacs and
VS Code when displaying info trees.
2025-01-16 16:58:20 +00:00
Leonardo de Moura
e42f7d9fc3 feat: equality resolution for grind (#6663)
This PR implements a basic equality resolution procedure for the `grind`
tactic.
2025-01-16 16:33:11 +00:00
Luisa Cicolini
906aa1be4b feat: add Nat.[shiftLeft_or_distrib, shiftLeft_xor_distrib, shiftLeft_and_distrib, testBit_mul_two_pow, bitwise_mul_two_pow, shiftLeft_bitwise_distrib] (#6630)
This PR adds theorems `Nat.[shiftLeft_or_distrib`,
shiftLeft_xor_distrib`, shiftLeft_and_distrib`, `testBit_mul_two_pow`,
`bitwise_mul_two_pow`, `shiftLeft_bitwise_distrib]`, to prove
`Nat.shiftLeft_or_distrib` by emulating the proof strategy of
`shiftRight_and_distrib`.

In particular, `Nat.shiftLeft_or_distrib` is necessary to simplify the
proofs in #6476.

---------

Co-authored-by: Alex Keizer <alex@keizer.dev>
2025-01-16 10:59:00 +00:00
Kim Morrison
f01527142e feat: align List.replicate/Array.mkArray/Vector.mkVector lemmas (#6667)
This PR aligns `List.replicate`/`Array.mkArray`/`Vector.mkVector`
lemmas.
2025-01-16 09:48:01 +00:00
Kim Morrison
f4c9934171 feat: Vector.getElem_flatMap (#6661)
This PR adds array indexing lemmas for `Vector.flatMap`. (These were not
available for `List` and `Array` due to variable lengths.)
2025-01-16 06:33:54 +00:00
Kim Morrison
80ddbf45eb feat: align List/Array/Vector.flatMap (#6660)
This PR defines `Vector.flatMap`, changes the order of arguments in
`List.flatMap` for consistency, and aligns the lemmas for
`List`/`Array`/`Vector` `flatMap`.
2025-01-16 05:19:28 +00:00
Leonardo de Moura
3a6c5cf4f1 feat: canonicalizer diagnostics (#6662)
This PR improves the canonicalizer used in the `grind` tactic and the
diagnostics it produces. It also adds a new configuration option,
`canonHeartbeats`, to address (some of) the issues. Here is an example
illustrating the new diagnostics, where we intentionally create a
problem by using a very small number of heartbeats.

<img width="1173" alt="image"
src="https://github.com/user-attachments/assets/484005c8-dcaa-4164-8fbf-617864ed7350"
/>
2025-01-16 04:59:18 +00:00
Leonardo de Moura
af4a7d7e98 fix: grind term preprocessor (#6659)
This PR fixes a bug in the `grind` term preprocessor. It was abstracting
nested proofs **before** reducible constants were unfolded.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2025-01-16 01:22:06 +00:00
Leonardo de Moura
6259b4742c feat: improve case-split heuristic used in grind (#6658)
This PR ensures that `grind` avoids case-splitting on terms congruent to
those that have already been case-split.
2025-01-16 00:17:27 +00:00
Mac Malone
0050e9369c refactor: lake: use StateRefT for BuildStore (#6290)
This PR uses `StateRefT` instead of `StateT` to equip the Lake build
monad with a build store.

As a IO reference, different threads may now contend with the build
store. However, benchmark results indicate that this does not have a
significant performance impact. On a synchronization front, the lack of
a mutex should not be a concern because the build store is a
memorization data structure and thus order is theoretically irrelevant.
2025-01-15 23:42:32 +00:00
Leonardo de Moura
64cf5e5e6a feat: improve grind search procedure (#6657)
This PR improves the `grind` search procedure, and adds the new
configuration option: `failures`.
2025-01-15 23:08:41 +00:00
Kim Morrison
127b3f9191 feat: more grind tests (#6650)
This PR adds some tests for `grind`, working on `List` lemmas.
2025-01-15 23:00:23 +00:00
Leonardo de Moura
65175dc7d4 feat: improvegrind diagnostic information (#6656)
This PR improves the diagnostic information provided in `grind` failure
states. We now include the list of issues found during the search, and
all search thresholds that have been reached. This PR also improves its
formatting.
2025-01-15 20:57:28 +00:00
Leonardo de Moura
54f06ccd64 feat: better support for partial applications in the E-matching procedure (#6654)
This PR improves the support for partial applications in the E-matching
procedure used in `grind`.
2025-01-15 18:31:34 +00:00
Leonardo de Moura
b3f8feffd3 fix: improve E-matching pattern selection heuristics (#6653)
This PR improves the E-matching pattern selection heuristics in the
`grind` tactic. They now take into account type predicates and
transformers.
2025-01-15 16:43:59 +00:00
Lukas Gerlach
6665837232 feat: verify insertMany method for adding lists to HashMaps (#6211)
This PR verifies the `insertMany` method on `HashMap`s for the special
case of inserting lists.

---------

Co-authored-by: jt0202 <johannes.tantow@gmail.com>
Co-authored-by: monsterkrampe <monsterkrampe@users.noreply.github.com>
Co-authored-by: Johannes Tantow <44068763+jt0202@users.noreply.github.com>
2025-01-15 14:57:26 +00:00
Henrik Böving
c7fd873333 feat: tag lemmas 2025-01-15 15:17:36 +01:00
Henrik Böving
a10ce9492f chore: update stage0 2025-01-15 15:17:36 +01:00
Henrik Böving
838ad281f2 feat: add the int_toBitVec simpset 2025-01-15 15:17:36 +01:00
Henrik Böving
a1ef26bd8b perf: improve bv_decide preprocessing based on Bitwuzla optimisations (#6641)
This PR implements several optimisation tricks from Bitwuzla's
preprocessing passes into the Lean equivalent in `bv_decide`. Note that
these changes are mostly geared towards large proof states as for
example seen in SMT-Lib.
2025-01-15 12:09:43 +00:00
Leonardo de Moura
a955708b6c fix: grind canonicalizer state management (#6649)
This PR fixes a bug in the term canonicalizer used in the `grind`
tactic.
2025-01-15 05:51:54 +00:00
Kim Morrison
0f7f80aff5 fix: indicate dependency on pkgconf in ubuntu docs (#6646)
This PR changes the ubuntu docs to indicate that Lean now requires
pkgconf to build.

This is a companion to #6643, but I can't push directly to that branch.
2025-01-15 05:30:20 +00:00
Leonardo de Moura
8d69909b18 feat: literals, lower and upper bounds in the offset constraint module within grind (#6648)
This PR adds support for numerals, lower & upper bounds to the offset
constraint module in the `grind` tactic. `grind` can now solve examples
such as:
```
example (f : Nat → Nat) :
        f 2 = a →
        b ≤ 1 → b ≥ 1 →
        c = b + 1 →
        f c = a := by
  grind
```
In the example above, the literal `2` and the lower&upper bounds, `b ≤
1` and `b ≥ 1`, are now processed by offset constraint module.
2025-01-15 02:53:31 +00:00
Kim Morrison
f95d8108f4 chore: fib_correct monadic reasoning example as a test (#6647)
This PR records the `fib_impl n = fib_spec n` example, and a proof using
current technologies, as a test.

I'd like to think about eliminating `MProd` from the terms produced by
`do` notation; it seems (at least) a simproc would be required.
2025-01-15 01:58:15 +00:00
Kim Morrison
5d6bf75795 feat: align List/Array/Vector flatten lemmas (#6640)
This PR completes aligning `List`/`Array`/`Vector` lemmas about
`flatten`. `Vector.flatten` was previously missing, and has been added
(for rectangular sizes only). A small number of missing `Option` lemmas
were also need to get the proofs to go through.
2025-01-15 01:16:19 +00:00
Leonardo de Moura
563d5e8bcf feat: offset equalities in grind (#6645)
This PR implements support for offset equality constraints in the
`grind` tactic and exhaustive equality propagation for them. The `grind`
tactic can now solve problems such as the following:

```lean
example (f : Nat → Nat) (a b c d e : Nat) :
        f (a + 3) = b →
        f (c + 1) = d →
        c ≤ a + 2 →
        a + 1 ≤ e →
        e < c →
        b = d := by
  grind
```
2025-01-14 23:45:46 +00:00
Cameron Zwarich
3da7f70014 fix: indicate dependency on pkgconf in macOS docs (#6643)
This PR changes the macOS docs to indicate that Lean now requires
pkgconf to build.
2025-01-14 23:40:26 +00:00
Cameron Zwarich
8e5a3e416b chore: remove duplicate branch in LCNF.toMonoType (#6644) 2025-01-14 23:32:54 +00:00
Henrik Böving
9dbe5e6f9c refactor: bv_normalize simp set and implementation (#6639)
This PR puts the `bv_normalize` simp set into simp_nf and splits up the
bv_normalize implementation across multiple files in preparation for
upcoming changes.
2025-01-14 12:06:01 +00:00
Luisa Cicolini
c12b1d0a55 chore: fix docstring in Bitvec.toNat_add_of_lt (#6638)
This PR correct the docstring of theorem `Bitvec.toNat_add_of_lt`
2025-01-14 10:56:48 +00:00
Kim Morrison
85294b800f chore: update release checklist (#6637)
This PR updates the release checklist script to:
* validate the `releases/v4.X.0` branch
* check that the release has been tagged
* appears on the releases list
* and has release notes (and if not, prompts to run the script
* and when checking downstream repositories, if something is not tagged
properly, suggests the script to run to push the missing tag.
2025-01-14 10:18:46 +00:00
Paul Reichert
821c9b7af9 feat: faster, linear HashMap.alter and modify (#6573)
This PR replaces the existing implementations of `(D)HashMap.alter` and
`(D)HashMap.modify` with primitive, more efficient ones and in
particular provides proofs that they yield well-formed hash maps (`WF`
typeclass).

---------

Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
2025-01-14 07:47:58 +00:00
Henrik Böving
e9bd9807ef fix: Windows stage0 linking (#6622)
This PR fixes stage0 linking on Windows against winsock.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-01-14 09:09:50 +01:00
Leonardo de Moura
05aa256c99 feat: model construction for offset constraints (#6636)
This PR implements model construction for offset constraints in the
`grind` tactic.
2025-01-14 03:28:58 +00:00
Leonardo de Moura
d6f0c324c3 chore: display E-matching theorems in goalToMessageData (#6635)
This PR includes the activated E-matching theorems and their patterns in
`goalToMessageData`
2025-01-14 02:25:30 +00:00
Leonardo de Moura
f57745e9d4 feat: improve grind failure message (#6633)
This PR improves the failure message produced by the `grind` tactic. We
now include information about asserted facts, propositions that are
known to be true and false, and equivalence classes.
2025-01-14 01:10:47 +00:00
Mac Malone
749a82a8ce fix: lake: set MACOSX_DEPLOYMENT_TARGET for shared libs (#6631)
This PR sets `MACOSX_DEPLOYMENT_TARGET` for shared libraries (it was
previously only set for executables).
2025-01-13 21:18:09 +00:00
Cameron Zwarich
85560da3e4 chore: remove functions for compiling decls from Environment (#6600)
This PR removes functions from compiling decls from Environment, and
moves all users to functions on CoreM. This is required for supporting
the new code generator, since its implementation uses CoreM.
2025-01-13 18:51:06 +00:00
Henrik Böving
e6a643770f feat: implement basic async IO with timers (#6505)
This PR implements a basic async framework as well as asynchronously
running timers using libuv.

---------

Co-authored-by: Sofia Rodrigues <sofia@algebraic.dev>
Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
Co-authored-by: Markus Himmel <markus@lean-fro.org>
2025-01-13 18:11:04 +00:00
Mac Malone
30ba383744 feat: lean --src-deps (#6427)
This PR adds the Lean CLI option `--src-deps` which parallels `--deps`.
It parses the Lean code's header and prints out the paths to the
(transitively) imported modules' source files (deduced from
`LEAN_SRC_PATH`).
2025-01-13 16:00:19 +00:00
Henrik Böving
734fca7b6a feat: UIntX.toBitVec lemmas (#6625)
This PR adds lemmas describing the behavior of `UIntX.toBitVec` on
`UIntX` operations.

I did not define them for the `IntX` half yet as that lemma file is non
existent so far and we can start working on `UIntX` in `bv_decide` with
this, then add `IntX` when we grow the `IntX` API.
2025-01-13 14:33:38 +00:00
Mac Malone
a6eea4b650 fix: lake: v4.16.0-rc1 trace issues (#6627)
This PR aims to fix the trace issues reported by Mathlib that are
breaking `lake exe cache` in downstream projects.
2025-01-13 14:16:07 +00:00
Sofia Rodrigues
8483ac7258 fix: adjustments to the datetime library (#6431)
This PR fixes the `Repr` instance of the `Timestamp` type and changes
the `PlainTime` type so that it always represents a clock time that may
be a leap second.

- Fix timestamp `Repr`.
- The `PlainTime` type now always represents a clock time that may be a
leap second.
- Changed `readlink -f` to `IO.FS.realPath`

---------

Co-authored-by: Mac Malone <tydeu@hatpress.net>
Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
2025-01-13 11:02:30 +00:00
Sebastian Ullrich
5f41cc71ff fix: trace indentation in info view (#6597)
This PR fixes the indentation of nested traces nodes in the info view.


![image](https://github.com/user-attachments/assets/c13ac2a2-e994-4900-9201-0d86889f6a1b)

Fixes #6389
2025-01-13 10:36:01 +00:00
Leonardo de Moura
2421f7f799 feat: exhaustive offset constraint propagation in the grind tactic (#6618)
This PR implements exhaustive offset constraint propagation in the
`grind` tactic. This enhancement minimizes the number of case splits
performed by `grind`. For instance, it can solve the following example
without performing any case splits:

```lean
example (p q r s : Prop) (a b : Nat) : (a + 1 ≤ c ↔ p) → (a + 2 ≤ c ↔ s) → (a ≤ c ↔ q) → (a ≤ c + 4 ↔ r) → a ≤ b → b + 2 ≤ c → p ∧ q ∧ r ∧ s := by
  grind (splits := 0)
```

TODO: support for equational offset constraints.
2025-01-13 04:38:14 +00:00
Kim Morrison
40efbb9b7a doc: commit conventions and Mathlib CI (#6605)
This PR updates the commit conventions documentation to describe the new
changelog conventions, and adds brief documentation of integrated
Mathlib CI, with a link for further explanation.
2025-01-13 02:29:46 +00:00
Kim Morrison
603108e34c feat: finish alignment of List/Array/Vector.append lemmas (#6617)
This PR completes alignment of `List`/`Array`/`Vector` `append` lemmas.
2025-01-13 02:00:49 +00:00
Leonardo de Moura
aa95a1c03f chore: cleaunp grind tests (#6616)
Tests using `logInfo` were taking an additional two seconds on my
machine. This is a performance issue with the old code generator, where
we spend all this time specializing the logging functions for `GoalM`. I
have not checked whether the new code generator is also affected by this
performance issue.

Here is a small example that exposes the issue:
```lean
import Lean

set_option profiler true
open Lean Meta Grind in
def test (e : Expr): GoalM Unit := do
  logInfo e
```

cc @zwarich
2025-01-13 00:07:48 +00:00
Leonardo de Moura
af8f3d1ec1 feat: avoid some redundant proof terms in grind (#6615)
This PR adds two auxiliary functions `mkEqTrueCore` and `mkOfEqTrueCore`
that avoid redundant proof terms in proofs produced by `grind`.
2025-01-12 23:09:39 +00:00
Leonardo de Moura
c7939cfb03 feat: offset constraints support for the grind tactic (#6603)
This PR implements support for offset constraints in the `grind` tactic.
Several features are still missing, such as constraint propagation and
support for offset equalities, but `grind` can already solve examples
like the following:

```lean
example (a b c : Nat) : a ≤ b → b + 2 ≤ c → a + 1 ≤ c := by
  grind
example (a b c : Nat) : a ≤ b → b ≤ c → a ≤ c := by
  grind
example (a b c : Nat) : a + 1 ≤ b → b + 1 ≤ c → a + 2 ≤ c := by
  grind
example (a b c : Nat) : a + 1 ≤ b → b + 1 ≤ c → a + 1 ≤ c := by
  grind
example (a b c : Nat) : a + 1 ≤ b → b ≤ c + 2 → a ≤ c + 1 := by
  grind
example (a b c : Nat) : a + 2 ≤ b → b ≤ c + 2 → a ≤ c := by
  grind
```

---------

Co-authored-by: Kim Morrison <scott.morrison@gmail.com>
2025-01-12 20:38:39 +00:00
Parth Shastri
0da3624ec9 fix: allow dot idents to resolve to local names (#6602)
This PR allows the dot ident notation to resolve to the current
definition, or to any of the other definitions in the same mutual block.
Existing code that uses dot ident notation may need to have `nonrec`
added if the ident has the same name as the definition.

Closes #6601
2025-01-12 17:18:22 +00:00
Leonardo de Moura
349da6cae2 feat: improve [grind =] attribute (#6614)
This PR improves the usability of the `[grind =]` attribute by
automatically handling
forbidden pattern symbols. For example, consider the following theorem
tagged with this attribute:
```
getLast?_eq_some_iff {xs : List α} {a : α} : xs.getLast? = some a ↔ ∃ ys, xs = ys ++ [a]
```
Here, the selected pattern is `xs.getLast? = some a`, but `Eq` is a
forbidden pattern symbol.
Instead of producing an error, this function converts the pattern into a
multi-pattern,
allowing the attribute to be used conveniently.
2025-01-12 16:51:09 +00:00
Leonardo de Moura
541902564b feat: improve case split heuristic used in grind (#6613)
This PR improves the case split heuristic used in the `grind` tactic,
ensuring it now avoids unnecessary case-splits on `Iff`.
2025-01-12 15:40:36 +00:00
Kim Morrison
8b1aabbb1e feat: lemmas about Array.append (#6612)
This PR adds lemmas about `Array.append`, improving alignment with the
`List` API.
2025-01-12 10:19:50 +00:00
Leonardo de Moura
ce1ff03af0 fix: checkParents in grind (#6611)
This PR fixes one of the sanity check tests used in `grind`.
2025-01-12 05:30:41 +00:00
Leonardo de Moura
c5c1278315 fix: bug in the grind propagator (#6610)
This PR fixes a bug in the `grind` core module responsible for merging
equivalence classes and propagating constraints.
2025-01-12 05:14:41 +00:00
Leonardo de Moura
5119528d20 feat: improve case-split heuristic used in grind (#6609)
This PR improves the case-split heuristic used in grind, prioritizing
case-splits with fewer cases.
2025-01-12 04:21:04 +00:00
Leonardo de Moura
4636091571 fix: simp_arith (#6608)
This PR fixes a bug in the `simp_arith` tactic. See new test.
2025-01-12 03:27:13 +00:00
Leonardo de Moura
7ea5504af2 feat: add support for splitting on <-> to grind (#6607)
This PR adds support for case-splitting on `<->` (and `@Eq Prop`) in the
`grind` tactic.
2025-01-12 02:25:02 +00:00
Leonardo de Moura
acad587938 fix: pattern selection for local lemmas (#6606)
This PR fixes a bug in the pattern selection in the `grind`.
2025-01-12 01:29:32 +00:00
Kim Morrison
8791a9ce06 chore: add lean4-cli to release checklist (#6596)
Users have requested toolchain tags on `lean4-cli`, so let's add it to
the release checklist to make sure these get added regularly.

Previously, `lean4-cli` has used more complicated tags, but going
forward we're going to just use the simple `v4.16.0` style tags, with no
repository-specific versioning.

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
2025-01-11 00:32:43 +00:00
David Thrane Christiansen
03081a5b6f doc: update FFI description for Int and signed fixed-width ints (#6599)
The FFI description didn't mention Int or signed integers.

This PR adds `Int` and signed integers to the FFI document.
2025-01-11 00:11:20 +00:00
Alex Keizer
918924c16b feat: BitVec.{toFin, toInt, msb}_umod (#6404)
This PR adds a `toFin` and `msb` lemma for unsigned bitvector modulus.
Similar to #6402, we don't provide a general `toInt_umod` lemmas, but
instead choose to provide more specialized rewrites, with extra
side-conditions.

---------

Co-authored-by: Kim Morrison <scott@tqft.net>
2025-01-10 23:23:58 +00:00
Lean stage0 autoupdater
58cd01154b chore: update stage0 2025-01-10 16:42:03 +00:00
Harun Khan
0b5d97725c feat: BitVec.toNat theorems for rotateLeft and rotateRight (#6347)
This PR adds `BitVec.toNat_rotateLeft` and `BitVec.toNat_rotateLeft`.

---------

Co-authored-by: Kim Morrison <scott@tqft.net>
2025-01-10 11:03:58 +00:00
Sofia Rodrigues
ed309dc2a4 feat: add decidable instances for comparison operation of time offset types (#6587)
This PR adds decidable instances for the `LE` and `LT` instances for the
`Offset` types defined in `Std.Time`.
2025-01-10 07:34:46 +00:00
Alex Keizer
d2c4471cfa feat: BitVec.{toInt, toFin, msb}_udiv (#6402)
This PR adds a `toFin` and `msb` lemma for unsigned bitvector division.
We *don't* have `toInt_udiv`, since the only truly general statement we
can make does no better than unfolding the definition, and it's not
uncontroversially clear how to unfold `toInt` (see
`toInt_eq_msb_cond`/`toInt_eq_toNat_cond`/`toInt_eq_toNat_bmod` for a
few options currently provided). Instead, we do have `toInt_udiv_of_msb`
that's able to provide a more meaningful rewrite given an extra
side-condition (that `x.msb = false`).

This PR also upstreams a minor `Nat` theorem (`Nat.div_le_div_left`)
needed for the above from Mathlib.

---------

Co-authored-by: Kim Morrison <scott@tqft.net>
2025-01-10 02:31:16 +00:00
jrr6
c07948a168 feat: add simp? and dsimp? in conversion mode (#6593)
This PR adds support for the `simp?` and `dsimp?` tactics in conversion
mode.

Closes #6164
2025-01-10 01:42:17 +00:00
Leonardo de Moura
d369976474 feat: improve inequality offset support theorems for grind (#6595)
This PR improves the theorems used to justify the steps performed by the
inequality offset module. See new test for examples of how they are
going to be used.
2025-01-09 20:43:30 +00:00
Henrik Böving
a6789a73ff feat: Std.Net.Addr (#6563)
This PR implements `Std.Net.Addr` which contains structures around IP
and socket addresses.

While we could implement our own parser instead of going through the
`addr_in`/`addr_in6` route we will need to implement these conversions
to make proper system calls anyway. Hence this is likely the approach
with the least amount of non trivial code overall. The only thing I am
uncertain about is whether `ofString` should return `Option` or
`Except`, unfortunately `libuv` doesn't hand out error messages on IP
parsing.
2025-01-09 09:33:03 +00:00
David Thrane Christiansen
1b4272821d feat: add UInt32.{lt, le} (#6591)
This PR adds less-than and less-than-or-equal-to relations to `UInt32`,
consistent with the other `UIntN` types.
2025-01-09 07:01:35 +00:00
Leonardo de Moura
dd6445515d feat: improve grind canonicalizer diagnostics (#6588)
This PR improves the `grind` canonicalizer diagnostics.

---------

Co-authored-by: Kim Morrison <scott.morrison@gmail.com>
2025-01-09 06:21:42 +00:00
Kim Morrison
827c6676fd feat: align List/Array lemmas for filter/filterMap (#6589)
This PR continues aligning `List/Array` lemmas, finishing `filter` and
`filterMap`.
2025-01-09 04:15:47 +00:00
Kim Morrison
623dec1047 feat: aligning List/Array/Vector lemmas for map (#6586)
This PR continues aligning `List/Array/Vector` lemmas, finishing up
lemmas about `map`.
2025-01-09 02:27:20 +00:00
Leonardo de Moura
cb9f198f01 fix: grind canonicalizer (#6585)
This PR fixes a bug in the `grind` canonicalizer.
2025-01-09 02:23:46 +00:00
Leonardo de Moura
c5314da28e feat: add helper theorems for handling offsets in grind (#6584)
This PR adds helper theorems to implement offset constraints in grind.
2025-01-09 01:32:49 +00:00
Leonardo de Moura
0afa1d1e5d feat: apply E-matching for local lemmas in grind (#6582)
This PR adds support for creating local E-matching theorems for
universal propositions known to be true. It allows `grind` to
automatically solve examples such as:

```lean
example (b : List α) (p : α → Prop) (h₁ : ∀ a ∈ b, p a) (h₂ : ∃ a ∈ b, ¬p a) : False := by
  grind
```
2025-01-08 21:37:29 +00:00
Leonardo de Moura
ddd454c9c1 feat: add grind configuration options to control case-splitting (#6581)
This PR adds the following configuration options to `Grind.Config`:
`splitIte`, `splitMatch`, and `splitIndPred`.
2025-01-08 20:52:21 +00:00
Leonardo de Moura
5be241cba0 fix: forall propagation in grind (#6578)
This PR fixes and improves the propagator for forall-expressions in the
`grind` tactic.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2025-01-08 18:03:31 +00:00
Sebastian Ullrich
034bc26740 feat: make classical tactic incremental (#6575)
This PR ensures tactics are evaluated incrementally in the body of
`classical`.
2025-01-08 13:04:31 +00:00
Sebastian Ullrich
680ede7a89 fix: set LLVM sysroot consistently (#6574)
This PR actually prevents Lake from accidentally picking up other
toolchains installed on the machine.

Fixes regression introduced in #6176
2025-01-08 12:56:27 +00:00
Henrik Böving
48eb3084a0 perf: speed up JSON serialisation (#6479)
This PR speeds up JSON serialisation by using a lookup table to check
whether a string needs to be escaped.

The approach is based on
https://byroot.github.io/ruby/json/2024/12/15/optimizing-ruby-json-part-1.html.
2025-01-08 12:06:25 +00:00
Sebastian Graf
f01471f620 fix: proper "excess binders" error locations for rintro and intro (#6565)
This PR fixes the location of the error emitted when the `rintro` and
`intro` tactics cannot introduce the requested number of binders.

This patch adds a few `withRef` wrappers to invocations of
`MVarId.intro` to fix error locations. Perhaps `MVarId.intro` should
take a syntax object to set the location itself in the future; however
there are a couple other call sites which would need non-trivial fixup.

Closes  #5659.
2025-01-08 08:36:45 +00:00
Leonardo de Moura
00ef231a6e feat: split on match-expressions in the grind tactic (#6569)
This PR adds support for case splitting on `match`-expressions in
`grind`.
We still need to add support for resolving the antecedents of
`match`-conditional equations.
2025-01-08 03:10:11 +00:00
Tobias Grosser
9040108e2f feat: add BitVec.[toNat|toInt|toFin|getLsbD|getMsbD|getElem|msb]_fill (#6177)
This PR implements `BitVec.*_fill`.

We also add `toInt_allOnes` and `toFin_allOnes` as the former is needed
here. This completes the allOnes API.
2025-01-08 02:57:53 +00:00
Harun Khan
91cbd7c80e feat: BitVec.toInt_shiftLeft theorem (#6346)
This PR completes the toNat/Int/Fin family for `shiftLeft`.
2025-01-08 02:55:50 +00:00
Kyle Miller
18b183f62b feat: let induction take zero alteratives (#6486)
This PR modifies the `induction`/`cases` syntax so that the `with`
clause does not need to be followed by any alternatives. This improves
friendliness of these tactics, since this lets them surface the names of
the missing alternatives:
```lean
example (n : Nat) : True := by
  induction n with
/-            ~~~~
alternative 'zero' has not been provided
alternative 'succ' has not been provided
-/
```

Related to issue #3555
2025-01-08 02:25:21 +00:00
Vlad Tsyrklevich
78ed072ab0 feat: add Int.emod_sub_emod and Int.sub_emod_emod (#6507)
This PR adds the subtraction equivalents for `Int.emod_add_emod` (`(a %
n + b) % n = (a + b) % n`) and `Int.add_emod_emod` (`(a + b % n) % n =
(a + b) % n`). These are marked @[simp] like their addition equivalents.

Discussed on Zulip in

https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Adding.20some.20sub_emod.20lemmas.20to.20DivModLemmas
2025-01-08 02:20:43 +00:00
Leonardo de Moura
22a799524f feat: add support for cast, Eq.rec, Eq.ndrec to grind (#6568)
This PR adds basic support for cast-like operators to the grind tactic.
Example:
```lean
example (α : Type) (β : Type) (a₁ a₂ : α) (b₁ b₂ : β)
        (h₁ : α = β)
        (h₂ : h₁ ▸ a₁ = b₁)
        (h₃ : a₁ = a₂)
        (h₄ : b₁ = b₂)
        : HEq a₂ b₂ := by
  grind
```
2025-01-08 00:21:13 +00:00
Leonardo de Moura
5decd2ce20 feat: trace messages for working and closing goals in the grind tactic (#6567)
This PR adds support for erasing the `[grind]` attribute used to mark
theorems for heuristic instantiation in the `grind` tactic.
2025-01-07 23:27:36 +00:00
Leonardo de Moura
0da5be1ba1 feat: add support for erasing the [grind] attribute (#6566)
This PR adds support for erasing the `[grind]` attribute used to mark
theorems for heuristic instantiation in the `grind` tactic.
2025-01-07 19:35:31 +00:00
Kim Morrison
83098cdaec chore: typos / improvements to grind messages (#6561)
This PR fixes some typos and makes minor improvements to grind
doc-strings and messages.
2025-01-07 14:25:01 +00:00
Sebastian Ullrich
a2a525f5c7 fix: set absolute linker path (#6547)
This PR should prevent Lake from accidentally picking up other linkers
installed on the machine.
2025-01-07 14:06:24 +00:00
Leonardo de Moura
97d07a54a3 feat: basic case-split for grind (#6559)
This PR adds a basic case-splitting strategy for the `grind` tactic. We
still need to add support for user customization.
2025-01-07 01:53:04 +00:00
Kim Morrison
a424029475 feat: Array lemma alignment; fold and map (#6546)
This PR continues aligning `Array` and `Vector` lemmas with `List`,
working on `fold` and `map` operations.
2025-01-06 22:20:09 +00:00
Leonardo de Moura
db3ab39e05 feat: propagate implication in the grind tactic (#6556)
This PR adds propagators for implication to the `grind` tactic. It also
disables the normalization rule: `(p → q) = (¬ p ∨ q)`
2025-01-06 21:31:12 +00:00
Kim Morrison
8dec57987a feat: grind tests for basic category theory (#6543)
This PR adds additional tests for `grind`, demonstrating that we can
automate some manual proofs from Mathlib's basic category theory
library, with less reliance on Mathlib's `@[reassoc]` trick.

In several places I've added bidirectional patterns for equational
lemmas.

I've updated some other files to use the new `@[grind_eq]` attribute
(but left as is all cases where we are inspecting the info messages from
`grind_pattern`).

---------

Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
2025-01-06 16:29:50 +00:00
Leonardo de Moura
3ca3f848a8 fix: avoid new tokens _=_ and =_ (#6554)
This PR an issue introduced by the `[grind _=_]` attribute.
2025-01-06 16:18:44 +00:00
Bhavik Mehta
2c9641f621 doc: modify aesop usage example of omegaDefault (#6549)
This PR fixes #6548.
2025-01-06 13:13:16 +00:00
Kim Morrison
78ddee9112 feat: release checklist script (#6542)
This PR introduces a script that automates checking whether major
downstream repositories have been updated for a new toolchain release.

Sample output:
```
% ./release_checklist.py v4.16.0-rc1

Repository: Batteries
   On compatible toolchain (>= v4.16.0-rc1)
   Tag v4.16.0-rc1 exists

Repository: lean4checker
   On compatible toolchain (>= v4.16.0-rc1)
   Tag v4.16.0-rc1 exists

Repository: doc-gen4
   On compatible toolchain (>= v4.16.0-rc1)
   Tag v4.16.0-rc1 exists

Repository: Verso
   Not on target toolchain (needs ≥ v4.16.0-rc1, but main is on leanprover/lean4:v4.15.0)

Repository: ProofWidgets4
   On compatible toolchain (>= v4.16.0-rc1)

Repository: Aesop
   On compatible toolchain (>= v4.16.0-rc1)
   Tag v4.16.0-rc1 exists

Repository: import-graph
   On compatible toolchain (>= v4.16.0-rc1)
   Tag v4.16.0-rc1 exists

Repository: plausible
   On compatible toolchain (>= v4.16.0-rc1)
   Tag v4.16.0-rc1 exists

Repository: Mathlib
   On compatible toolchain (>= v4.16.0-rc1)
   Tag v4.16.0-rc1 exists

Repository: REPL
   Not on target toolchain (needs ≥ v4.16.0-rc1, but master is on leanprover/lean4:v4.14.0)
```
2025-01-06 06:37:01 +00:00
Leonardo de Moura
2ed77f3b26 feat: attribute [grind] (#6545)
This PR introduces the parametric attribute `[grind]` for annotating
theorems and definitions. It also replaces `[grind_eq]` with `[grind
=]`. For definitions, `[grind]` is equivalent to `[grind =]`.

The new attribute supports the following variants:

- **`[grind =]`**: Uses the left-hand side of the theorem's conclusion
as the pattern for E-matching.
- **`[grind =_]`**: Uses the right-hand side of the theorem's conclusion
as the pattern for E-matching.
- **`[grind _=_]`**: Creates two patterns. One for the left-hand side
and one for the right-hand side.
- **`[grind →]`**: Searches for (multi-)patterns in the theorem's
antecedents, stopping once a usable multi-pattern is found.
- **`[grind ←]`**: Searches for (multi-)patterns in the theorem's
conclusion, stopping once a usable multi-pattern is found.
- **`[grind]`**: Searches for (multi-)patterns in both the theorem's
conclusion and antecedents. It starts with the conclusion and stops once
a usable multi-pattern is found.

The `grind_pattern` command remains available for cases where these
attributes do not yield the desired result.
2025-01-06 03:05:20 +00:00
Sebastian Ullrich
76f883b999 fix: remove unused -static-libgcc MinGW linker arg (#6535)
This PR avoids a linker warning on Windows.

The argument may have been superfluous ever since the initial
implementation.
2025-01-05 21:57:56 +00:00
Leonardo de Moura
675244de76 feat: [grind_eq] attribute for the grind tactic (#6539)
This PR introduces the `[grind_eq]` attribute, designed to annotate
equational theorems and functions for heuristic instantiations in the
`grind` tactic.
When applied to an equational theorem, the `[grind_eq]` attribute
instructs the `grind` tactic to automatically use the annotated theorem
to instantiate patterns during proof search. If applied to a function,
it marks all equational theorems associated with that function.

```lean
@[grind_eq]
theorem foo_idempotent : foo (foo x) = foo x := ...

@[grind_eq] def f (a : Nat) :=
  match a with
  | 0 => 10
  | x+1 => g (f x)
```

In the example above, the `grind` tactic will add instances of the
theorem `foo_idempotent` to the local context whenever it encounters the
pattern `foo (foo x)`. Similarly, functions annotated with `[grind_eq]`
will propagate this annotation to their associated equational theorems.
2025-01-05 21:38:05 +00:00
Leonardo de Moura
fd091d1dfe feat: pattern normalization in the grind tactic (#6538)
This PR ensures patterns provided by users are normalized. See new test
to understand why this is needed.
2025-01-05 19:35:52 +00:00
Leonardo de Moura
7b29f488df fix: E-matching thresholds in the grind tactic (#6536)
This PR fixes different thresholds for controlling E-matching in the
`grind` tactic.
2025-01-05 17:34:56 +00:00
Leonardo de Moura
fb506b957c fix: allow projections in E-matching patterns (#6534)
This PR ensures that users can utilize projections in E-matching
patterns within the `grind` tactic.
2025-01-05 16:20:54 +00:00
Leonardo de Moura
dc5c8097b5 feat: add term offset support to the grind E-matching modulo (#6533)
This PR adds support to E-matching offset patterns. For example, we want
to be able to E-match the pattern `f (#0 + 1)` with term `f (a + 2)`.
2025-01-05 02:20:17 +00:00
Kim Morrison
9dcbc330fd chore: fix signature of perm_insertIdx (#6532) 2025-01-04 23:43:23 +00:00
Leonardo de Moura
d22233fc7b fix: let_fun support in grind (#6531)
This PR fixes the support for `let_fun` in `grind`.
2025-01-04 22:22:55 +00:00
Leonardo de Moura
a5b1ed906c fix: nondeterministic failure in grind (#6530)
This PR fixes nondeterministic failures in the (WIP) `grind` tactic.
2025-01-04 21:40:32 +00:00
Leonardo de Moura
ad2c16dade feat: add support for let-declarations to grind (#6529)
This PR adds support for `let`-declarations to the (WIP) `grind` tactic.
2025-01-04 19:24:56 +00:00
Leonardo de Moura
37127ead07 fix: missing propagation in grind (#6528)
This PR adds a missing propagation rule to the (WIP) `grind` tactic.
2025-01-04 18:45:55 +00:00
Kitamado
31435e9cd1 doc: fix broken code blocks in RELEASES.md (#6527)
just fix markdown
2025-01-04 08:08:12 +00:00
Kim Morrison
639e6e92a4 chore: cleanup imports in Lean.Lsp (#6523)
This PR splits a definition out of `Lean.Lsp.Basic`, with the effect
that material about JSON is not needed for `Lean.Meta.Sorry` and its
dependencies.
2025-01-04 04:33:24 +00:00
Kim Morrison
9080df3110 chore: import cleanup in Init (#6522)
This PR avoids unnecessarily importing "kitchen sink" files.
2025-01-04 04:13:13 +00:00
Kim Morrison
cdeb958afd chore: add plausible to release checklist (#6525) 2025-01-04 04:08:21 +00:00
Kim Morrison
d2189542b5 chore: upstream some List.Perm lemmas (#6524)
This PR upstreams some remaining `List.Perm` lemmas from Batteries.
2025-01-04 04:04:13 +00:00
Leonardo de Moura
ad593b36d9 feat: add support for match-expressions to grind (#6521)
This PR adds support for activating relevant `match`-equations as
E-matching theorems. It uses the `match`-equation lhs as the pattern.
2025-01-04 02:18:43 +00:00
Kim Morrison
28a7098728 feat: add script for generating release notes (#6519)
This PR adds a script to automatically generate release notes using the
new `changelog-*` labels and "This PR ..." conventions.

Usage:
```
script/release_notes.py v4.X.0
```
where `v4.X.0` is the **previous** release, i.e. the script will process
all commits *since* that tag.
2025-01-04 01:31:02 +00:00
Kim Morrison
d991feddad chore: cherry-pick release notes from releases/v4.15.0 and releases/v4.16.0 (#6520)
These release notes were automatically generated by the script in #6519.
2025-01-04 01:25:33 +00:00
Henrik Böving
58d178e68f fix: cond reflection bug in bv_decide (#6517)
This PR fixes a slight bug that was created in the reflection of `bif`
in `bv_decide`.

Tagged as changelog-no as the code in question isn't in an RC yet.
2025-01-03 19:35:58 +00:00
Leonardo de Moura
7b496bf44b feat: improve cases tactic used in grind (#6516)
This PR enhances the `cases` tactic used in the `grind` tactic and
ensures that it can be applied to arbitrary expressions.
2025-01-03 15:54:55 +00:00
Mitchell Lee
10b2f6b27e feat: bdiv and bmod lemmas (#6494)
This PR proves the basic theorems about the functions `Int.bdiv` and
`Int.bmod`.

For all integers `x` and all natural numbers `m`, we have:
- `Int.bdiv_add_bmod`: `m * bdiv x m + bmod x m = x` (which is stated in
the docstring for docs#Int.bdiv)
- `Int.bmod_add_bdiv`: `bmod x m + m * bdiv x m = x`
- `Int.bdiv_add_bmod'`: `bdiv x m * m + bmod x m = x`
- `Int.bmod_add_bdiv'`: `bmod x m + bdiv x m * m = x`
- `Int.bmod_eq_self_sub_mul_bdiv`: `bmod x m = x - m * bdiv x m`
- `Int.bmod_eq_self_sub_bdiv_mul`: `bmod x m = x - bdiv x m * m`

These theorems are all equivalent to each other by the basic properties
of addition, multiplication, and subtraction of integers.

The names `Int.bdiv_add_bmod`, `Int.bmod_add_bdiv`,
`Int.bdiv_add_bmod'`, and `Int.bmod_add_bdiv'` are meant to parallel the
names of the existing theorems docs#Int.tmod_add_tdiv,
docs#Int.tdiv_add_tmod, docs#Int.tmod_add_tdiv', and
docs#Int.tdiv_add_tmod'.

The names `Int.bmod_eq_self_sub_mul_bdiv` and
`Int.bmod_eq_self_sub_bdiv_mul` follow mathlib's naming conventions.
Note that there is already a theorem called docs#Int.bmod_def, so it
would not have been possible to parallel the name of the existing
theorem docs#Int.tmod_def.

See
https://leanprover.zulipchat.com/#narrow/channel/217875-Is-there-code-for-X.3F/topic/bdiv.20and.20bmod.

Closes #6493.
2025-01-03 09:37:02 +00:00
Leonardo de Moura
19078655bc perf: avoid unnecessary assert/intro pairs in grind (#6514)
This PR enhances the assertion of new facts in `grind` by avoiding the
creation of unnecessary metavariables.
2025-01-03 02:16:08 +00:00
Leonardo de Moura
df9ed20385 feat: ite and dite support in grind (#6513)
This PR adds support for (dependent) if-then-else terms (i.e., `ite` and
`dite` applications) in the `grind` tactic.
2025-01-03 01:05:44 +00:00
Leonardo de Moura
3e2f1faebf feat: add user-defined fallback procedure for the grind tactic (#6512)
This PR introduces support for user-defined fallback code in the `grind`
tactic. The fallback code can be utilized to inspect the state of
failing `grind` subgoals and/or invoke user-defined automation. Users
can now write `grind on_failure <code>`, where `<code>` should have the
type `GoalM Unit`. See the modified tests in this PR for examples.
2025-01-02 23:56:51 +00:00
Leonardo de Moura
9d622270a1 feat: custom congruence rule for equality in grind (#6510)
This PR adds a custom congruence rule for equality in `grind`. The new
rule takes into account that `Eq` is a symmetric relation. In the
future, we will add support for arbitrary symmetric relations. The
current rule is important for propagating disequalities effectively in
`grind`.
2025-01-02 22:08:19 +00:00
Leonardo de Moura
e46b5f39bf fix: congruence closure in the grind tactic (#6509)
This PR fixes a bug in the congruence closure data structure used in the
`grind` tactic. The new test includes an example that previously caused
a panic. A similar panic was also occurring in the test
`grind_nested_proofs.lean`.
2025-01-02 19:08:02 +00:00
Leonardo de Moura
3cba17140f fix: missing case in checkParents (#6508)
This PR fixes a bug in the sanity checkers for the `grind` tactic. See
the new test for an example of a case where it was panicking.
2025-01-02 16:06:52 +00:00
Lean stage0 autoupdater
092449adb8 chore: update stage0 2025-01-02 12:29:37 +00:00
Joachim Breitner
e9f069146c feat: partial_fixpoint: monotonicity tactic (#6506)
This PR adds the `monotonicity` tactic, intended to be used inside the
`partial_fixpoint` feature.

Part of #6355.
2025-01-02 11:07:05 +00:00
Joachim Breitner
7d0c0d4d92 feat: partial_fixpoint: theory (#6477)
This PR adds the necessary domain theory that backs the
`partial_fixpoint` feature.

Part of #6355.
2025-01-02 09:39:18 +00:00
Eric Wieser
9eb173e444 fix: ignore no_index around OfNat.ofNat in norm_cast (#6438)
This PR ensures `norm_cast` doesn't fail to act in the presence of
`no_index` annotations

While leanprover/lean4#2867 exists, it is necessary to put `no_index`
around `OfNat.ofNat` in simp lemmas.
This results in extra `Expr.mdata` nodes, which must be removed before
checking for `ofNat` numerals.
2025-01-02 09:10:27 +00:00
Leonardo de Moura
8d9d81453b feat: grind simple strategy (#6503)
This PR adds a simple strategy to the (WIP) `grind` tactic. It just
keeps internalizing new theorem instances found by E-matching. The
simple strategy can solve examples such as:

```lean
grind_pattern Array.size_set => Array.set a i v h
grind_pattern Array.get_set_eq  => a.set i v h
grind_pattern Array.get_set_ne => (a.set i v hi)[j]

example (as bs : Array α) (v : α)
        (i : Nat)
        (h₁ : i < as.size)
        (h₂ : bs = as.set i v)
        : as.size = bs.size := by
  grind

example (as bs cs : Array α) (v : α)
        (i : Nat)
        (h₁ : i < as.size)
        (h₂ : bs = as.set i v)
        (h₃ : cs = bs)
        (h₄ : i ≠ j)
        (h₅ : j < cs.size)
        (h₆ : j < as.size)
        : cs[j] = as[j] := by
  grind


opaque R : Nat → Nat → Prop
theorem Rtrans (a b c : Nat) : R a b → R b c → R a c := sorry

grind_pattern Rtrans => R a b, R b c

example : R a b → R b c → R c d → R d e → R a d := by
  grind
```
2025-01-02 05:36:01 +00:00
Leonardo de Moura
a08379ce2e fix: proof generation for grind tactic (#6502)
This PR fixes a bug in the proof assembly procedure utilized by the
`grind` tactic.
2025-01-02 04:42:31 +00:00
Leonardo de Moura
f0c59364f4 feat: add PersistentHashSet.toList (#6501)
This PR adds `PersistentHashSet.toList`
2025-01-02 03:52:21 +00:00
Leonardo de Moura
c0d67e2a65 fix: bug in markNestedProofs within grind (#6500)
This PR fixes a bug in the `markNestedProofs` used in `grind`. See new
test.
2025-01-02 02:14:45 +00:00
Leonardo de Moura
a8d09dad1b fix: proof canonicalizer in grind (#6499)
This PR fixes the proof canonicalizer for `grind`.
2025-01-02 01:26:39 +00:00
Leonardo de Moura
f7c4edc2b7 feat: dependent forall propagator in grind (#6498)
This PR adds support in the `grind` tactic for propagating dependent
forall terms `forall (h : p), q[h]` where `p` is a proposition.
2025-01-02 00:08:36 +00:00
Leonardo de Moura
82bae24e59 fix: another bug in theorem instantiation in grind (#6497)
This PR fixes another theorem instantiation bug in the `grind` tactic.
It also moves new instances to be processed to `Goal`.
2025-01-01 23:09:21 +00:00
Leonardo de Moura
fedaf850bb fix: theorem instantiation in grind (#6492)
This PR fixes a bug in the theorem instantiation procedure in the (WIP)
`grind` tactic. For example, it was missing the following instance in
one of the tests:

```lean
[grind.ematch.instance] Array.get_set_ne: ∀ (hj : i < bs.size), j ≠ i → (bs.set j w ⋯)[i] = bs[i]
```

This PR also renames the `grind` base monad to `GrindCoreM`.
2025-01-01 17:56:27 +00:00
Kyle Miller
6d447156c4 fix: make sure parent structure projections have 'go to definition' information (#6487)
This PR adds source position information for `structure` parent
projections, supporting "go to definition". Closes #3063.
2024-12-31 21:59:38 +00:00
Leonardo de Moura
3427630a14 feat: configuration options for the grind tactic (#6490)
This PR adds basic configuration options for the `grind` tactic.
2024-12-31 21:09:41 +00:00
Leonardo de Moura
5ba476116f fix: E-matching module for grind (#6488)
This PR fixes and refactors the E-matching module for the (WIP) `grind`
tactic.

Next step: top-level search procedure for `grind`.
2024-12-31 20:07:27 +00:00
Leonardo de Moura
8899c7ed8c feat: instantiate ematch theorems in grind (#6485)
This PR implements `Grind.EMatch.instantiateTheorem` in the (WIP)
`grind` tactic.
2024-12-31 19:25:12 +00:00
Kyle Miller
640b356a04 chore: add missing diff-exposing in type/value mismatch errors (#6484)
This PR addresses a few error messages where diffs weren't being
exposed.
2024-12-31 17:47:12 +00:00
Kyle Miller
8f5ce3a356 feat: upstream ToExpr deriving handler from Mathlib (#6473)
This PR adds a deriving handler for the `ToExpr` class. It can handle
mutual and nested inductive types, however it falls back to creating
`partial` instances in such cases. This is upstreamed from the Mathlib
deriving handler written by @kmill, but has fixes to handle autoimplicit
universe level variables.

This is a followup to #6285 (adding the `ToLevel` class). This PR
supersedes #5906.

Co-authored-by: Alex Keizer <alex@keizer.dev>

---------

Co-authored-by: Alex Keizer <alex@keizer.dev>
2024-12-31 15:11:53 +00:00
Leonardo de Moura
2c87905d77 feat: E-matching procedure for the grind tactic (#6481)
This PR implements E-matching for the (WIP) `grind` tactic. We still
need to finalize and internalize the new instances.
2024-12-31 02:46:09 +00:00
Cameron Zwarich
32dc16590b chore: reduce churn in tests/lean/run/meta5.lean (#6480) 2024-12-31 02:32:56 +00:00
Leonardo de Moura
7e8e22e2bd fix: internalize nested ground patterns when activating ematch theorems (#6478)
This PR internalize nested ground patterns when activating ematch
theorems in the (WIP) `grind` tactic.
2024-12-30 16:13:47 +00:00
Leonardo de Moura
9b28c5879a feat: ematch theorem activation for grind (#6475)
This PR adds support for activating relevant theorems for the (WIP)
`grind` tactic. We say a theorem is relevant to a `grind` goal if the
symbols occurring in its patterns also occur in the goal.
2024-12-30 09:57:33 +00:00
Leonardo de Moura
24a8561ec4 feat: check pattern coverage in the grind_pattern command (#6474)
This PR adds pattern validation to the `grind_pattern` command. The new
`checkCoverage` function will also be used to implement the attributes
`@[grind_eq]`, `@[grind_fwd]`, and `@[grind_bwd]`.
2024-12-30 03:40:43 +00:00
Lean stage0 autoupdater
3c326d771c chore: update stage0 2024-12-29 21:10:53 +00:00
Leonardo de Moura
7433e74fc4 feat: theorem patterns for heuristic instantiation in grind (#6472)
This PR implements the command `grind_pattern`. The new command allows
users to associate patterns with theorems. These patterns are used for
performing heuristic instantiation with e-matching. In the future, we
will add the attributes `@[grind_eq]`, `@[grind_fwd]`, and
`@[grind_bwd]` to compute the patterns automatically for theorems.
2024-12-29 20:26:58 +00:00
Eric Wieser
11eea84fd5 doc: explain app_delab (#6450)
This PR adds a docstring to the `@[app_delab]` attribute.

---------

Co-authored-by: Kyle Miller <kmill31415@gmail.com>
2024-12-29 15:06:55 +00:00
Lean stage0 autoupdater
536c6a8ea6 chore: update stage0 2024-12-29 01:19:00 +00:00
Leonardo de Moura
9c0ef2a282 feat: add grind_pattern command (#6470)
This PR introduces a command for specifying patterns used in the
heuristic instantiation of global theorems in the `grind` tactic. Note
that this PR only adds the parser.
2024-12-29 00:44:40 +00:00
Leonardo de Moura
a781f9858c feat: missing data for grind e-match (#6469)
This PR adds support code for implementing e-match in the (WIP) `grind`
tactic.
2024-12-29 00:33:25 +00:00
Leonardo de Moura
5930db946c fix: Int.reduceNeg simproc (#6468)
This PR fixes issue #6467 


closes #6467
2024-12-28 22:58:09 +00:00
Leonardo de Moura
3fc74854d7 fix: check function types when detecting congruences in grind (#6466)
This PR completes the implementation of `addCongrTable` in the (WIP)
`grind` tactic. It also adds a new test to demonstrate why the extra
check is needed. It also updates the field `cgRoot` (congruence root).
2024-12-28 19:53:02 +00:00
Leonardo de Moura
fe45ddd610 feat: projections in grind (#6465)
This PR adds support for projection functions to the (WIP) `grind`
tactic.
2024-12-27 23:50:58 +00:00
Leonardo de Moura
f545df9922 feat: literal values in grind (#6464)
This PR completes support for literal values in the (WIP) `grind`
tactic. `grind` now closes the goal whenever it merges two equivalence
classes with distinct literal values.
2024-12-27 22:18:56 +00:00
Leonardo de Moura
844e82e176 feat: constructors in grind (#6463)
This PR adds support for constructors to the (WIP) `grind` tactic. When
merging equivalence classes, `grind` checks for equalities between
constructors. If they are distinct, it closes the goal; if they are the
same, it applies injectivity.
2024-12-27 21:15:02 +00:00
Leonardo de Moura
2d7d3388e2 fix: missing Not propagation rule in grind (#6461)
This PR adds a new propagation rule for negation to the (WIP) `grind`
tactic.
2024-12-27 17:37:32 +00:00
Henrik Böving
c14e5ae7de chore: implement reduceCond for bv_decide (#6460)
This PR implements the equivalent of `reduceIte` for `cond` in
`bv_decide` as we switched to `bif` for the `if` normal form.
2024-12-27 10:12:52 +00:00
Leonardo de Moura
6a839796fd feat: add grind tactic (#6459)
This PR adds the (WIP) `grind` tactic. It currently generates a warning
message to make it clear that the tactic is not ready for production.
2024-12-27 03:48:01 +00:00
Leonardo de Moura
e76dc20200 feat: use compact congruence proofs in grind if applicable (#6458)
This PR adds support for compact congruence proofs in the (WIP) `grind`
tactic. The `mkCongrProof` function now verifies whether the congruence
proof can be constructed using only `congr`, `congrFun`, and `congrArg`,
avoiding the need to generate the more complex `hcongr` auxiliary
theorems.
2024-12-26 23:58:04 +00:00
Leonardo de Moura
dca874ea57 feat: congruence proofs for grind (#6457)
This PR adds support for generating congruence proofs for congruences
detected by the `grind` tactic.
2024-12-26 22:20:36 +00:00
Leonardo de Moura
c282d558fa fix: fix: bug in mkEqProof within grind (#6456)
This PR fixes another bug in the equality proof generator in the (WIP)
`grind` tactic.
2024-12-26 19:03:35 +00:00
Leonardo de Moura
57050be3ab fix: bug in mkEqProof within grind (#6455)
This PR fixes a bug in the equality proof generator in the (WIP) `grind`
tactic.
2024-12-26 18:25:11 +00:00
Henrik Böving
37b53b70d0 perf: improve bv_decide performance with large literals (#6453)
This PR improves bv_decide's performance in the presence of large
literals.

The core change of this PR is the reformulation of the reflection code
for literals to:
```diff
 def eval (assign : Assignment) : BVExpr w → BitVec w
   | .var idx =>
-    let ⟨bv⟩ := assign.get idx
-    bv.truncate w
+    let packedBv := assign.get idx
+    /-
+    This formulation improves performance, as in a well formed expression the condition always holds
+    so there is no need for the more involved `BitVec.truncate` logic.
+    -/
+    if h : packedBv.w = w then
+      h ▸ packedBv.bv
+    else
+      packedBv.bv.truncate w
```
The remainder is merely further simplifications that make the terms
smaller and easier to deal with in general. This change is motivated by
applying the following diff to the kernel:
```diff
diff --git a/src/kernel/type_checker.cpp b/src/kernel/type_checker.cpp
index b0e6844dca..f13bb96bd4 100644
--- a/src/kernel/type_checker.cpp
+++ b/src/kernel/type_checker.cpp
@@ -518,6 +518,7 @@ optional<constant_info> type_checker::is_delta(expr const & e) const {
 optional<expr> type_checker::unfold_definition_core(expr const & e) {
     if (is_constant(e)) {
         if (auto d = is_delta(e)) {
+//            std::cout << "Working on unfolding: " << d->get_name() << std::endl;
             if (length(const_levels(e)) == d->get_num_lparams()) {
                 if (m_diag) {
                     m_diag->record_unfold(d->get_name());
```
and observing that in the test case from #6043 we see a long series of
```
Working on unfolding: Bool.decEq
Working on unfolding: Bool.decEq.match_1
Working on unfolding: Bool.casesOn
Working on unfolding: Nat.ble
Working on unfolding: Nat.brecOn
Working on unfolding: Nat.beq.match_1
Working on unfolding: Nat.casesOn
Working on unfolding: Nat.casesOn
Working on unfolding: Nat.beq.match_1
Working on unfolding: Nat.casesOn
Working on unfolding: Nat.casesOn
```
the chain begins with `BitVec.truncate`, works through a few
abstractions and then continues like above forever, so I avoid the call
to truncate like this. It is not quite clear to me why removing `ofBool`
helps so much here, maybe some other kernel heuristic kicks in to rescue
us.

Either way this diff is a general improvement for reflection of `BitVec`
constants as we should never have to run `BitVec.truncate` again!

Fixes: #6043
2024-12-26 16:50:00 +00:00
Leonardo de Moura
8a1e50f0b9 feat: equality proof generation for grind (#6452)
This PR adds support for generating (small) proofs for any two
expressions that belong to the same equivalence class in the `grind`
tactic state.
2024-12-26 06:01:45 +00:00
Leonardo de Moura
bdcb7914b5 chore: check whether pointer equality implies structural equality in grind (#6451)
This PR checks whether in the internal state of the `grind` tactic
pointer equality implies structural equality.
2024-12-26 03:50:39 +00:00
Leonardo de Moura
0ebe9e5ba3 feat: support for builtin grind propagators (part 2) (#6449)
This PR completes the implementation of the command
`builtin_grind_propagator`.
2024-12-25 23:54:55 +00:00
Lean stage0 autoupdater
65e8ba0574 chore: update stage0 2024-12-25 23:27:32 +00:00
Leonardo de Moura
3cddae6492 feat: support for builtin grind propagators (#6448)
This PR declares the command `builtin_grind_propagator` for registering
equation propagator for `grind`. It also declares the auxiliary the
attribute.
2024-12-25 22:55:39 +00:00
Leonardo de Moura
977b8e001f refactor: move simplifier support to GrindM (#6447)
This PR refactors `grind` and adds support for invoking the simplifier
using the `GrindM` monad.
2024-12-25 21:01:32 +00:00
Leonardo de Moura
f9f8abe2a3 feat: propagate equality in grind (#6443)
This PR adds support for propagating the truth value of equalities in
the (WIP) `grind` tactic.
2024-12-24 23:54:36 +00:00
Leonardo de Moura
ec80de231e fix: checkParents in grind (#6442)
This PR fixes the `checkParents` sanity check in `grind`.
2024-12-24 22:45:18 +00:00
Leonardo de Moura
630577a9ea feat: truth value propagation for grind (#6441)
This PR adds basic truth value propagation rules to the (WIP) `grind`
tactic.
2024-12-24 21:12:53 +00:00
Leonardo de Moura
cde35bcc0d test: grind (#6440)
This PR adds additional tests for `grind` and fixed minor issues.
2024-12-24 04:33:05 +00:00
Leonardo de Moura
b18f3a3877 feat: detect congruent terms in grind (#6437)
This PR adds support for detecting congruent terms in the (WIP) `grind`
tactic. It also introduces the `grind.debug` option, which, when set to
`true`, checks many invariants after each equivalence class is merged.
This option is intended solely for debugging purposes.
2024-12-24 00:11:36 +00:00
Leonardo de Moura
5240405cf4 feat: congruence table for grind tactic (#6435)
This PR implements the congruence table for the (WIP) `grind` tactic. It
also fixes several bugs, and adds a new preprocessing step.
2024-12-23 02:31:42 +00:00
Leonardo de Moura
eb6c52e7e2 feat: canonicalizer for the grind tactic (#6433)
This PR adds a custom type and instance canonicalizer for the (WIP)
`grind` tactic. The `grind` tactic uses congruence closure but
disregards types, type formers, instances, and proofs. Proofs are
ignored due to proof irrelevance. Types, type formers, and instances are
considered supporting elements and are not factored into congruence
detection. Instead, `grind` only checks whether elements are
structurally equal, which, in the context of the `grind` tactic, is
equivalent to pointer equality. See new tests for examples where the
canonicalizer is important.
2024-12-21 22:32:25 +00:00
Kyle Miller
71942631d7 feat: explanations for cases applied to non-inductive types (#6378)
This PR adds an explanation to the error message when `cases` and
`induction` are applied to a term whose type is not an inductive type.
For `Prop`, these tactics now suggest the `by_cases` tactic. Example:
```
tactic 'cases' failed, major premise type is not an inductive type
  Prop

Explanation: the 'cases' tactic is for constructor-based reasoning as well as for applying
custom cases principles with a 'using' clause or a registered '@[cases_eliminator]' theorem.
The above type neither is an inductive type nor has a registered theorem.

Consider using the 'by_cases' tactic, which does true/false reasoning for propositions.
```

[Zulip
discussion](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Improving.20the.20error.20for.20.60cases.20p.60.20when.20.60p.60.20is.20a.20proposition/near/488882682)
2024-12-21 21:38:30 +00:00
Leonardo de Moura
16bc6ebcb6 fix: ensure simp and dsimp do not unfold too much (#6397)
This PR ensures that `simp` and `dsimp` do not unfold definitions that
are not intended to be unfolded by the user. See issue #5755 for an
example affected by this issue.

Closes #5755

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2024-12-21 04:16:15 +00:00
Leonardo de Moura
9e30ac3265 feat: add Expr.fvarsSubset (#6430)
This PR adds the predicate `Expr.fvarsSet a b`, which returns `true` if
and only if the free variables in `a` are a subset of the free variables
in `b`.
2024-12-20 22:29:47 +00:00
Cameron Zwarich
bf1d253764 feat: add support for extern LCNF decls (#6429)
This PR adds support for extern LCNF decls, which is required for parity
with the existing code generator.
2024-12-20 21:20:56 +00:00
Leonardo de Moura
052f3f54c8 fix: normalize universe levels in grind preprocessor (#6428)
This PR adds a new preprocessing step to the `grind` tactic:
universe-level normalization. The goal is to avoid missing equalities in
the congruence closure module.
2024-12-20 20:41:59 +00:00
Kim Morrison
39eaa214d4 chore: protect some lemmas in List/Array/Vector namespace (#6425) 2024-12-20 11:23:56 +00:00
Kim Morrison
9a53c88ecf chore: temporarily disable Web Assembly build in CI (#6424) 2024-12-20 08:58:10 +00:00
Kim Morrison
e06673e200 feat: lemmas about List/Array/Vector lexicographic order (#6423)
This PR adds missing lemmas about lexicographic order on
List/Array/Vector.
2024-12-20 06:16:27 +00:00
Mac Malone
7b0b1909f1 feat: lake: local package overrides (#6411)
This PR adds the ability to override package entries in a Lake manifest
via a separate JSON file. This file can be specified on the command line
with `--packages` or applied persistently by placing it at
`.lake/package-overrides.json`.

The overrides file is a subset of `lake-manifest.json` with just a
version and a `packages` field. The entries in the package share the
syntax of the manifest file and take precedence over the entries there.
Lake loads the entries from the manifest, then overrides them with those
in `.lake/package-overrides.json` (if any) and then those in any file
passed to `--packages`.
2024-12-20 05:33:50 +00:00
Mac Malone
759da5d52c fix: lake: afterBuildCache* traces (#6422)
This PR fixes a bug in #6388 where the `Package.afterBuildCahe*`
functions would produce different traces depending on whether the cache
was fetched.
2024-12-20 04:39:46 +00:00
Leonardo de Moura
9fca337f38 fix: multiple bugs in grind (#6419)
This PR fixes multiple bugs in the WIP `grind` tactic. It also adds
support for printing the `grind` internal state.
2024-12-19 23:44:44 +00:00
Kyle Miller
12cadda3bd fix: process delayed assignment metavariables correctly in Lean.Meta.Closure (#6414)
This PR fixes a bug in `Lean.Meta.Closure` that would introduce
under-applied delayed assignment metavariables, which would keep them
from ever getting instantiated. This bug affected `match` elaboration
when the expected type contained postponed elaboration problems, for
example tactic blocks.

Closes #5925, closes #6354
2024-12-19 20:15:49 +00:00
Kim Morrison
b4ff5455ba feat: lemmas about lexicographic order on Array and Vector (#6399)
This PR adds basic lemmas about lexicographic order on Array and Vector,
achieving parity with List.

Many lemmas are still missing for all three, particularly about how
order interacts with `++`.
2024-12-19 10:36:50 +00:00
Kim Morrison
5dd35360d9 chore: protect Nat.div_eq_iff (#6417)
Protects a recently added lemma to avoid collision in Mathlib. I will
need to protect many more of the core `Nat` lemmas later.
2024-12-19 10:35:17 +00:00
Leonardo de Moura
5b14d3e809 fix: sharecommon bug (#6415)
This PR fixes a bug in the `sharecommon` module, which was returning
incorrect results for objects that had already been processed by
`sharecommon`. See the new test for an example that triggered the bug.
2024-12-19 02:52:56 +00:00
Leonardo de Moura
7b81fb7050 feat: grind preprocessing and Expr internalization (#6413)
This PR introduces the following features to the WIP `grind` tactic:
- `Expr` internalization.
- Congruence theorem cache.
- Procedure for adding new facts
- New tracing options
- New preprocessing steps: fold projections and eliminate dangling
`Expr.mdata`
2024-12-19 00:16:48 +00:00
François G. Dorais
75fc103be4 chore: fix some docstrings (#6410)
Minor: Uniformize language. Fix some typos.
2024-12-18 19:32:07 +00:00
Lean stage0 autoupdater
1214e6463f chore: update stage0 2024-12-18 17:14:27 +00:00
Mac Malone
3e942f2654 refactor: lake: merge BuildJob into Job (#6388)
This PR merges `BuildJob` and `Job`, deprecating the former. `Job` now
contains a trace as part of its state which can be interacted with
monadically. This PR also simplifies the implementation of `OpaqueJob`.

This merger removes the need in Lake to distinguish between different
kinds of jobs, which helps enable the overall goal of making all targets
return a `Job` (and therefore make it easer for the frontend to
manipulate them in, e.g., #6323).
2024-12-18 08:19:01 +00:00
Leonardo de Moura
bc9b814858 feat: reserved names for congruence theorems (#6412)
This PR adds reserved names for congruence theorems used in the
simplifier and `grind` tactics. The idea is prevent the same congruence
theorems to be generated over and over again.

After update stage0, we must use the new API in the simplifier.
2024-12-18 06:19:29 +00:00
David Thrane Christiansen
11fc9b9bca chore: update documentation title and link README to reference (#6409)
This PR makes the title of the mdbook documentation page reflect the
updated link on lean-lang.org and adds the reference manual to the
README.
2024-12-17 22:18:56 +00:00
Marc Huisinga
dc24ebde2f fix: ghost goals in autoparam tactic block (#6408)
This PR fixes a regression where goals that don't exist were being
displayed. The regression was triggered by #5835 and originally caused
by #4926.

Bug originally reported at
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/tactic.20doesn't.20change.20primary.20goal.20state/near/488957772.

The cause of this issue was that #5835 made certain `SourceInfo`s
canonical, which was directly transferred to several `TacticInfo`s by
#4926. The goal state selection mechanism would then pick up these extra
`TacticInfo`s.

The approach taken by this PR is to ensure that the `SourceInfo` that is
being transferred by #4926 is noncanonical.
2024-12-17 20:57:39 +00:00
Kyle Miller
64d3e9a48e chore: in #print for structures, mention 'field notation' (#6406)
This PR modifies `#print` for structures to say "field notation
resolution order" instead of just "resolution order".
2024-12-17 02:21:03 +00:00
Cameron Zwarich
1880c61507 feat: support erasure of Decidable.decide in new code generator (#6405)
This PR adds support for erasure of `Decidable.decide` to the new code
generator. It also adds a new `Probe.runOnDeclsNamed` function, which is
helpful for writing targeted single-file tests of compiler internals.

---------

Co-authored-by: Cameron Zwarich <cameron@lean-fro.org>
2024-12-17 01:48:55 +00:00
David Thrane Christiansen
5fcd42d71a chore: remove old language manual (#6401)
To avoid user confusion, there should be just one manual.

This PR deletes the old manual, adding a link to the new one; the
website config will redirect these pages to the corresponding new manual
content.
2024-12-16 14:37:16 +00:00
Eric Wieser
1b15a0f27c fix: add missing fields in the profiler datastructures (#6363)
This PR fixes errors at load time in the comparison mode of the Firefox
profiler.

See https://github.com/firefox-devtools/profiler/issues/5254


6306555856/src/types/profile.js (L313)
suggests there are a _lot_ of missing fields in these structures, which
means the firefox profiler could at any point break any historic
profiler data.


https://profiler.firefox.com/compare/calltree/?globalTrackOrder=0w2&profiles[]=https%3A%2F%2Fprofiler.firefox.com%2Fpublic%2Fx1j7asq6jwsyc368j58m8brbqef6s8vqsx0mnzr%2Fcalltree%2F%3FglobalTrackOrder%3D0%26thread%3D0%26v%3D10&profiles[]=https%3A%2F%2Fprofiler.firefox.com%2Fpublic%2F55hw0v1q2zhe2w6ds3zckt04d55vsa6wd9kqb4r%2Fcalltree%2F%3FglobalTrackOrder%3D0%26thread%3D0%26v%3D10&thread=0&timelineType=category&v=10
is a demo of this working.
2024-12-16 08:23:51 +00:00
Leonardo de Moura
0340f904b3 fix: check must check projections (#6398)
This PR ensures `Meta.check` check projections.

closes #5660
2024-12-16 06:42:18 +00:00
Kim Morrison
791bea027f feat: lemmas about Std.Range (#6396)
This PR adds lemmas reducing for loops over `Std.Range` to for loops
over `List.range'`.

Equivalent theorems previously existed in Batteries, but the underlying
definitions have changed so these are written from scratch.
2024-12-16 03:16:46 +00:00
Eric Wieser
5c2ef51b44 chore: add gitpod configuration (#6382)
This PR adds a dockerfile for use with Gitpod.

This provides all the dependencies, and kicks off a build once the
editor is opened for the first time.

It can be tested by going to
https://gitpod.io/#https://github.com/leanprover/lean4/pull/6382

This should make it less painful for users hoping to contribute small
lemmas to `Init/` and `Std/`; they can open gitpod and wait, rather than
having to read the docs to run a series of commands.
2024-12-15 21:38:13 +00:00
Mac Malone
a8656c5812 feat: generalize panic to Sort (#6333)
This PR generalizes the panic functions to a type of `Sort u` rather
than `Type u`. This better supports universe polymorphic types and
avoids confusing errors.

An minimal (but somewhat contrived) example of such a confusing error
is:

```lean
/-
stuck at solving universe constraint
  ?u.59+1 =?= max 1 ?u.7
while trying to unify
  Subtype.{?u.7} P : Sort (max 1 ?u.7)
with
  Subtype.{?u.7} P : Sort (max 1 ?u.7)
-/
def assertSubtype! {P : α → Prop} [Inhabited (Subtype P)] (a : α) [Decidable (P a)] : Subtype P := -- errors on :=
  if h : P a then 
    ⟨a, h⟩ 
  else 
    panic! "Property not satisified"
```
2024-12-15 21:36:45 +00:00
Eric Wieser
a8dc619f8e doc: split the docstring of LocalContext (#6340)
This results in better hovers in VSCode, without duplicating information
in a way that might go out of sync.
2024-12-15 21:35:25 +00:00
Kim Morrison
80fb404a04 chore: require 0 < Range.step (#6391)
This PR requires that the step size in `Std.Range` is positive, to avoid
ill-specified behaviour.
2024-12-15 11:33:41 +00:00
Kim Morrison
474adc8c9e feat: redefine Range.forIn' (#6390)
This PR redefines `Range.forIn'` and `Range.forM`, in preparation for
writing lemmas about them.
2024-12-15 09:47:50 +00:00
Kim Morrison
6893913683 feat: replace List.lt with List.Lex (#6379)
This PR replaces `List.lt` with `List.Lex`, from Mathlib, and adds the
new `Bool` valued lexicographic comparatory function `List.lex`. This
subtly changes the definition of `<` on Lists in some situations.

`List.lt` was a weaker relation: in particular if `l₁ < l₂`, then
`a :: l₁ < b :: l₂` may hold according to `List.lt` even if `a` and `b`
are merely incomparable
(either neither `a < b` nor `b < a`), whereas according to `List.Lex`
this would require `a = b`.

When `<` is total, in the sense that `¬ · < ·` is antisymmetric, then
the two relations coincide.

Mathlib was already overriding the order instances for `List α`,
so this change should not be noticed by anyone already using Mathlib.

We simultaneously add the boolean valued `List.lex` function,
parameterised by a `BEq` typeclass
and an arbitrary `lt` function. This will support the flexibility
previously provided for `List.lt`,
via a `==` function which is weaker than strict equality.
2024-12-15 08:22:39 +00:00
Leonardo de Moura
a8a160b091 fix: revertAll must clear auxiliary declarations (#6386)
This PR ensures that `revertAll` clears auxiliary declarations when
invoked directly by users.

closes #6263
2024-12-15 00:56:57 +00:00
Leonardo de Moura
e08d35cea1 fix: type incorrect term produced by contradiction (#6387)
This PR fixes a type error in the proof generated by the `contradiction`
tactic.

closes #4851
2024-12-15 00:21:15 +00:00
Leonardo de Moura
94641e88cf fix: simp_all? local declarations (#6385)
This PR fixes a bug in `simp_all?` that caused some local declarations
to be omitted from the `Try this:` suggestions.

closes #3519
2024-12-14 23:13:30 +00:00
Leonardo de Moura
b721c0f540 test: add test for issue #4585 (#6384)
This issue has been fixed by #6123

closes #4585
2024-12-14 22:12:00 +00:00
Leonardo de Moura
f790b1999f fix: new code generator must generate code for opaque declarations that are not @[extern] (#6383)
This PR ensures the new code generator produces code for `opaque`
definitions that are not tagged as `@[extern]`.
Remark: This is the behavior of the old code generator.
2024-12-14 20:26:14 +00:00
Leonardo de Moura
6571bc01d7 fix: withTrackingZetaDelta must reset cache (#6381)
This PR fixes a bug in `withTrackingZetaDelta` and
`withTrackingZetaDeltaSet`. The `MetaM` caches need to be reset. See new
test.
2024-12-14 18:23:32 +00:00
Kim Morrison
37122c3262 chore: move implementation details of mergeSort into namespace (#6380) 2024-12-14 11:24:15 +00:00
Mac Malone
280fcc9883 feat: lean --error=kind (#6362)
This PR adds the `--error=kind` option (shorthand: `-Ekind`) to the
`lean` CLI. When set, messages of `kind` (e.g.,
`linter.unusedVariables`) will be reported as errors. This setting does
nothing in interactive contexts (e.g., the server).

Closes #5194.

The spelling `--error` was chosen instead of the common `-Werror` both
for practical and behavioral reasons. Behaviorally, this option effects
not just warnings, but informational messages as well. Practically,
`-Werror` conflicts with the existing `-W` option for the worker and
`lean` also does not currently use long single-hyphen option names.
2024-12-14 01:31:14 +00:00
Leonardo de Moura
19eac5f341 fix: propagate Simp.Config when reducing terms and checking definitional equality in simp (#6123)
This PR ensures that the configuration in `Simp.Config` is used when
reducing terms and checking definitional equality in `simp`.

closes #5455

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2024-12-14 00:59:40 +00:00
Cameron Zwarich
aa00725624 chore: stop running compiler twice during tests (#6321)
The reason given for this in the comment seemingly no longer holds.

Co-authored-by: Cameron Zwarich <cameron@lean-fro.org>
2024-12-13 23:59:20 +00:00
Cameron Zwarich
7530fd6955 chore: remove Lean.Compiler.LCNF.ForEachExpr (#6313)
Co-authored-by: Cameron Zwarich <cameron@lean-fro.org>
2024-12-13 23:58:42 +00:00
Alissa Tung
58ffd15a8f doc: fix typo reference in doc of lazy discrimination tree (#6377)
This PR fix a bad reference in doc of lazy discrimination tree.
2024-12-13 07:41:04 +00:00
Kim Morrison
bac34c7767 feat: theorems about == on Vector (#6376)
This PR adds theorems about `==` on `Vector`, reproducing those already
on `List` and `Array`.
2024-12-13 02:07:12 +00:00
Kim Morrison
db354d2cde chore: run Batteries linter on Lean (#6364)
This PR makes fixes suggested by the Batteries environment linters,
particularly `simpNF`, and `unusedHavesSuffices`.
2024-12-13 01:28:53 +00:00
Leonardo de Moura
945abe0065 fix: unused let_fun elimination in simp (#6375)
This PR fixes a bug in the simplifier. It was producing terms with loose
bound variables when eliminating unused `let_fun` expressions.

This issue was affecting the example at #6374. The example is now timing
out.
2024-12-13 01:18:46 +00:00
Kim Morrison
48be424eaa feat: lemmas about Vector.any/all/set (#6369)
This PR adds lemmas about `Vector.set`, `anyM`, `any`, `allM`, and
`all`.

With these additions, `Vector` is now as in-sync with the `List` API as
`Array` is, and in future I'll be updating both simultaneously.
2024-12-12 04:48:34 +00:00
Kyle Miller
58f8e21502 feat: labeled and unique sorries (#5757)
This PR makes it harder to create "fake" theorems about definitions that
are stubbed-out with `sorry` by ensuring that each `sorry` is not
definitionally equal to any other. For example, this now fails:
```lean
example : (sorry : Nat) = sorry := rfl -- fails
```
However, this still succeeds, since the `sorry` is a single
indeterminate `Nat`:
```lean
def f (n : Nat) : Nat := sorry
example : f 0 = f 1 := rfl -- succeeds
```
One can be more careful by putting parameters to the right of the colon:
```lean
def f : (n : Nat) → Nat := sorry
example : f 0 = f 1 := rfl -- fails
```
Most sources of synthetic sorries (recall: a sorry that originates from
the elaborator) are now unique, except for elaboration errors, since
making these unique tends to cause a confusing cascade of errors. In
general, however, such sorries are labeled. This enables "go to
definition" on `sorry` in the Infoview, which brings you to its origin.
The option `set_option pp.sorrySource true` causes the pretty printer to
show source position information on sorries.

**Details:**

* Adds `Lean.Meta.mkLabeledSorry`, which creates a sorry that is labeled
with its source position. For example, `(sorry : Nat)` might elaborate
to
  ```
sorryAx (Lean.Name → Nat) false
`lean.foo.12.8.12.13.8.13._sorry._@.lean.foo._hyg.153
  ```
It can either be made unique (like the above) or merely labeled. Labeled
sorries use an encoding that does not impact defeq:
  ```
sorryAx (Unit → Nat) false (Function.const Lean.Name ()
`lean.foo.14.7.13.7.13.69._sorry._@.lean.foo._hyg.174)
  ```

* Makes the `sorry` term, the `sorry` tactic, and every elaboration
failure create labeled sorries. Most are unique sorries, but some
elaboration errors are labeled sorries.

* Renames `OmissionInfo` to `DelabTermInfo` and adds configuration
options to control LSP interactions. One field is a source position to
use for "go to definition". This is used to implement "go to definition"
on labeled sorries.

* Makes hovering over a labeled `sorry` show something friendlier than
that full `sorryAx` expression. Instead, the first hover shows the
simplified ``sorry `«lean.foo:48:11»``. Hovering over that hover shows
the full `sorryAx`. Setting `set_option pp.sorrySource true` makes
`sorry` always start with printing with this source position
information.

* Removes `Lean.Meta.mkSyntheticSorry` in favor of `Lean.Meta.mkSorry`
and `Lean.Meta.mkLabeledSorry`.

* Changes `sorryAx` so that the `synthetic` argument is no longer
optional.

* Gives `addPPExplicitToExposeDiff` awareness of labeled sorries. It can
set `pp.sorrySource` when source positions differ.

* Modifies the delaborator framework so that delaborators can set Info
themselves without it being overwritten.

Incidentally closes #4972.

Inspired by [this Zulip
thread](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Is.20a.20.60definition_wanted.60.20keyword.20possible.3F/near/477260277).
2024-12-11 23:53:02 +00:00
Mac Malone
a64a17e914 feat: Nat.shiftRight_bitwise_distrib (#6334)
This PR adds `Nat` theorems for distributing `>>>` over bitwise
operations, paralleling those of `BitVec`.

This enables closing goals like the following using `simp`:

```lean
example (n : Nat) : (n <<< 2 ||| 3) >>> 2 = n := by simp [Nat.shiftRight_or_distrib]
```

It might be nice for these theorems to be `simp` lemmas, but they are
not currently in order to be consistent with the existing `BitVec` and
`div_two` theorems.
2024-12-11 23:30:54 +00:00
Sebastian Ullrich
b862e2d251 chore: preserve reported messages in MessageLog (#6307)
Fixes #4460 (and similar future changes) making prior messages
inaccessible to metaprograms such as linters
2024-12-11 12:24:00 +00:00
Kim Morrison
8709ca35e9 chore: DecidableRel allows a heterogeneous relation (#6341)
This PR generalizes `DecidableRel` to allow a heterogeneous relation.
2024-12-11 05:02:58 +00:00
Mac Malone
19fb1fb388 feat: do not propagate pretty printer errors through messages (#3696)
This PR makes all message constructors handle pretty printer errors.

Prior to this change, pretty printer errors in messages were not
uniformly handled. In core, some printers capture their errors (e.g.,
`ppExprWithInfos` and `ppTerm` ) and some do not (e.g., `ppGoal` and
`ppSignature`) propagate them to whatever serializes the message (e.g.,
the frontend).

To resolve this inconsistency and uniformly handle errors, the signature
for `ofLazy` now uses `BaseIO`. As such, all printers been adapted to
capture any errors within them and print similar messages to
`ppExprWithInfos` and `ppTerm` on such errors.
2024-12-11 04:10:09 +00:00
Kim Morrison
cb31ddc6ad feat: lemmas about indexing and membership for Vector (#6367)
This PR brings Vector lemmas about membership and indexing to parity
with List and Array.
2024-12-11 03:52:04 +00:00
Leonardo de Moura
633c825ff3 feat: add Float32 support (#6366)
This PR adds support for `Float32` and fixes a bug in the runtime.
2024-12-11 02:55:58 +00:00
Kim Morrison
c83ce020bf feat: alignment of Array.set lemmas with List lemmas (#6365)
This PR expands the `Array.set` and `Array.setIfInBounds` lemmas to
match existing lemmas for `List.set`.
2024-12-11 01:45:06 +00:00
Kyle Miller
cd909b0a98 fix: when pretty printing constant names, do not use aliases from "non-API exports" (#5689)
This PR adjusts the way the pretty printer unresolves names. It used to
make use of all `export`s when pretty printing, but now it only uses
`export`s that put names into parent namespaces (heuristic: these are
"API exports" that are intended by the library author), rather than
"horizontal exports" that put the names into an unrelated namespace,
which the dot notation feature in #6189 now incentivizes.

Closes the already closed #2524
2024-12-10 17:50:50 +00:00
Joachim Breitner
d27c5afa6e refactor: ArgsPacker.unpack to return Option (#6359)
so that it can be used in pure code and that the error message can be
adjusted
2024-12-10 15:23:13 +00:00
Joachim Breitner
938651121f refactor: elabWFRel to take names, not PreDefinition (#6358)
just to clarify what this function can or cannot do
2024-12-10 14:46:48 +00:00
Joachim Breitner
a9b6a9a975 refactor: WF.EqnInfo.hasInduct (#6357)
after #6355 not all functions with equation infos will support
functional induction, so prepare a flag to guide the name reservation.
2024-12-10 14:33:10 +00:00
Joachim Breitner
d5b565e95f refactor: make mkInhabitantFor error message configurable (#6356)
preparation for #6355
2024-12-10 14:32:19 +00:00
Kim Morrison
27c2323ef9 chore: alignment of Array.any/all lemmas with List (#6353)
This PR reproduces the API around `List.any/all` for `Array.any/all`.
2024-12-10 09:23:52 +00:00
Tobias Grosser
17865394d4 feat: BitVec.[toInt|toFin|getMsbD]_ofBool (#6317)
This PR completes the basic API for BitVec.ofBool.

---------

Co-authored-by: Kim Morrison <scott@tqft.net>
2024-12-10 08:46:24 +00:00
Sebastian Ullrich
a805946466 chore: adjust CODEOWNERS (#6327)
Remove some noise from my assignments
2024-12-10 08:37:20 +00:00
Lean stage0 autoupdater
8a3a806b1a chore: update stage0 2024-12-10 03:47:20 +00:00
Leonardo de Moura
5c333ef969 fix: Float32 runtime support (#6350)
This PR adds missing features and fixes bugs in the `Float32` support
2024-12-10 01:37:01 +00:00
Kim Morrison
e69bcb0757 chore: improve BitVec ext lemmas (#6349)
This PR modifies `BitVec` extensionality lemmas to prefer bounded Nats
over `Fin`, and avoids unnecessary use of `bif` in BitVec theorems.
2024-12-10 01:33:09 +00:00
Tobias Grosser
c5b82e0b16 feat: BitVec.[toFin|getMsbD]_setWidth and [getMsbD|msb]_signExtend (#6338)
This PR adds `BitVec.[toFin|getMsbD]_setWidth` and
`[getMsb|msb]_signExtend` as well as `ofInt_toInt`.

Also correct renamed the misnamed theorem for
`signExtend_eq_setWidth_of_msb_false`.

---------

Co-authored-by: Siddharth <siddu.druid@gmail.com>
2024-12-10 01:17:20 +00:00
Lean stage0 autoupdater
b6177bad9c chore: update stage0 2024-12-09 22:30:45 +00:00
Leonardo de Moura
2e11b8ac88 feat: add support for Float32 to the Lean runtime (#6348)
This PR adds support for `Float32` to the Lean runtime.

We need an update stage0, and then uncomment `Float32.lean` file.
2024-12-09 21:33:43 +00:00
Alex Keizer
ff3d12c8b5 doc: clarify difference between Expr.hasLooseBVars and Expr.hasLooseBVar (#6344)
This PR adds docstrings to `Expr.hasLooseBVars` and `Expr.hasLooseBVar`,
to clarify the difference between these functions, and to document that
the former traverses the expression, while the latter is constant-time,
using cached information.

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2024-12-09 21:15:16 +00:00
Kim Morrison
520d4b698f chore: cleanup of Array lemmas (#6343)
Continuing cleanup of Array lemmas.
2024-12-09 14:04:16 +00:00
Kim Morrison
c7b8c5c6a6 chore: alignment of Array and List lemmas (#6342)
Further alignment of `Array` and `List` lemmas. Moved lemmas about
`List.toArray` to a separate file, and aligned lemmas about membership.
2024-12-09 11:30:45 +00:00
Kyle Miller
3f791933f1 chore: release notes for 4.14.0 (#6339) 2024-12-09 05:30:50 +00:00
Kyle Miller
63791f0177 feat: _ separators in numeric literals (#6204)
This PR lets `_` be used in numeric literals as a separator. For
example, `1_000_000`, `0xff_ff` or `0b_10_11_01_00`. New lexical syntax:
```text
numeral10 : [0-9]+ ("_"+ [0-9]+)*
numeral2  : "0" [bB] ("_"* [0-1]+)+
numeral8  : "0" [oO] ("_"* [0-7]+)+
numeral16 : "0" [xX] ("_"* hex_char+)+
float     : numeral10 "." numeral10? [eE[+-]numeral10]
```

Closes #6199
2024-12-08 22:23:12 +00:00
Kim Morrison
6abb8aad43 chore: cleanup of Array lemmas (#6337)
This PRs continues cleaning up Array lemmas and improving alignment with
List.
2024-12-08 22:03:23 +00:00
Kim Morrison
4dd182c554 chore: remove deprecated aliases for Int.tdiv and Int.tmod (#6322)
This PR removes the deprecated aliases `Int.div := Int.tdiv` and
`Int.mod := Int.tmod`. Later we will rename `Int.ediv` to `Int.div` and
`Int.emod` to `Int.mod`.
2024-12-08 05:19:42 +00:00
jsr-p
762c5758f5 doc: missing (type := true) in reader monad example (#6196)
This PR adds missing `(types := true)` to `#reduce` example in [Readers
example](https://lean-lang.org/lean4/doc/monads/readers.lean.html).
Since [4.10](https://lean-lang.org/blog/2024-8-1-lean-4100/) the `(types
:= true)` is necessary for the `ReaderM Environment String` type to be
reduced into `Environment → String`.
2024-12-07 15:59:36 +00:00
Joachim Breitner
6447fda253 feat: FunInd: omit unused parameters (#6330)
This PR removes unnecessary parameters from the funcion induction
principles. This is a breaking change; broken code can typically be adjusted
simply by passing fewer parameters.

Part 2, adjusting after stage0 update.

Closes #6320
2024-12-07 04:19:21 +01:00
Joachim Breitner
279f36b4cc chore: update stage0 2024-12-07 04:19:21 +01:00
Joachim Breitner
d2853ecbc4 feat: FunInd: omit unused parameters (#6330)
This PR removes unnecessary parameters from the funcion induction
principles. This is a breaking change; broken code can typically be adjusted
simply by passing fewer parameters.

Part 1, before stage0 update.

Closes #6320
2024-12-07 04:19:21 +01:00
Kim Morrison
6e60d13084 feat: getElem lemmas for Vector operations (#6324)
This PR adds `GetElem` lemmas for the basic `Vector` operations.

The `Vector` API is still very sparse, but I'm hoping to infill rapidly.
2024-12-06 01:45:19 +00:00
Kim Morrison
019f8e175f chore: protect Fin.cast and BitVec.cast (#6315)
This PR adds `protected` to `Fin.cast` and `BitVec.cast`, to avoid
confusion with `_root_.cast`. These should mostly be used via
dot-notation in any case.
2024-12-05 06:11:45 +00:00
Kim Morrison
c366a291ca chore: generalize universe in Array.find? (#6318)
This PR generalizes the universe level for `Array.find?`, by giving it a
separate implementation from `Array.findM?`.
2024-12-05 06:11:40 +00:00
Alex Keizer
1400b95ffb feat: upstream ToLevel from mathlib (#6285)
This PR upstreams the `ToLevel` typeclass from mathlib and uses it to
fix the existing `ToExpr` instances so that they are truly universe
polymorphic (previously it generated malformed expressions when the
universe level was nonzero). We improve on the mathlib definition of
`ToLevel` to ensure the class always lives in `Type`, irrespective of
the universe parameter.

This implements part one of the plan to upstream a derive handler for
`ToExpr`, as discussed in #5906 and #5909.

---------

Co-authored-by: Kyle Miller <kmill31415@gmail.com>
Co-authored-by: Tobias Grosser <tobias@grosser.es>
2024-12-05 05:50:32 +00:00
Kim Morrison
00c7b85261 feat: lemmas about for loops over Option (#6316)
This PR adds lemmas simplifying `for` loops over `Option` into
`Option.pelim`, giving parity with lemmas simplifying `for` loops of
`List` into `List.fold`.
2024-12-05 05:09:07 +00:00
Leonardo de Moura
f6e88e5a05 fix: missing HEq support at ToLCNF (#6311)
This PR adds support for `HEq` to the new code generator.
2024-12-04 19:49:16 +00:00
Sebastian Ullrich
88573c802d test: do not filter output for non-diff tests (#6308) 2024-12-04 17:49:35 +00:00
Henrik Böving
faf07e58db chore: remove unused imports (#6305)
This PR removes an unused import in the time library that can yield to
import cycles when building stuff that gets imported by `Std.Internal`
but also wants to import `Std.Time`.
2024-12-04 12:46:08 +00:00
Tobias Grosser
c5181569f9 feat: BitVec.[toInt|toFin]_concat and Bool.toInt (#6182)
This PR adds `BitVec.[toInt|toFin]_concat` and moves a couple of
theorems into the concat section, as `BitVec.msb_concat` is needed for
the `toInt_concat` proof.

We also add `Bool.toInt`.
2024-12-04 01:53:30 +00:00
Siddharth
77211029da feat: BitVec.toFin/ToInt BitVec.ushiftRight (#6238)
This PR adds theorems characterizing the value of the unsigned shift
right of a bitvector in terms of its 2s complement interpretation as an
integer.
Unsigned shift right by at least one bit makes the value of the
bitvector less than or equal to `2^(w-1)`,
makes the interpretation of the bitvector `Int` and `Nat` agree.
In the case when `n = 0`, then the shift right value equals the integer
interpretation.

```lean
theorem toInt_ushiftRight_eq_ite {x : BitVec w} {n : Nat} :
  (x >>> n).toInt = if n = 0 then x.toInt else x.toNat >>> n
```

```lean
theorem toFin_uShiftRight {x : BitVec w} {n : Nat} :
  (x >>> n).toFin = x.toFin / (Fin.ofNat' (2^w) (2^n))
```

---------

Co-authored-by: Harun Khan <harun19@stanford.edu>
Co-authored-by: Tobias Grosser <github@grosser.es>
2024-12-04 01:49:58 +00:00
Lean stage0 autoupdater
da9a0c4190 chore: update stage0 2024-12-04 00:04:00 +00:00
Leonardo de Moura
b9bf94313a feat: add debug.proofAsSorry (#6300)
This PR adds the `debug.proofAsSorry` option. When enabled, the proofs
of theorems are ignored and replaced with `sorry`.
2024-12-03 23:21:38 +00:00
Sebastian Ullrich
2a891a3889 chore: CMAKE_CXX_SYSROOT_FLAG is also needed for linking (#6297)
Fixes #6296
2024-12-03 16:14:22 +00:00
Sebastian Ullrich
00718c3959 chore: clean up Elab.async handling (#6299)
* Make sure metaprogramming users cannot be surprised by its
introduction
* Make `#guard_msgs` compatible with its use
2024-12-03 12:42:02 +00:00
Sebastian Ullrich
473274f145 chore: update stage0 2024-12-03 13:59:37 +01:00
Kim Morrison
7b98fbece4 feat: reverse HashMap.toList, so it agrees with HashMap.toArray (#6244)
This PR changes the implementation of `HashMap.toList`, so the ordering
agrees with `HashMap.toArray`.

Currently there are no verification lemmas about `HashMap.toList`, so no
contract is being broken yet!
2024-12-03 12:25:35 +00:00
Henrik Böving
24b412ebe3 refactor: move IO.Channel and IO.Mutex to Std.Sync (#6282)
This PR moves `IO.Channel` and `IO.Mutex` from `Init` to `Std.Sync` and
renames them to `Std.Channel` and `Std.Mutex`.

Note that the original files are retained and the deprecation is written
manually as we cannot import `Std` from `Init` so this is the only way
to deprecate without a hard breaking change. In particular we do not yet
move `Std.Queue` from `Init` to `Std` both because it needs to be
retained for this deprecation to work but also because it is already
within the `Std` namespace and as such we cannot maintain two copies of
the file at once. After the deprecation period is finished `Std.Queue`
will find a new home in `Std.Data.Queue`.
2024-12-03 09:36:50 +00:00
Kim Morrison
cb600ed9b4 chore: restore broken proofs
This reverts commit d099f560f72b5f18695c7fb586a9da93af0cb17e.
2024-12-03 17:59:23 +11:00
Kim Morrison
57d83c835e feat: add simp configuration to norm_cast macros 2024-12-03 17:59:23 +11:00
Kim Morrison
ce27d49e31 chore: update stage0 2024-12-03 17:59:23 +11:00
Kim Morrison
8a7889d602 chore: temporarily sorry broken proofs 2024-12-03 17:59:23 +11:00
Kim Morrison
69340297be chore: add simp configuration to norm_cast syntax
chore: define NormCastConfig earlier
2024-12-03 17:59:23 +11:00
Kim Morrison
222abdd43d feat: simprocs for other Fin operations (#6295)
This PR sets up simprocs for all the remaining operations defined in
`Init.Data.Fin.Basic`
2024-12-03 04:42:17 +00:00
François G. Dorais
490be9282e chore: specialize fold loops (#6293)
This PR adds `specialize` and `semireducible` attributes to loops for
`Fin.fold[lr]M?`
2024-12-03 02:44:19 +00:00
Kim Morrison
cda6d5c67a chore: upstream List.length_flatMap (#6294)
This PR upstreams `List.length_flatMap`, `countP_flatMap` and
`count_flatMap` from Mathlib. These were not possible to state before we
upstreamed `List.sum`.
2024-12-03 01:59:32 +00:00
Kim Morrison
904404303b chore: robustify for byAsSorry (#6287)
This PR makes some proofs more robust so they will still work with
`byAsSorry`. Unfortunately, they are not a complete fix and there are
remaining problems building with `byAsSorry`.
2024-12-02 23:53:16 +00:00
Mac Malone
f6bc6b2eb1 fix: lake: properly prepend job log in ensureJob (#6291)
This PR ensures the the log error position is properly preserved when
prepending stray log entries to the job log. It also adds comparison
support for `Log.Pos`.
2024-12-02 23:43:12 +00:00
Mac Malone
d9d54c1f99 chore: lake: use & check prelude (#6289)
This PR adapts Lake modules to use `prelude` and includes them in the
`check-prelude` CI.
2024-12-02 19:55:05 +00:00
Henrik Böving
b2336fd980 perf: speed up bv_decide reflection using Lean.RArray (#6288)
This PR uses Lean.RArray in bv_decide's reflection proofs. Giving
speedups on problems with lots of variables.

Implement like #6068, speedup:
```
# before
λ hyperfine "lean +nightly-2024-12-02 tests/lean/run/bv_reflection_stress.lean"
Benchmark 1: lean +nightly-2024-12-02 tests/lean/run/bv_reflection_stress.lean
  Time (mean ± σ):      1.939 s ±  0.007 s    [User: 1.549 s, System: 0.104 s]
  Range (min … max):    1.928 s …  1.947 s    10 runs
# after
λ hyperfine "lean tests/lean/run/bv_reflection_stress.lean"                                                                                                                                                                                                                        
Benchmark 1: lean tests/lean/run/bv_reflection_stress.lean
  Time (mean ± σ):      1.409 s ±  0.006 s    [User: 1.058 s, System: 0.073 s]
  Range (min … max):    1.401 s …  1.419 s    10 runs
```
2024-12-02 17:44:58 +00:00
Mac Malone
f156f22d7c feat: lake: build without leanc (#6176)
This PR changes Lake's build process to no longer use `leanc` for
compiling C files or linking shared libraries and executables. Instead,
it directly invokes the bundled compiler (or the native compiler if
none) using the necessary flags.
2024-12-02 17:11:27 +00:00
dependabot[bot]
3c348d4526 chore: CI: bump dawidd6/action-download-artifact from 6 to 7 (#6274)
Bumps
[dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
from 6 to 7.
<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>v7</h2>
<h2>What's Changed</h2>
<ul>
<li>build(deps): bump fast-xml-parser from 4.4.0 to 4.4.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/299">dawidd6/action-download-artifact#299</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.7 to
2.1.9 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/300">dawidd6/action-download-artifact#300</a></li>
<li>build(deps): bump adm-zip from 0.5.14 to 0.5.15 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/301">dawidd6/action-download-artifact#301</a></li>
<li>build(deps): bump adm-zip from 0.5.15 to 0.5.16 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/306">dawidd6/action-download-artifact#306</a></li>
<li>build(deps): bump path-to-regexp from 6.2.2 to 6.3.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/307">dawidd6/action-download-artifact#307</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.9 to
2.1.10 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/311">dawidd6/action-download-artifact#311</a></li>
<li>build(deps): bump <code>@​actions/core</code> from 1.10.1 to 1.11.0
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/310">dawidd6/action-download-artifact#310</a></li>
<li>build(deps): bump <code>@​actions/core</code> from 1.11.0 to 1.11.1
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/312">dawidd6/action-download-artifact#312</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.10 to
2.1.11 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/313">dawidd6/action-download-artifact#313</a></li>
<li>build(deps): Fix cross-spawn &gt;=7.0.0 &lt;= 7.0.5 vulnerability by
<a href="https://github.com/alexcouret"><code>@​alexcouret</code></a> in
<a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/317">dawidd6/action-download-artifact#317</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/alexcouret"><code>@​alexcouret</code></a> made
their first contribution in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/317">dawidd6/action-download-artifact#317</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v6...v7">https://github.com/dawidd6/action-download-artifact/compare/v6...v7</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="80620a5d27"><code>80620a5</code></a>
node_modules: update</li>
<li><a
href="b15e003f46"><code>b15e003</code></a>
node_modules: install</li>
<li><a
href="1ee9a455fd"><code>1ee9a45</code></a>
build(deps): Fix cross-spawn &gt;=7.0.0 &lt;= 7.0.5 vulnerability (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/317">#317</a>)</li>
<li><a
href="b2f2706ac4"><code>b2f2706</code></a>
build(deps): bump <code>@​actions/artifact</code> from 2.1.10 to 2.1.11
(<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/313">#313</a>)</li>
<li><a
href="fdbeba027c"><code>fdbeba0</code></a>
build(deps): bump <code>@​actions/core</code> from 1.11.0 to 1.11.1 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/312">#312</a>)</li>
<li><a
href="a74b42987a"><code>a74b429</code></a>
build(deps): bump <code>@​actions/core</code> from 1.10.1 to 1.11.0 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/310">#310</a>)</li>
<li><a
href="24e807a70c"><code>24e807a</code></a>
build(deps): bump <code>@​actions/artifact</code> from 2.1.9 to 2.1.10
(<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/311">#311</a>)</li>
<li><a
href="9592e3c4ab"><code>9592e3c</code></a>
build(deps): bump path-to-regexp from 6.2.2 to 6.3.0 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/307">#307</a>)</li>
<li><a
href="5f966b63eb"><code>5f966b6</code></a>
build(deps): bump adm-zip from 0.5.15 to 0.5.16 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/306">#306</a>)</li>
<li><a
href="db9477a3eb"><code>db9477a</code></a>
build(deps): bump adm-zip from 0.5.14 to 0.5.15 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/301">#301</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/dawidd6/action-download-artifact/compare/v6...v7">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=6&new-version=7)](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>
2024-12-02 16:09:50 +00:00
Sebastian Ullrich
0b8f50f78d feat: async linting (#4460)
This PR runs all linters for a single command (together) on a separate
thread from further elaboration, making a first step towards
parallelizing the elaborator.
2024-12-02 14:37:03 +00:00
Henrik Böving
0d89f0194b perf: bv_decide uses rfl in reflection if possible (#6286)
This PR ensure `bv_decide` uses definitional equality in its reflection
procedure as much as possible. Previously it would build up explicit
congruence proofs for the kernel to check. This reduces the size of
proof terms passed to kernel speeds up checking of large reflection
proofs.
2024-12-02 14:27:49 +00:00
Kim Morrison
e157fcbcd1 chore: missing Array/Vector injectivity lemmas (#6284) 2024-12-02 11:00:03 +00:00
Henrik Böving
95dbac26cf chore: shake Std.Time (#6283)
This PR reduces the import closure of `Std.Time` such that it doesn't
have to be rebuilt on every change in `Init.Data`.

Noticed while working on `Init` refactorings.
2024-12-02 10:52:43 +00:00
dependabot[bot]
be63c8280e chore: CI: bump dcarbone/install-jq-action from 2.1.0 to 3.0.1 (#6275)
Bumps
[dcarbone/install-jq-action](https://github.com/dcarbone/install-jq-action)
from 2.1.0 to 3.0.1.
<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.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Use sh in action by <a
href="https://github.com/dcarbone"><code>@​dcarbone</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/15">dcarbone/install-jq-action#15</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dcarbone/install-jq-action/compare/v3.0.0...v3.0.1">https://github.com/dcarbone/install-jq-action/compare/v3.0.0...v3.0.1</a></p>
<h2>v3.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>updating matrix versions by <a
href="https://github.com/dcarbone"><code>@​dcarbone</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/12">dcarbone/install-jq-action#12</a></li>
<li>trying out posix sh by <a
href="https://github.com/dcarbone"><code>@​dcarbone</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/14">dcarbone/install-jq-action#14</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dcarbone/install-jq-action/compare/v2...v3.0.0">https://github.com/dcarbone/install-jq-action/compare/v2...v3.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e397bd8743"><code>e397bd8</code></a>
Use sh in action (<a
href="https://redirect.github.com/dcarbone/install-jq-action/issues/15">#15</a>)</li>
<li><a
href="36b228ee68"><code>36b228e</code></a>
Add dependabot for github-actions</li>
<li><a
href="d5935278d5"><code>d593527</code></a>
updating examples</li>
<li><a
href="ca8101273e"><code>ca81012</code></a>
trying out posix sh (<a
href="https://redirect.github.com/dcarbone/install-jq-action/issues/14">#14</a>)</li>
<li><a
href="de7c0d1fb1"><code>de7c0d1</code></a>
updating matrix versions (<a
href="https://redirect.github.com/dcarbone/install-jq-action/issues/12">#12</a>)</li>
<li>See full diff in <a
href="https://github.com/dcarbone/install-jq-action/compare/v2.1.0...v3.0.1">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=2.1.0&new-version=3.0.1)](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>
2024-12-02 10:33:27 +00:00
Sebastian Ullrich
6fcf35e930 chore: script/mathlib-bench (#6280)
A simple approach to benchmarking lean4 PRs against Mathlib
2024-12-02 10:00:57 +00:00
Marc Huisinga
b3e0c9c3fa fix: use sensible notion of indentation in structure instance field completion (#6279)
This PR fixes a bug in structure instance field completion that caused
it to not function correctly for bracketed structure instances written
in Mathlib style.
2024-12-02 09:37:12 +00:00
Kim Morrison
3c5e612dc5 chore: begin development cycle for v4.16.0 (#6277) 2024-12-02 04:11:10 +00:00
Kim Morrison
29e84fa7ea feat: omega doesn't get stuck on bare Int.negSucc (#6276)
This PR ensures `omega` doesn't get stuck on bare `Int.negSucc` terms in
goals.

This came up in https://github.com/ImperialCollegeLondon/FLT/pull/260.
2024-12-01 23:57:15 +00:00
Mac Malone
6bf8ff32f0 feat: more UInt bitwise theorems (#6188)
This PR completes the `toNat` theorems for the bitwise operations
(`and`, `or`, `xor`, `shiftLeft`, `shiftRight`) of the UInt types and
adds `toBitVec` theorems as well. It also renames `and_toNat` to
`toNat_and` to fit with the current naming convention.
2024-12-01 22:38:49 +00:00
Henrik Böving
62b8238782 chore: remove accidentally added file (#6262)
This PR removes an accidentally comitted file.
2024-12-01 21:11:44 +00:00
Kyle Miller
0a2a8e8aa4 feat: make "foo has been deprecated" warning be hoverable (#6273)
This PR modifies the "foo has been deprecated: use betterFoo instead"
warning so that foo and betterFoo are hoverable.
2024-12-01 19:12:42 +00:00
Kyle Miller
23236ef520 fix: have Lean.Meta.isConstructorApp'? be aware of n + k Nat offsets (#6270)
This PR fixes a bug that could cause the `injectivity` tactic to fail in
reducible mode, which could cause unfolding lemma generation to fail
(used by tactics such as `unfold`). In particular,
`Lean.Meta.isConstructorApp'?` was not aware that `n + 1` is equivalent
to `Nat.succ n`.

Closes #5064
2024-12-01 18:04:32 +00:00
Kim Morrison
b2f70dad52 feat: Array.swap_perm (#6272)
This PR introduces the basic theory of permutations of `Array`s and
proves `Array.swap_perm`.

The API falls well short of what is available for `List` at this point.
2024-12-01 08:35:28 +00:00
Kim Morrison
819cb879e1 chore: upstream Vector lemmas (#6271)
This PR upstreams existing lemmas about `Vector` from Batteries.

Thanks to @fgdorais for preparing these in
https://github.com/leanprover-community/batteries/pull/1062. Further
contributions to the `Vector` API welcome via PR here.
2024-12-01 06:44:14 +00:00
Kim Morrison
3ee2842e77 feat: remove runtime bounds checks and partial from qsort (#6241)
This PR refactors `Array.qsort` to remove runtime array bounds checks,
and avoids the use of `partial`. We use the `Vector` API, along with
auto_params, to avoid having to write any proofs. The new code
benchmarks indistinguishably from the old.
2024-12-01 06:26:00 +00:00
Kyle Miller
7b8504cf06 chore: post-stage0 cleanup for #6165 (#6268)
This PR puts code in terms of syntax quotations now that there has been
a stage0 update. Fixes a lingering bug in StructInst where some
intermediate syntax was malformed, but this had no observable effects
outside of some debug messages.
2024-12-01 00:20:59 +00:00
Lean stage0 autoupdater
ca96922b4b chore: update stage0 2024-11-30 21:22:30 +00:00
Kyle Miller
a1c3a36433 feat: parity between structure instance notation and where notation (#6165)
This PR modifies structure instance notation and `where` notation to use
the same notation for fields. Structure instance notation now admits
binders, type ascriptions, and equations, and `where` notation admits
full structure lvals. Examples of these for structure instance notation:
```lean
structure PosFun where
  f : Nat → Nat
  pos : ∀ n, 0 < f n

def p : PosFun :=
  { f n := n + 1
    pos := by simp }

def p' : PosFun :=
  { f | 0 => 1
      | n + 1 => n + 1
    pos := by rintro (_|_) <;> simp }
```
Just like for the structure `where` notation, a field `f x y z : ty :=
val` expands to `f := fun x y z => (val : ty)`. The type ascription is
optional.

The PR also is setting things up for future expansion. Pending some
discussion, in the future structure/`where` notation could have have
embedded `where` clauses; rather than `{ a := { x := 1, y := z } }` one
could write `{ a where x := 1; y := z }`.
2024-11-30 20:27:25 +00:00
Lean stage0 autoupdater
734ea3071d chore: update stage0 2024-11-30 12:58:59 +00:00
Kyle Miller
f3f00451c8 feat: add structInstFieldDecl syntax category (#6265)
This PR is preparation for changes to structure instance notation in
#6165. It adds a syntax category that will be used for field syntax.
2024-11-30 12:12:53 +00:00
Leonardo de Moura
27df5e968a feat: Simp.Config.implicitDefEqProofs (#4595)
This PR implements `Simp.Config.implicitDefEqsProofs`. When `true`
(default: `true`), `simp` will **not** create a proof term for a
rewriting rule associated with an `rfl`-theorem. Rewriting rules are
provided by users by annotating theorems with the attribute `@[simp]`.
If the proof of the theorem is just `rfl` (reflexivity), and
`implicitDefEqProofs := true`, `simp` will **not** create a proof term
which is an application of the annotated theorem.

The default setting does change the existing behavior. Users can use
`simp -implicitDefEqProofs` to force `simp` to create a proof term for
`rfl`-theorems. This can positively impact proof checking time in the
kernel.

This PR also fixes an issue in the `split` tactic that has been exposed
by this feature. It was looking for `split` candidates in proofs and
implicit arguments. See new test for issue exposed by the previous
feature.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2024-11-29 22:29:27 +00:00
Lean stage0 autoupdater
3752241edd chore: update stage0 2024-11-29 21:32:14 +00:00
Marc Huisinga
39bffb6fda fix: don't walk full project file tree on every file save (#6246)
This PR fixes a performance issue where the Lean language server would
walk the full project file tree every time a file was saved, blocking
the processing of all other requests and notifications and significantly
increasing overall language server latency after saving.

This issue was originally reported at
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Compiling.20too.20slow/near/484386515
and uncovered in a lengthy investigation. The performance bug that
causes the Lean language server to walk the full project file tree when
the file watcher for .ilean files is triggered was introduced when the
.ileans were first introduced, whereas the specific issue of file saving
also triggering the walk was introduced by #3247 in 4.8.0 and the use of
the file watcher for .lean files, which would then also trigger the
directory walk. Combining this with VS Code's auto-save feature causes
the language server to walk the full project file tree on every change
of the document.

It somehow hasn't really been much of an issue until now, but we still
do way too much work in the watchdog main loop. I'll look into resolving
that more general issue in the future.
2024-11-29 15:34:44 +00:00
Sebastian Ullrich
86f303774a chore: harden markPersistent uses (#6257)
This API may or may not have been a footgun, better to be safe than
`sorry`
2024-11-29 14:33:33 +00:00
Sebastian Ullrich
d97af36867 feat: simpler trace timing annotation logic (#6259)
This PR ensures that nesting trace nodes are annotated with timing
information iff `trace.profiler` is active.

The previous connection to the otherwise unrelated `profiler` option was
a remnant from before `trace.profiler` existed; if users want to
annotate explicitly activated trace classes only, they can instead
increase `trace.profiler.threshold`.
2024-11-29 14:03:01 +00:00
Mac Malone
27cc0c8039 feat: USize.reduceToNat (#6190)
This PR adds the builtin simproc `USize.reduceToNat` which reduces the
`USize.toNat` operation on literals less than `UInt32.size` (i.e.,
`4294967296`).
2024-11-29 08:24:40 +00:00
Mac Malone
c9ee66fb1f chore: lake: fix typo in materialize error (#6250) 2024-11-29 06:20:51 +00:00
Kim Morrison
5c7e027b03 chore: cleanup of List/Array lemmas (#6249)
This PR performs further cleanup of `List/Lemmas.lean` and
`Array/Lemmas.lean`, trying to make them more parallel.

Still a long way to go.
2024-11-29 06:12:38 +00:00
Mac Malone
4969ec9cdb feat: more UInt lemmas (#6205)
This PR upstreams some UInt theorems from Batteries and adds more
`toNat`-related theorems. It also adds the missing `UInt8` and `UInt16`
to/from `USize` conversions so that the the interface is uniform across
the UInt types.

**Summary of all changes:**

* Upstreamed and added `toNat` constructors lemmas: `toNat_mk`,
`ofNat_toNat`, `toNat_ofNat`, `toNat_ofNatCore`, and
`USize.toNat_ofNat32`
* Upstreamed and added `toNat` canonicalization; `val_val_eq_toNat` and
`toNat_toBitVec_eq_toNat`
* Added injectivity iffs: `toBitVec_inj`, `toNat_inj`, and `val_inj`
* Added inequality iffs: `le_iff_toNat_le` and `lt_iff_toNat_lt`
* Upstreamed antisymmetry lemmas: `le_antisymm` and `le_antisymm_iff`
* Upstreamed missing `toNat` lemmas on arithmetic operations:
`toNat_add`, `toNat_sub`, `toNat_mul`
* Upstreamed and added missing conversion lemmas: `toNat_toUInt*` and
`toNat_USize`
* Added missing `USize` conversions: `USize.toUInt8`, `UInt8.toUSize`,
`USize.toUInt16`, `UInt16.toUSize`
2024-11-29 02:08:52 +00:00
Mac Malone
827062f807 feat: System.Platform.numBits inequalities (#6247)
This PR adds the theorems `numBits_pos`, `le_numBits`, `numBits_le` ,
which make proving inequalities about `System.Platform.numBits` easier.
2024-11-28 21:20:47 +00:00
Kim Morrison
6d495586a1 chore: deprecate Fin.ofNat (replaced by Fin.ofNat', subsequently to be renamed) (#6242)
This PR deprecates `Fin.ofNat` in favour of `Fin.ofNat'` (which takes an
`[NeZero]` instance, rather than returning an element of `Fin (n+1)`).

After leaving the deprecation warning in place for some time, we will
then rename `ofNat'` back to `ofNat`.
2024-11-28 05:23:23 +00:00
Kim Morrison
10d1d2cc25 chore: cleanup in Array/Lemmas (#6243) 2024-11-28 03:50:41 +00:00
Wojciech Nawrocki
2325f5c7b9 doc: explain abstraction order (#6239)
This PR explains the order in which `Expr.abstract` introduces de Bruijn
indices.
2024-11-28 01:37:30 +00:00
Sofia Rodrigues
88e3a2b1ab fix: improve directory fallback on Linux and trim local time identifier (#6221)
This PR fixes:
- Problems in other linux distributions that the default `tzdata`
directory is not the same as previously defined by ensuring it with a
fallback behavior when directory is missing.
- Trim unnecessary characters from local time identifier.
2024-11-27 14:52:35 +00:00
Lean stage0 autoupdater
b378fe98a7 chore: update stage0 2024-11-27 14:20:47 +00:00
Sebastian Ullrich
5f1ff42a15 fix: Runtime.markPersistent is unsafe (#6209)
This PR documents under which conditions `Runtime.markPersistent` is
unsafe and adjusts the elaborator accordingly
2024-11-27 13:32:05 +00:00
Jens Petersen
30d01f7a9a fix: add cmake COPY_CADICAL option to allow turning off install copy (#5931)
This PR adds a cmake knob to allow turning off installing a copy of
`cadical`.
This can be useful for custom builds/installs where cadical is already
available in the system.

Closes: #5603
2024-11-27 13:21:20 +00:00
Sebastian Ullrich
81b85d8e2f fix: reparsing may need to backtrack two commands (#6236)
This PR fixes an issue where edits to a command containing a nested
docstring fail to reparse the entire command.

Fixes #6227
2024-11-27 13:06:57 +00:00
Sebastian Ullrich
5982a6d230 chore: default parseQuotWithCurrentStage to true in stage 0 (#6212)
Use the default that solves bootstrapping issues in exchange for an
insignificant(?) perf overhead
2024-11-27 12:58:44 +00:00
Mac Malone
ac1197ff59 feat: Lean.loadPlugin (#6130)
This PR adds `Lean.loadPlugin` which exposes functionality similar to
the `lean` executable's `--plugin` option to Lean code.

This will allow custom Lean frontends (e.g., Lake, the Lean language
server) to also load plugins.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2024-11-27 09:56:31 +00:00
Kim Morrison
609346f5e0 feat: relate Nat.fold/foldRev/any/all to List.finRange (#6235)
This PR relates that operations `Nat.fold`/`foldRev`/`any`/`all` to the
corresponding List operations over `List.finRange`.
2024-11-27 05:38:18 +00:00
Mac Malone
04f80a1f9f feat: lake: detailed Reservoir fetch error (#6231)
This PR improves the errors Lake produces when it fails to fetch a
dependency from Reservoir. If the package is not indexed, it will
produce a suggestion about how to require it from GitHub.

Closes #5330.
2024-11-27 05:07:09 +00:00
Kim Morrison
7e9dd5668b feat: upstream List.finRange from Batteries (#6234)
This PR upstreams the definition and basic lemmas about `List.finRange`
from Batteries.

Thanks for contributors to Batteries and Mathlib who've previously
worked on this material. Further PRs are welcome here. I'll be adding
more API later.
2024-11-27 04:27:22 +00:00
Kim Morrison
79f050b816 feat: upstream Vector lemmas (#6233)
This PR upstreams lemmas about `Vector` from Batteries.

I'll be adding more soon, and PRs are welcome, particularly from those
who have previously contributed to `Vector` in Batteries.
2024-11-27 04:19:30 +00:00
Siddharth
af4a3f2251 feat: BitVec.toInt_abs (#6154)
This PR implements `BitVec.toInt_abs`.


The absolute value of `x : BitVec w` is naively a case split on the sign
of `x`.
However, recall that when `x = intMin w`, `-x = x`.
Thus, the full value of `abs x` is computed by the case split:
- If `x : BitVec w` is `intMin`, then its absolute value is also `intMin
w`, and
  thus `toInt` will equal `intMin.toInt`.
- Otherwise, if `x` is negative, then `x.abs.toInt = (-x).toInt`.
- Finally, when `x` is nonnegative, then `x.abs.toInt = x.toInt`.

```lean
theorem toInt_abs {x : BitVec w} :
  x.abs.toInt =
    if x = intMin w then (intMin w).toInt
    else if x.msb then -x.toInt
    else x.toInt
```

We also provide a variant of `toInt_abs` that
hides the case split for `x` being positive or negative by using
`natAbs`.
```lean
theorem toInt_abs_eq_natAbs {x : BitVec w} : x.abs.toInt =
    if x = intMin w then (intMin w).toInt else x.toInt.natAbs
```

Supercedes https://github.com/leanprover/lean4/pull/5787

---------

Co-authored-by: Tobias Grosser <github@grosser.es>
2024-11-27 03:50:55 +00:00
Siddharth
7692343720 feat: BitVec.toNat BitVec.signExtend (#6155)
This PR adds `toNat` theorems for `BitVec.signExtend.`

Sign extending to a larger bitwidth depends on the msb. If the msb is
false, then the result equals the original value. If the msb is true,
then we add a value of `(2^v - 2^w)`, which arises from the sign
extension.

```lean
theorem toNat_signExtend (x : BitVec w) {v : Nat} :
    (x.signExtend v).toNat = (x.setWidth v).toNat + if x.msb then 2^v - 2^w else 0
```

Co-authored-by: Harun Khan <harun19@stanford.edu>
2024-11-27 03:50:15 +00:00
Luisa Cicolini
597ef8cfee feat: add Nat.mod_eq_sub and fix dependencies from Nat.sub_mul_eq_mod_of_lt_of_le (#6160)
This PR adds theorem `mod_eq_sub`, makes theorem
`sub_mul_eq_mod_of_lt_of_le` not private anymore and moves its location
within the `rotate*` section to use it in other proofs.
2024-11-27 03:48:59 +00:00
Kim Morrison
321e148f51 feat: Array fold lemmas (#6230)
This PR copies some lemmas about `List.foldX` to `Array`.
2024-11-27 02:09:41 +00:00
Kyle Miller
ce692436f4 feat: expose diff at "synthesized type class instance is not definitionally equal" error (#6213)
This PR exposes the difference in "synthesized type class instance is
not definitionally equal" errors.
2024-11-27 00:52:58 +00:00
Mac Malone
23bec25fce feat: Nat.lt_pow_self (#6200)
This PR upstreams `Nat.lt_pow_self` and `Nat.lt_two_pow` from Mathlib
and uses them to prove the simp theorem `Nat.mod_two_pow`.

This simplifies expressions like `System.Platform.numBits % 2 ^
System.Platform.numBits = System.Platform.numBits`, which is needed for
#6188.
2024-11-26 23:42:23 +00:00
Mac Malone
3d511a582a feat: USize.size inequalities (#6203)
This PR adds the theorems `le_usize_size` and `usize_size_le`, which
make proving inequalities about `USize.size` easier.

It also deprecates `usize_size_gt_zero` in favor of `usize_size_pos` (as
that seems more consistent with our naming covention) and adds
`USize.toNat_ofNat_of_lt_32` for dealing with small USize literals.

It also moves `USize.ofNat32` and `USize.toUInt64` to
`Init.Data.UInt.Basic` as neither are used in `Init.Prelude` anymore.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2024-11-26 23:42:15 +00:00
Mac Malone
51015bf5c0 fix: lake: eager logging when materializing deps (#6225)
This PR makes `lake build` also eagerly print package materialization
log lines. Previously, only a `lake update` performed eager logging.
2024-11-26 22:11:23 +00:00
Mac Malone
3ece36de9d feat: GitHub cloud releases do not clobber prebuilt artifacts (#6218)
This PR makes Lake no longer automatically fetch GitHub cloud releases
if the package build directory is already present (mirroring the
behavior of the Reservoir cache). This prevents the cache from
clobbering existing prebuilt artifacts. Users can still manually fetch
the cache and clobber the build directory by running `lake build
<pkg>:release`.
2024-11-26 22:10:42 +00:00
Leonardo de Moura
54c48363ca feat: proper let_fun support in simp (#6220)
This PR adds proper support for `let_fun` in `simp`.
2024-11-26 21:42:08 +00:00
Markus Himmel
0a22f8fa6f chore: improve consistency & documentation for hash table insert and insertMany (#6222)
This PR changes the definition of `HashSet.insertMany` and
`HashSet.Raw.insertMany` so that it is equivalent to repeatedly calling
`HashSet.insert`/`HashSet.Raw.insert`. It also clarifies the docstrings
of all the `insert` and `insertMany` functions.

---------

Co-authored-by: Kim Morrison <scott.morrison@gmail.com>
2024-11-26 11:22:23 +00:00
Kim Morrison
f70b7e5722 feat: @[deprecated] requires a replacement identifier or message, and a since field (#6112)
This PR makes stricter requirements for the `@[deprecated]` attribute,
requiring either a replacement identifier as `@[deprecated bar]` or
suggestion text `@[deprecated "Past its use by date"]`, and also
requires a `since := "..."` field.
2024-11-26 08:45:54 +00:00
Kim Morrison
9a17919ef1 feat: missing lemmas about List's BEq (#6217)
This PR adds `simp` lemmas about `List`'s `==` operation.
2024-11-25 22:55:03 +00:00
Kyle Miller
606aeddf06 feat: make dot notation be affected by export/open (#6189)
This PR changes how generalized field notation ("dot notation") resolves
the function. The new resolution rule is that if `x : S`, then `x.f`
resolves the name `S.f` relative to the root namespace (hence it now
affected by `export` and `open`). Breaking change: aliases now resolve
differently. Before, if `x : S`, and if `S.f` is an alias for `S'.f`,
then `x.f` would use `S'.f` and look for an argument of type `S'`. Now,
it looks for an argument of type `S`, which is more generally useful
behavior. Code making use of the old behavior should consider defining
`S` or `S'` in terms of the other, since dot notation can unfold
definitions during resolution.

This also fixes a bug in explicit-mode generalized field notation
(`@x.f`) where `x` could be passed as the wrong argument. This was not a
bug for explicit-mode structure projections.

Closes #3031. Addresses the `Function` namespace issue in #1629.
2024-11-25 18:38:17 +00:00
Kyle Miller
0eca3bd55d feat: add a coercion from List Nat to Lean.Meta.Occurrences (#6206)
This PR makes it possible to write `rw (occs := [1,2]) ...` instead of
`rw (occs := .pos [1,2]) ...` by adding a coercion from `List.Nat` to
`Lean.Meta.Occurrences`.
2024-11-25 13:19:23 +00:00
Kim Morrison
43dfc2a25f chore: fix Vector.indexOf? (#6208)
Just a better defeq.
2024-11-25 10:47:58 +00:00
Mac Malone
935fcfb6ec feat: non-opaque UInt64.toUSize (#6202)
This PR makes `USize.toUInt64` a regular non-opaque definition. 

It also moves it to `Init.Data.UInt.Basic`, as it is not actually used
in `Init.Prelude` anymore.
2024-11-25 08:33:53 +00:00
Kim Morrison
20acc72a29 feat: ensure Fin.foldl/r are semireducible (#6207)
This PR ensures the `Fin.foldl` and `Fin.foldr` are semireducible.
Without this the defeq `example (f : Fin 3 → ℕ) : List.ofFn f = [f 0, f
1, f 2] := rfl` was failing.

Thanks @eric-wieser and @digama0 for diagnosing on
[Zulip](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/.60List.2EfinRange.60.20in.20Mathlib/near/484191814).
2024-11-25 03:21:36 +00:00
Kim Morrison
c3948cba24 feat: upstream definition of Vector from Batteries (#6197)
This PR upstreams the definition of `Vector` from Batteries, along with
the basic functions.
2024-11-24 23:01:32 +00:00
Kim Morrison
4e885be96d feat: rename Array.setD to setIfInBounds (#6195)
This PR renames `Array.setD` to `Array.setIfInBounds`.
2024-11-24 08:54:19 +00:00
Kim Morrison
42e98bd3c9 feat: Array.swap takes Nat arguments, with tactic provided proofs (#6194)
This PR changes the signature of `Array.swap`, so it takes `Nat`
arguments with tactic provided bounds checking. It also renames
`Array.swap!` to `Array.swapIfInBounds`.
2024-11-24 07:59:57 +00:00
Kim Morrison
884a9ea2ff feat: remove partial keyword and runtime bounds checks from Array.binSearch (#6193)
This PR completes the TODO in `Init.Data.Array.BinSearch`, removing the
`partial` keyword and converting runtime bounds checks to compile time
bounds checks.
2024-11-24 06:08:16 +00:00
Kyle Miller
2f5c7d0465 fix: structures with copied parents can now use other parents as instances (#6175)
This PR fixes a bug with the `structure`/`class` command where if there
are parents that are not represented as subobjects but which used other
parents as instances, then there would be a kernel error. Closes #2611.

Note: there is still the limitation that parents that are not
represented as subobjects do not themselves provide instances to other
parents.
2024-11-24 04:22:39 +00:00
Kim Morrison
a5ffef7e13 feat: Array.zipWithAll (#6191)
This PR adds `Array.zipWithAll`, and the basic lemmas relating it to
`List.zipWithAll`.
2024-11-24 03:49:57 +00:00
Kim Morrison
442c3d5097 chore: missing deprecations for Lean.HashMap (#6192)
This PR adds deprecations for `Lean.HashMap` functions which did not
receive deprecation attributes initially.

(Requested on
[zulip](https://leanprover.zulipchat.com/#narrow/channel/348111-batteries/topic/Unifying.20.60Batteries.2EHashMap.60.20and.20.60Std.2EHashMap.60.2E/near/484113660).)

Note that I've used the original deprecation date of 2024-08-08, when
the type itself was deprecated; this will not delay removal.
2024-11-24 03:29:48 +00:00
Joachim Breitner
bf13b24692 doc: refine kernel code comments (#6150)
I just spent too much time being confused about the kernel type checker
until I noticed that `lazy_delta_reduction` modifies its arguments.
2024-11-23 17:13:51 +00:00
Andrii Kurdiumov
51d1cc61d7 fix: remove obsolete sentence in doc-string (#6185)
Even if this sentence is technically true, it do not add anything to the
explanation of typechecker and code.
2024-11-23 07:56:31 +00:00
Siddharth
107a2e8b2e feat: BitVec.toInt BitVec.signExtend (#6157)
This PR adds toInt theorems for BitVec.signExtend.

If the current width `w` is larger than the extended width `v`,
then the value when interpreted as an integer is truncated,
and we compute a modulo by `2^v`.

```lean
theorem toInt_signExtend_of_le (x : BitVec w) (hv : v ≤ w) :
    (x.signExtend v).toInt = Int.bmod (x.toNat) (2^v)
```

Co-authored-by: Siddharth Bhat <siddu.druid@gmail.com>
Co-authored-by: Harun Khan <harun19@stanford.edu>


Stacked on top of #6155

---------

Co-authored-by: Harun Khan <harun19@stanford.edu>
2024-11-23 07:29:08 +00:00
Kim Morrison
c4b0b94c91 chore: use Array.findFinIdx? where it is better than findIdx? (#6184)
This PR uses `Array.findFinIdx?` in preference to `Array.findIdx?` where
it allows converting a runtime bounds check to a compile time bounds
check.

(and some other minor cleanup)
2024-11-23 07:22:31 +00:00
Kyle Miller
ba3f2b3ecf fix: make sure #check id heeds pp.raw (#6181)
This PR fixes a bug where the signature pretty printer would ignore the
current setting of `pp.raw`. This fixes an issue where `#check ident`
would not heed `pp.raw`. Closes #6090.
2024-11-23 00:39:58 +00:00
Leonardo de Moura
4a69643858 fix: nontermination while generating equation lemmas for match-expressions (#6180)
This PR fixes a non-termination bug that occurred when generating the
match-expression equation theorems. The bug was triggered when the proof
automation for the equation theorem repeatedly applied `injection(` to
the same local declaration, as it could not be removed due to forward
dependencies. See issue #6067 for an example that reproduces this issue.

closes #6067
2024-11-23 00:06:34 +00:00
Kyle Miller
b6a0d63612 feat: have "motive is not type correct" come with an explanation (#6168)
This PR extends the "motive is not type correct" error message for the
rewrite tactic to explain what it means. It also pretty prints the
type-incorrect motive and reports the type error.

Suggested [on
Zulip](https://leanprover.zulipchat.com/#narrow/channel/113489-new-members/topic/tactic.20'rewrite'.20failed.2C.20motive.20is.20not.20type.20correct/near/483545154).
2024-11-22 23:56:17 +00:00
Kyle Miller
5145030ff4 chore: refactor Elab.StructInst to use mutual for its structures/inductives (#6174)
Making use of #6125.
2024-11-22 19:17:48 +00:00
Kyle Miller
d3cb812fb6 chore: add test for recursive structures (#6173)
Closes #6140. This was fixed by #6125.
2024-11-22 18:53:59 +00:00
Lean stage0 autoupdater
e066c17a65 chore: update stage0 2024-11-22 18:29:01 +00:00
Sebastian Ullrich
38cff08888 feat: creation and reporting for asynchronous elaboration tasks (#6170)
This PR adds core metaprogramming functions for forking off background
tasks from elaboration such that their results are visible to reporting
and the language server
2024-11-22 17:12:30 +00:00
David Thrane Christiansen
3388fc8d06 doc: fix typo and make docstring more precise (#6009)
This PR fixes a typo in the docstring for prec and makes the text
slightly more precise.
2024-11-22 16:30:01 +00:00
Eric Wieser
5adcd520fa fix: make the stack handling more robust to sanitizers and -O3 (#6143)
This PR should make lean better-behaved around sanitizers, per
https://github.com/google/sanitizers/issues/1688.
As far as I can tell,
https://github.com/google/sanitizers/wiki/AddressSanitizerUseAfterReturn#algorithm
replaces local variables with heap allocations, and so taking the
address of a local is not effective at producing a monotonic measure of
stack usage.

The approach used here is the same as the one used by clang.
2024-11-22 15:10:20 +00:00
David Thrane Christiansen
1126407d9b feat: create temporary directories (#6148)
This PR adds a primitive for creating temporary directories, akin to the
existing functionality for creating temporary files.
2024-11-22 12:24:32 +00:00
Kyle Miller
a19ff61e15 feat: allow structure in mutual blocks (#6125)
This PR adds support for `structure` in `mutual` blocks, allowing
inductive types defined by `inductive` and `structure` to be mutually
recursive. The limitations are (1) that the parents in the `extends`
clause must be defined before the `mutual` block and (2) mutually
recursive classes are not allowed (a limitation shared by `class
inductive`). There are also improvements to universe level inference for
inductive types and structures. Breaking change: structure parents now
elaborate with the structure in scope (fix: use qualified names or
rename the structure to avoid shadowing), and structure parents no
longer elaborate with autoimplicits enabled.

Internally, this is a large refactor of both the `inductive` and
`structure` commands. Common material is now in
`Lean.Elab.MutualInductive`, and each command plugs into this mutual
inductive elaboration framework with the logic specific to the
respective command. For example, `structure` has code to add projections
after the inductive types are added to the environment.

Closes #4182
2024-11-22 09:20:07 +00:00
Lean stage0 autoupdater
6202461a21 chore: update stage0 2024-11-22 04:42:45 +00:00
Kim Morrison
ea221f3283 feat: Nat.(fold|foldRev|any|all)M? take a function which sees the upper bound (#6139)
This PR modifies the signature of the functions `Nat.fold`,
`Nat.foldRev`, `Nat.any`, `Nat.all`, so that the function is passed the
upper bound. This allows us to change runtime array bounds checks to
compile time checks in many places.
2024-11-22 03:05:51 +00:00
Kyle Miller
7c50d597c3 feat: add builtin attribute to support elaboration of mutual inductives/structures (#6166)
This PR is a prerequisite for #6125.
2024-11-22 01:48:37 +00:00
Tony Beta Lambda
99031695bd feat: display coercions with a type ascription (#6119)
This PR adds a new delab option `pp.coercions.types` which, when
enabled, will display all coercions with an explicit type ascription.

[Link to Zulip
discussion](https://leanprover.zulipchat.com/#narrow/channel/239415-metaprogramming-.2F-tactics/topic/Roundtripping.20delaboration.20involving.20coercions)

Towards #4315
2024-11-21 23:02:47 +00:00
JovanGerb
b7248d5295 fix: revert creates natural metavariable goal (#6145)
This PR fixes the `revert` tactic so that it creates a `syntheticOpaque`
metavariable as the new goal, instead of a `natural` metavariable

I reported it on
[Zulip](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/.60revert.60.20gives.20natural.20metavariable.20goal/near/483388096)
2024-11-21 23:00:57 +00:00
Tobias Grosser
7f2e7e56d2 feat: BitVec.getMsbD_[ofNatLt|allOnes|not] (#6149)
This PR completes the elementwise accessors for `ofNatLt`, `allOnes`,
and `not` by adding their implementations of `getMsbD`.
2024-11-21 22:13:09 +00:00
Tobias Grosser
1fe66737ad feat: BitVec.toInt_[or|and|xor|not] (#6151)
This PR completes the `toInt` interface for `BitVec` bitwise operations.
2024-11-21 22:10:33 +00:00
Bhavik Mehta
765eb02279 doc: adjust file reference in Data.Sum (#6158)
This file was upstreamed from batteries; I just got bitten by the
invalid reference and it took quite a while to figure out that this one
had been moved!
2024-11-21 21:48:27 +00:00
Henrik Böving
a101377054 perf: speed up reflection of if in bv_decide (#6162)
This PR adds a slight performance improvement to reflection of `if`
statements that I noticed by profiling Leanwuzla against SMTCOMP's
`non-incremental/QF_BV/fft/Sz256_6616.smt2`.

In particular:
1. The profile showed about 4 percent of the total run time were spent
constructing these decidable instances in reflection of `if` statements.
We can construct them much quicker by hand as they always have the same
structure
2. This delays construction of these statements until we actually
generate the reflection proof that we wish to submit to the kernel. Thus
if we encounter a SAT instad of an UNSAT problem we will not spend time
generating these expressions anymore.

```
baseline
  Time (mean ± σ):     31.236 s ±  0.258 s
  Range (min … max):   30.899 s … 31.661 s    10 runs

after
  Time (mean ± σ):     30.671 s ±  0.288 s
  Range (min … max):   30.350 s … 31.156 s    10 runs
```
2024-11-21 19:40:14 +00:00
Kyle Miller
aca9929d84 fix: make sure whitespace is printed before tactic configuration (#6161)
This PR ensures whitespace is printed before `+opt` and `-opt`
configuration options when pretty printing, improving the experience of
tactics such as `simp?`.

Reported [on
Zulip](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Minor.20simp.3F.20annoyances/near/483736310)
2024-11-21 19:21:59 +00:00
Sebastian Ullrich
19a701e5c9 refactor: one more recursive structure (#6159) 2024-11-21 18:30:28 +00:00
Leonardo de Moura
fc4305ab15 fix: nontermination when generating the match-expression splitter theorem (#6146)
This PR fixes a non-termination bug that occurred when generating the
match-expression splitter theorem. The bug was triggered when the proof
automation for the splitter theorem repeatedly applied `injection` to
the same local declaration, as it could not be removed due to forward
dependencies. See issue #6065 for an example that reproduces this issue.

closes #6065
2024-11-21 17:20:33 +00:00
Kim Morrison
9cf83706e7 chore: add changelog-* labels via comment (#6147)
This PR enables contributors to modify `changelog-*` labels simply by
writing a comment with the desired label.
2024-11-21 07:23:13 +00:00
Tobias Grosser
459c6e2a46 feat: BitVec.getElem_[sub|neg|sshiftRight'|abs] (#6126)
This PR adds lemmas for extracting a given bit of a `BitVec` obtained
via `sub`/`neg`/`sshiftRight'`/`abs`.

---------

Co-authored-by: Kim Morrison <scott@tqft.net>
2024-11-21 07:01:11 +00:00
Kim Morrison
72e952eadc chore: avoid runtime array bounds checks (#6134)
This PR avoids runtime array bounds checks in places where it can
trivially be done at compile time.

None of these changes are of particular consequence: I mostly wanted to
learn how much we do this, and what the obstacles are to doing it less.
2024-11-21 05:04:52 +00:00
damiano
56a80dec1b doc: doc-strings to module docs in Data/Array/Lemmas (#6144)
This PR converts 3 doc-string to module docs since it seems that this is
what they were intended to be!
2024-11-21 05:04:09 +00:00
JovanGerb
b894464191 fix: type occurs check bug (#6128)
This PR does the same fix as #6104, but such that it doesn't break the
test/the file in `Plausible`. This is done by not creating unused let
binders in metavariable types that are made by `elimMVar`. (This is also
a positive thing for users looking at metavariable types, for example in
error messages)

We get rid of `skipAtMostNumBinders`. This function was originally
defined for the purpose of making this test work, but it is a hack
because it allows cycles in the metavariable context.

It would make sense to split these changes into 2 PRs, but I combined
them here to show that the combination of them closes #6013 without
breaking anything

Closes #6013
2024-11-21 00:28:36 +00:00
Sebastian Ullrich
b30903d1fc refactor: make use of recursive structures in snapshot types (#6141) 2024-11-20 15:15:14 +00:00
Sebastian Ullrich
7fbe8e3b36 fix: Inhabited Float produced a bogus run-time value (#6136)
This PR fixes the run-time evaluation of `(default : Float)`.
2024-11-20 10:43:59 +00:00
Sebastian Ullrich
2fbc46641d fix: trace.profiler pretty-printing (#6138)
This PR fixes `trace.profiler.pp` not using the term pretty printer.

Fixes #5872
2024-11-20 10:21:02 +00:00
Sebastian Ullrich
17419aca7f feat: thread support for trace.profiler.output (#6137)
This PR adds support for displaying multiple threads in the trace
profiler output.

`TraceState.tid` needs to be adjusted for this purpose, which is not
done yet by the Lean elaborator as it is still single-threaded.
2024-11-20 10:02:39 +00:00
Kim Morrison
f85c66789d feat: Array.insertIdx/eraseIdx take a tactic-provided proof (#6133)
This PR replaces `Array.feraseIdx` and `Array.insertAt` with
`Array.eraseIdx` and `Array.insertIdx`, both of which take a `Nat`
argument and a tactic-provided proof that it is in bounds. We also have
`eraseIdxIfInBounds` and `insertIdxIfInBounds` which are noops if the
index is out of bounds. We also provide a `Fin` valued version of
`Array.findIdx?`. Together, these quite ergonomically improve the array
indexing safety at a number of places in the compiler/elaborator.
2024-11-20 09:52:38 +00:00
Kim Morrison
c8b4f6b511 feat: duplicate List.attach/attachWith/pmap API for Array (#6132)
This PR duplicates the verification API for
`List.attach`/`attachWith`/`pmap` over to `Array`.
2024-11-20 01:16:48 +00:00
Luisa Cicolini
3c7555168d feat: add BitVec.(msb, getMsbD)_(rotateLeft, rotateRight) (#6120)
This PR adds theorems `BitVec.(getMsbD, msb)_(rotateLeft, rotateRight)`.

We follow the same strategy taken for `getLsbD`, constructing the
necessary auxilliary theorems first (relying on different hypotheses)
and then generalizing.

---------

Co-authored-by: Siddharth <siddu.druid@gmail.com>
Co-authored-by: Tobias Grosser <tobias@grosser.es>
2024-11-19 23:04:14 +00:00
Kyle Miller
5eef3d27fb feat: have #print show precise fields of structures (#6096)
This PR improves the `#print` command for structures to show all fields
and which parents the fields were inherited from, hiding internal
details such as which parents are represented as subobjects. This
information is still present in the constructor if needed. The pretty
printer for private constants is also improved, and it now handles
private names from the current module like any other name; private names
from other modules are made hygienic.

Example output for `#print Monad`:
```
class Monad.{u, v} (m : Type u → Type v) : Type (max (u + 1) v)
number of parameters: 1
parents:
  Monad.toApplicative : Applicative m
  Monad.toBind : Bind m
fields:
  Functor.map : {α β : Type u} → (α → β) → m α → m β
  Functor.mapConst : {α β : Type u} → α → m β → m α
  Pure.pure : {α : Type u} → α → m α
  Seq.seq : {α β : Type u} → m (α → β) → (Unit → m α) → m β
  SeqLeft.seqLeft : {α β : Type u} → m α → (Unit → m β) → m α
  SeqRight.seqRight : {α β : Type u} → m α → (Unit → m β) → m β
  Bind.bind : {α β : Type u} → m α → (α → m β) → m β
constructor:
  Monad.mk.{u, v} {m : Type u → Type v} [toApplicative : Applicative m] [toBind : Bind m] : Monad m
resolution order:
  Monad, Applicative, Bind, Functor, Pure, Seq, SeqLeft, SeqRight
```

Suggested by Floris van Doorn [on
Zulip](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/.23print.20command.20for.20structures/near/482503637).
2024-11-19 21:54:45 +00:00
Leonardo de Moura
75d1504af2 fix: isDefEq for constants with different universe parameters (#6131)
This PR fixes a bug at the definitional equality test (`isDefEq`). At
unification constraints of the form `c.{u} =?= c.{v}`, it was not trying
to unfold `c`. This bug did not affect the kernel.

closes #6117
2024-11-19 21:39:13 +00:00
Mario Carneiro
a00cf6330f fix: add a missing case to Level.geq (#2689)
This PR adds a case to `Level.geq` that is present in the kernel's level
`is_geq` procedure, making them consistent with one another.

This came up during testing of `lean4lean`. Currently `Level.geq`
differs from `level::is_geq` in the case of `max u v >= imax u v`. The
elaborator function is overly pessimistic and yields `false` on this
while the kernel function yields true. This comes up concretely in the
`Trans` class:
```lean
class Trans (r : α → β → Sort u) (s : β → γ → Sort v) (t : outParam (α → γ → Sort w)) where
  trans : r a b → s b c → t a c
```
The type of this class is `Sort (max (max (max (max (max (max 1 u) u_1)
u_2) u_3) v) w)` (where `u_1 u_2 u_3` are the levels of `α β γ`), but if
you try writing that type explicitly then the `class` command fails.
Omitting the type leaves the `class` to infer the universe level (the
command assumes the level is correct, and the kernel agrees it is), but
including the type then the elaborator checks the level inequality with
`Level.geq` and fails.

---------

Co-authored-by: Kyle Miller <kmill31415@gmail.com>
2024-11-19 21:27:00 +00:00
Leonardo de Moura
1f32477385 fix: isDefEq when zetaDelta := false (#6129)
This PR fixes a bug at `isDefEq` when `zetaDelta := false`. See new test
for a small example that exposes the issue.
2024-11-19 21:22:02 +00:00
Thomas Köppe
91c14c7ee9 fix: only consider salient bytes in sharecommon eq, hash (#5840)
This PR changes `lean_sharecommon_{eq,hash}` to only consider the
salient bytes of an object, and not any bytes of any
unspecified/uninitialized unused capacity.

Accessing uninitialized storage results in undefined behaviour.

This does not seem to have any semantics disadvantages: If objects
compare equal after this change, their salient bytes are still equal. By
contrast, if the actual identity of allocations needs to be
distinguished, that can be done by just comparing pointers to the
storage.

If we wanted to retain the current logic, we would need initialize the
otherwise unused parts to some specific value to avoid the undefined
behaviour.

Closes #5831
2024-11-19 13:56:46 +00:00
Lean stage0 autoupdater
69530afdf9 chore: update stage0 2024-11-19 13:06:43 +00:00
Marc Huisinga
b7667c1604 fix: don't issue atomic id completions when there is a dangling dot (#5837)
This PR fixes an old auto-completion bug where `x.` would issue
nonsensical completions when `x.` could not be elaborated as a dot
completion.
2024-11-19 12:23:41 +00:00
Eric Wieser
d6f898001b chore: generalize List.get_mem (#6095)
This is syntactically more general than before, though up to eta
expansion it make no difference.
2024-11-19 11:08:10 +00:00
Marc Huisinga
a38566693b test: fix brittle structure instance completion test (#6127)
#5835 contains a brittle test that uses an FVar ID, which caused a
failure on master. This PR changes that test to use a declaration
instead.
2024-11-19 10:13:51 +00:00
Marc Huisinga
4bef3588b5 chore: update stage0 2024-11-19 09:26:58 +01:00
Marc Huisinga
64538cf6e8 chore: prepare for bootstrap
Co-Authored-By: Sebastian Ullrich <sebasti@nullri.ch>
2024-11-19 09:26:58 +01:00
Marc Huisinga
aadf3f1d2c feat: use new structInstFields parser to tag structure instance fields 2024-11-19 09:26:58 +01:00
Marc Huisinga
95bf45ff8b refactor: split Completion.lean 2024-11-19 09:26:58 +01:00
Marc Huisinga
2a02c121cf feat: structure auto-completion & partial InfoTrees 2024-11-19 09:26:58 +01:00
Mac Malone
4600bb16fc feat: use BaseIO at IO.rand (#6102)
This PR moves `IO.rand` and `IO.setRandSeed` to be in the `BaseIO`
monad.

This is their proper monad as neither can error.
2024-11-19 05:26:03 +00:00
Kim Morrison
7ccdfc30ff chore: turn off pp.mvars in apply? results (#6108)
Per request on
[zulip](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/apply.3F.20using.20tombstones/near/482895588).
2024-11-19 02:02:32 +00:00
Kim Morrison
7f0bdefb6e chore: fix apply? error reporting when out of heartbeats (#6121) 2024-11-19 00:57:59 +00:00
Joachim Breitner
799b2b6628 fix: handle reordered indices in structural recursion (#6116)
This PR fixes a bug where structural recursion did not work when indices
of the recursive argument appeared as function parameters in a different
order than in the argument's type's definition.

Fixes #6015.
2024-11-18 11:28:02 +00:00
David Thrane Christiansen
b8d6e44c4f fix: liberalize rules for atoms by allowing leading '' (#6114)
This PR liberalizes atom rules by allowing `''` to be a prefix of an
atom, after #6012 only added an exception for `''` alone, and also adds
some unit tests for atom validation.
2024-11-18 10:19:20 +00:00
Kim Morrison
5a99cb326c chore: make Lean.Elab.Command.mkMetaContext public (#6113) 2024-11-18 06:14:34 +00:00
Kim Morrison
e10fac93a6 feat: lemmas for Array.findSome? and find? (#6111)
This PR fills in the API for `Array.findSome?` and `Array.find?`,
transferring proofs from the corresponding List statements.
2024-11-18 04:19:56 +00:00
Kyle Miller
62ae320e1c chore: document Lean.Elab.StructInst, refactor (#6110)
This PR does some mild refactoring of the `Lean.Elab.StructInst` module
while adding documentation.

Documentation is drawn from @thorimur's #1928.
2024-11-18 02:57:22 +00:00
Leonardo de Moura
98b1edfc1f fix: backtrack at injection failure (#6109)
This PR fixes an issue in the `injection` tactic. This tactic may
execute multiple sub-tactics. If any of them fail, we must backtrack the
partial assignment. This issue was causing the error: "`mvarId` is
already assigned" in issue #6066. The issue is not yet resolved, as the
equation generator for the match expressions is failing in the example
provided in this issue.
2024-11-18 02:26:06 +00:00
Leonardo de Moura
ab162b3f52 fix: isDefEq, whnf, simp caching and configuration (#6053)
This PR fixes the caching infrastructure for `whnf` and `isDefEq`,
ensuring the cache accounts for all relevant configuration flags. It
also cleans up the `WHNF.lean` module and improves the configuration of
`whnf`.
2024-11-18 01:17:26 +00:00
Kim Morrison
b8a13ab755 chore: fix naming of left/right injectivity lemmas (#6106)
We've been internally inconsistent on the naming of these lemmas in
Lean; this changes them to match Mathlib (which, moreover, I think is
correct).
2024-11-18 00:53:46 +00:00
Sebastian Ullrich
405593ea28 chore: avoid stack overflow in debug tests (#6103) 2024-11-17 14:54:49 +00:00
Kim Morrison
24f305c0e3 chore: fix canonicalizer handling over forall/lambda (#6082)
This PR changes how the canonicalizer handles `forall` and `lambda`,
replacing bvars with temporary fvars. Fixes a bug reported by @hrmacbeth
on
[zulip](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Quantifiers.20in.20CanonM/near/482483448).
2024-11-17 07:34:45 +00:00
Leonardo de Moura
5d553d6369 fix: circular assignment at structure instance elaborator (#6105)
This PR fixes a stack overflow caused by a cyclic assignment in the
metavariable context. The cycle is unintentionally introduced by the
structure instance elaborator.

closes #3150
2024-11-17 00:56:52 +00:00
Sebastian Ullrich
a449e3fdd6 feat: IO.getTID (#6049)
This PR adds a primitive for accessing the current thread ID

To be used in a thread-aware trace profiler
2024-11-16 19:13:11 +00:00
Kyle Miller
764386734c fix: improvements to change tactic (#6022)
This PR makes the `change` tactic and conv tactic use the same
elaboration strategy. It works uniformly for both the target and local
hypotheses. Now `change` can assign metavariables, for example:
```lean
example (x y z : Nat) : x + y = z := by
  change ?a = _
  let w := ?a
  -- now `w : Nat := x + y`
```
2024-11-16 07:08:29 +00:00
Kyle Miller
7f1d7a595b fix: use Expr.equal instead of == in MVarId.replaceTargetDefEq and MVarId.replaceLocalDeclDefEq (#6098)
This PR modifies `Lean.MVarId.replaceTargetDefEq` and
`Lean.MVarId.replaceLocalDeclDefEq` to use `Expr.equal` instead of
`Expr.eqv` when determining whether the expression has changed. This is
justified on the grounds that binder names and binder infos are
user-visible and affect elaboration.
2024-11-16 02:03:16 +00:00
Leonardo de Moura
f13e5ca852 chore: naming convention and NaN normalization (#6097)
Changes:
- `Float.fromBits` => `Float.ofBits`
- NaN normalization
2024-11-16 00:14:28 +00:00
Leonardo de Moura
ecbaeff24b feat: add Float.toBits and Float.fromBits (#6094)
This PR adds raw transmutation of floating-point numbers to and from
`UInt64`. Floats and UInts share the same endianness across all
supported platforms. The IEEE 754 standard precisely specifies the bit
layout of floats. Note that `Float.toBits` is distinct from
`Float.toUInt64`, which attempts to preserve the numeric value rather
than the bitwise value.

closes #6071
2024-11-15 19:45:19 +00:00
Kyle Miller
691acde696 feat: pp.parens option to pretty print with all parentheses (#2934)
This PR adds the option `pp.parens` (default: false) that causes the
pretty printer to eagerly insert parentheses, which can be useful for
teaching and for understanding the structure of expressions. For
example, it causes `p → q → r` to pretty print as `p → (q → r)`.

Any notations with precedence greater than or equal to `maxPrec` do not
receive such discretionary parentheses, since this precedence level is
considered to be infinity.

This option was a feature in the Lean 3 community edition.
2024-11-15 19:11:54 +00:00
Kyle Miller
b1e0c1b594 chore: remove decide! tactic (#6016)
This PR removes the `decide!` tactic in favor of `decide +kernel`
(breaking change).
2024-11-15 17:49:33 +00:00
Joachim Breitner
93b4ec0351 refactor: use mkFreshUserName in ArgsPacker (#6093)
and other small refinements done while investigating an issue; not
actually user-visible.
2024-11-15 15:59:14 +00:00
JovanGerb
f06fc30c0b perf: remove @[specialize] from mkBinding (#6019)
This PR removes @[specilize] from `MkBinding.mkBinding`, which is a
function that cannot be specialized (as none of its arguments are
functions). As a result, the specializable function `Nat.foldRevM.loop`
doesn't get specialized, which leads to worse performing code.

As expected, the mathlib bench shows a very small improvement. About 95%
of files show a speedup.
(http://speed.lean-fro.org/mathlib4/compare/e7b27246-a3e6-496a-b552-ff4b45c7236e/to/6033df75-aa53-44d9-819d-51f93fc05e94?hash1=b28f0d7f7e9cc3949a9a3556a6b36513f37f690d)
2024-11-15 15:06:49 +00:00
Markus Himmel
64b35a8c19 perf: add LEAN_ALWAYS_INLINE to some functions (#6045)
Otherwise, clang refuses to inline them for large functions which leads
to a performance cliff.
2024-11-15 15:05:32 +00:00
Markus Himmel
688ee4c887 fix: constant folding for Nat.ble and Nat.blt (#6087)
This PR fixes a bug in the constant folding for the `Nat.ble` and
`Nat.blt` function in the old code generator, leading to a
miscompilation.

Closes #6086
2024-11-15 12:09:52 +00:00
Henrik Böving
9a3dd615e0 chore: bv_decide remove noop rewrites (#6080)
Merely removes rules that are actually just syntactic aliases but equal
at the `Expr` level.
2024-11-15 11:41:54 +00:00
Violeta Hernández
7e6363dc05 chore: join → flatten in docstring (#6040)
Update the docstring of `List.flatten`.
2024-11-15 10:11:42 +00:00
Kim Morrison
a074bd9a2b feat: implementation of Array.pmap (#6052)
This PR adds `Array.pmap`, as well as a `@[csimp]` lemma in terms of the
no-copy `Array.attachWith`.
2024-11-15 02:10:04 +00:00
Kyle Miller
498d41633b fix: pretty print .coeFun with terminfo of coercee (#6085)
This PR improves the term info for coercions marked with
`CoeFnType.coeFun` (such as `DFunLike.coe` in Mathlib), making "go to
definition" on the function name work. Hovering over such a coerced
function will show the coercee rather than the coercion expression. The
coercion expression can still be seen by hovering over the whitespace in
the function application.
2024-11-15 01:45:38 +00:00
Sofia Rodrigues
e0d7c3ac79 feat: add date and time functionality (#4904)
This PR introduces date and time functionality to the Lean 4 Std.

Breaking Changes:
- `Lean.Data.Rat` is now `Std.Internal.Rat` because it's used by the
DateTime library.

---------

Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
Co-authored-by: Mac Malone <tydeu@hatpress.net>
2024-11-14 14:04:19 +00:00
Joachim Breitner
6a5b122b40 perf: use RArray in simp_arith meta code (#6068 part 2)
This PR makes `simp_arith` use `RArray` for the context of the
reflection proofs, which scales better when there are many variables.

On our synthetic benchmark:
```
simp_arith1               instructions    -25.1% (-4892.6 σ)
```

No effect on mathlib, though, guess it’s not used much on large goals there:
http://speed.lean-fro.org/mathlib4/compare/873b982b-2038-462a-9b68-0c0fc457f90d/to/56e66691-2f1f-4947-a922-37b80680315d
2024-11-14 14:08:48 +01:00
Joachim Breitner
bf9ddf2c74 chore: update stage0 2024-11-14 14:08:48 +01:00
Joachim Breitner
3f47871e73 perf: use RArray in simp_arith meta code (#6068 part 1)
This PR prepares #6068 by using the `RArray` data structure in
`simp_arith` the simp-arith meta code.

After the subsequent stage0 we can change the simp-arith theorems in
`Init`.
2024-11-14 14:08:48 +01:00
Joachim Breitner
85f25967ea feat: Lean.RArray (#6070)
This PR adds the Lean.RArray data structure.

This data structure is equivalent to `Fin n → α` or `Array α`, but
optimized for a fast kernel-reduction `get` operation.

It is not suitable as a general-purpose data structure. The primary
intended use case is the “denote” function of a typical proof by
reflection proof, where only the `get` operation is necessary, and where
using `List.get` unnecessarily slows down proofs with more than a
hand-full of atomic expressions.


There is no well-formedness invariant attached to this data structure,
to keep it concise; it's semantics is given through `RArray.get`. In
that way one can also view an `RArray` as a decision tree implementing
`Nat → α`.

In #6068 this data structure is used in `simp_arith`.
2024-11-14 10:56:50 +00:00
David Thrane Christiansen
8e1ddbc5aa fix: validate atoms modulo leading and trailing whitespace (#6012)
This PR improves the validation of new syntactic tokens. Previously, the
validation code had inconsistencies: some atoms would be accepted only
if they had a leading space as a pretty printer hint. Additionally,
atoms with internal whitespace are no longer allowed.

Closes #6011
2024-11-14 10:40:17 +00:00
Henrik Böving
e6e39f502f feat: add options to configure all of bv_decide's preprocessing (#6077)
This PR adds options to `bv_decide`'s configuration structure such that
all non mandatory preprocessing passes can be disabled.
2024-11-14 09:22:23 +00:00
Henrik Böving
debb82bc20 perf: make andFlattening work on deeply nested hyps in one pass (#6075)
No changelog as this PR improves performance of a feature that is not
yet released.
2024-11-14 09:09:25 +00:00
Violeta Hernández
9a85433477 refactor: allow Sort u in Squash (#6074)
Co-authored-by: Kim Morrison <kim@tqft.net>
2024-11-14 05:55:21 +00:00
Mac Malone
4616c0ac3e refactor: lake: avoid v! in builtin code (#6073)
Use of `v!` in Lake code can cause bootstrapping failures and is easily
avoided. It is perfectly safe in user code.
2024-11-14 05:00:02 +00:00
Leonardo de Moura
e55b681774 feat: add Context.setConfig (#6072)
This PR adds `Lean.Simp.Context.setConfig` function.
2024-11-14 00:32:13 +00:00
Kim Morrison
63132105ba feat: lemmas about for loops over Array (#6055)
This PR adds lemmas about for loops over `Array`, following the existing
lemmas for `List`.
2024-11-13 23:23:55 +00:00
Kim Morrison
350b36411c chore: upstream some NameMap functions (#6056) 2024-11-13 23:22:01 +00:00
Kim Morrison
1c30c76e72 chore: remove >6 month old deprecations (#6057) 2024-11-13 23:21:23 +00:00
Alissa Tung
d5adadc00e chore: add newline at end of file for lake new templates (#6026)
This PR adds a newline at end of each Lean file generated by `lake new`
templates.

I have tested it with a locally compiled Lean with this commit. I hope
these changes make `lake new`'s behavior more consistent with the Lean 4
plugins and libraries newlines convention.
2024-11-13 19:39:47 +00:00
Mac Malone
f08805e5c4 feat: message kinds (#5945)
This PR adds a new definition `Message.kind` which returns the top-level
tag of a message. This is serialized as the new field `kind` in
`SerialMessaege` so that i can be used by external consumers (e.g.,
Lake) to identify messages via `lean --json`.

The tag of trace messages has also been changed from `_traceMsg` to the
more friendly `trace`.
2024-11-13 18:05:52 +00:00
Joachim Breitner
256b49bda9 perf: optimize Nat.Linear.Poly.norm (#6064)
Not a huge benefit, but actually reduces the code complexity (no need
for the `.fuse` function), and can help with problems with many repeated
varibles.
2024-11-13 17:36:51 +00:00
Kyle Miller
28cf146d00 fix: make sure monad lift coercion elaborator has no side effects (#6024)
This PR fixes a bug where the monad lift coercion elaborator would
partially unify expressions even if they were not monads. This could be
taken advantage of to propagate information that could help elaboration
make progress, for example the first `change` worked because the monad
lift coercion elaborator was unifying `@Eq _ _` with `@Eq (Nat × Nat)
p`:
```lean
example (p : Nat × Nat) : p = p := by
  change _ = ⟨_, _⟩ -- used to work (yielding `p = (p.fst, p.snd)`), now it doesn't
  change ⟨_, _⟩ = _ -- never worked
```
As such, this is a breaking change; you may need to adjust expressions
to include additional implicit arguments.
2024-11-13 16:22:31 +00:00
Joachim Breitner
970261b1e1 perf: optimize Nat.Linear.Expr.toPoly (#6062) 2024-11-13 15:54:29 +00:00
Joachim Breitner
6b811f8c92 test: synthetic simp_arith benchmark (#6061)
This PR adds a simp_arith benchmark.

This benchmark highlights some improvable asymptotics in `Nat.Linear`,
which
will be fixed subsequently.
2024-11-13 15:49:52 +00:00
Henrik Böving
f721f94045 feat: Bool.to(U)IntX (#6060)
This PR implements conversion functions from `Bool` to all `UIntX` and
`IntX` types.

Note that `Bool.toUInt64` already existed in previous versions of Lean.
2024-11-13 15:49:16 +00:00
Sebastian Ullrich
86524d5c23 fix: line break in simp? output (#6048)
This PR fixes `simp?` suggesting output with invalid indentation 

Fixes #6006
2024-11-13 15:49:11 +00:00
Joachim Breitner
f18d9e04bc refactor: omega: avoid MVar machinery (#5991)
This PR simplifies the implementation of `omega`.

When constructing the proof, `omega` is using MVars only for the purpose
of doing case analysis on `Or`. We can simplify the implementation a
fair bit if we just produce the proof directly using `Or.elim`.

While it didn’t yield the performance benefits I was hoping for, this
still seems a worthwhile simplification, now that we already have it.
2024-11-13 15:49:03 +00:00
Joachim Breitner
fa33423c84 chore: pr-body: run as part of merge_group, but do not do anything (#6069) 2024-11-13 15:47:58 +00:00
Leonardo de Moura
1315266dd3 refactor: mark the Simp.Context constructor as private
motivation: this is the first step to fix the mismatch
between `isDefEq` and the discrimination tree indexing.
2024-11-13 14:12:55 +11:00
Leonardo de Moura
b1e52f1475 chore: mark Meta.Context.config as private (#6051)
Motivation: we want to modify the internal representation and improve
`isDefEq` caching.
This PR is preparing the stage for future modifications.
2024-11-13 13:30:06 +11:00
Kim Morrison
985600f448 chore: update stage0 2024-11-13 11:16:34 +11:00
Kim Morrison
ace6248e20 chore: deprecate Array.sequenceMap 2024-11-13 11:16:34 +11:00
Lean stage0 autoupdater
9f42368e1a chore: update stage0 2024-11-12 13:28:14 +00:00
Kim Morrison
a401368384 feat: various minor changes to List/Array API (#6044)
Minor emendations to the List/Array API, collected from other PRs that
are still in the pipeline.
2024-11-12 08:27:36 +00:00
Kim Morrison
5e01e628b2 chore: review Array operations argument order (#6041)
This PR modifies the order of arguments for higher-order `Array`
functions, preferring to put the `Array` last (besides positional
arguments with defaults). This is more consistent with the `List` API,
and is more flexible, as dot notation allows two different partially
applied versions.
2024-11-12 04:55:03 +00:00
Kim Morrison
3a408e0e54 feat: change Array.get to take a Nat and a proof (#6032)
This PR changes the signature of `Array.get` to take a Nat and a proof,
rather than a `Fin`, for consistency with the rest of the (planned)
Array API. Note that because of bootstrapping issues we can't provide
`get_elem_tactic` as an autoparameter for the proof. As users will
mostly use the `xs[i]` notation provided by `GetElem`, this hopefully
isn't a problem.

We may restore `Fin` based versions, either here or downstream, as
needed, but they won't be the "main" functions.

---------

Co-authored-by: David Thrane Christiansen <david@davidchristiansen.dk>
2024-11-12 03:30:46 +00:00
Kyle Miller
675d2d5a11 feat: only direct parents of classes create projections (#5920)
This PR changes the rule for which projections become instances. Before,
all parents along with all indirect ancestors that were represented as
subobject fields would have their projections become instances. Now only
projections for direct parents become instances.

Features:
- Only parents that are not ancestors of other parents get instances.
This allows "discretionary" indirect parents to be inserted for the
purpose of computing strict resolution orders when
`structure.strictResolutionOrder` is enabled, without having an impact
on typeclass synthesis.
- Non-subobject projections are now theorems if the parent is a
proposition. These are also no longer `@[reducible]`.

Closes #2905
2024-11-12 01:55:17 +00:00
Henrik Böving
281c07ca97 fix: bv_decide embedded constraint substitution changes models (#6037)
This PR fixes `bv_decide`'s embedded constraint substitution to generate
correct counter examples in the corner case where duplicate theorems are
in the local context.
2024-11-11 16:33:21 +00:00
Sebastian Ullrich
004430b568 fix: avoid new term info around def bodies (#6031)
This PR fixes a regression with go-to-definition and document highlight
misbehaving on tactic blocks.

We explicitly avoid creating term info nodes around `by` blocks, which
#5338 might accidentally do; as the new info is not relevant for the
server, it is instead moved into a custom info.

Reported at
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Go-to-def.20for.20tactics.20broken.20on.20v4.2E14.2E0-rc1.
2024-11-11 14:54:59 +00:00
Henrik Böving
61f7dcb36b feat: bv_decide and flattening (#6035)
This PR introduces the and flattening pre processing pass from Bitwuzla
to `bv_decide`. It splits hypotheses of the form `(a && b) = true` into
`a = true` and `b = true` which has synergy potential with the already
existing embedded constraint substitution pass.

Beyond this I also added some profiling infra structure for the passes.
2024-11-11 13:28:37 +00:00
Joachim Breitner
5c611f7814 fix: simp only [· ∈ ·] (#6030)
This PR fixes `simp only [· ∈ ·]` after #5020.

Fixes #5905
2024-11-11 10:03:27 +00:00
Siddharth
722cb73019 feat: BitVec normalization rule for udiv by twoPow (#6029)
This PR adds a normalization rule to `bv_normalize` (which is used by
`bv_decide`) that converts `x / 2^k` into `x >>> k` under suitable
conditions. This allows us to simplify the expensive division circuits
that are used for bitblasting into much cheaper shifting circuits.
Concretely, it allows for the following canonicalization:

```lean
example {x : BitVec 16} : x / (BitVec.twoPow 16 2) = x >>> 2 := by bv_normalize
example {x : BitVec 16} : x / (BitVec.ofNat 16 8) = x >>> 3 := by bv_normalize
```
2024-11-11 09:45:47 +00:00
Kim Morrison
258d3725e7 feat: change Array.set to take a Nat and a tactic provided bound (#5988)
This PR changes the signature of `Array.set` to take a `Nat`, and a
tactic-provided bound, rather than a `Fin`.

Corresponding changes (but without the auto-param) for `Array.get` will
arrive shortly, after which I'll go more pervasively through the Array
API.
2024-11-11 07:53:24 +00:00
Kim Morrison
456e6d2b79 chore: deprecate duplicated Fin.size_pos (#6025) 2024-11-11 04:06:13 +00:00
Kim Morrison
48e3d76173 feat: variants of List.forIn_eq_foldlM (#6023) 2024-11-11 02:30:40 +00:00
Siddharth
78fe92507c feat: BitVec lemmas for smtUDiv, smtSDiv when denominator is zero (#5616)
This PR is a follow-up to https://github.com/leanprover/lean4/pull/5609,
where we add lemmas characterizing `smtUDiv` and `smtSDiv`'s behavior
when the denominator is zero.

We build some `slt` theory, connecting it to `msb` for a clean proof. I
chose not to characterize `slt` in terms of `msb` a `simp` lemma, since
I anticipate use cases where we want to keep the arithmetic
interpretation of `slt`.
2024-11-10 22:08:43 +00:00
JovanGerb
811d8fb3c0 chore: cleanup (#6021)
This PR removes
- a duplicate `MonadMCtx` instance in `MetavarContext.lean`
- `:= return ←` that I had left there accidentally in a previous PR.
- the unnecessary application of `mapMetaM` in `withTransparency`.
2024-11-09 23:16:12 +00:00
Sebastian Ullrich
f55a9a71cb chore: CI: do not run check-pr-body in merge group 2024-11-09 12:58:53 +01:00
Henrik Böving
d12df6c2ad fix: bv_decide benchmarks (#6017)
This PR fixes the nightly build after bv_decide changed its options
2024-11-09 11:18:33 +00:00
Kyle Miller
d1a99d8d45 fix: avoid delaborating with field notation if object is a metavariable (#6014)
This PR prevents `Nat.succ ?_` from pretty printing as `?_.succ`, which
should make `apply?` be more usable.

Closes #5993
2024-11-08 20:57:37 +00:00
Kyle Miller
c10e4c2256 feat: prop instance yields theorems (#5856)
This PR adds a feature to the the mutual def elaborator where the
`instance` command yields theorems instead of definitions when the class
is a `Prop`.

Closes #5672
2024-11-08 18:18:10 +00:00
Kyle Miller
e3420c08f1 feat: decide +revert and improvements to native_decide (#5999)
This PR adds configuration options for
`decide`/`decide!`/`native_decide` and refactors the tactics to be
frontends to the same backend. Adds a `+revert` option that cleans up
the local context and reverts all local variables the goal depends on,
along with indirect propositional hypotheses. Makes `native_decide` fail
at elaboration time on failure without sacrificing performance (the
decision procedure is still evaluated just once). Now `native_decide`
supports universe polymorphism.

Closes #2072
2024-11-08 18:17:46 +00:00
Sebastian Ullrich
4f7aa8c3c8 chore: CI: exempt drafts from PR body check (#6002) 2024-11-08 15:53:48 +00:00
Sebastian Ullrich
dac73c15c8 perf: avoid negative environment lookup (#5429)
Avoids some `Environment.find?` lookup misses that become especially
expensive on the async branch
2024-11-08 15:37:39 +00:00
Marc Huisinga
cb40ddad69 fix: avoid max heartbeat error in completion (#5996)
This now occurs for some large completions downstream of `import
Mathlib`. I'd like to get rid of this `whnf` call entirely in the
future, but this is a decent quick mitigation.
2024-11-08 13:47:10 +00:00
Alex Keizer
fc0529b020 fix: ensure instantiateMVarsProfiling adds a trace node (#5501)
We add a new `Meta.instantiateMVars` trace node to the
`instantiateMVarsProfiling` definition used in `elabMutualDef`, and we
replace various uses of plain `instantiateMVars` with the profiled
version (which necessitated pulling up the definition to be higher in
the file).

This fixes a "time leak" when profiling large proofs, where
instantiating the goal metavariable can take a significant amount of
time, that previously would not be accounted for when using the trace
profiler.
2024-11-08 13:26:44 +00:00
Henrik Böving
837a67bedb feat: change bv_decide to an elaborated config (#6010)
This PR changes `bv_decide`'s configuration from lots of `set_option` to
an elaborated config like `simp` or `omega`. The notable exception is
`sat.solver` which is still a `set_option` such that users can configure
a custom SAT solver globally for an entire project or file. Additionally
it introduces the ability to set `maxSteps` for the simp preprocessing
run through the new config.

The latter feature was requested by people using `bv_decide` on SMTLIB
which has ginormous terms that exceed the default.
2024-11-08 13:15:04 +00:00
Kyle Miller
85f2213d5a fix: unset trailing for simpa? "try this" suggestion (#5907)
Closes #4581
2024-11-08 12:36:49 +00:00
Lukas Gerlach
9b167e2051 feat: verify keys method on HashMaps (#5866)
This PR verifies the `keys` function on `Std.HashMap`.

---

Initial discussions have already happend with @TwoFX and we are
collaborating on this matter.
This will remain a draft as long as not all desired results have been
added.

If we should still create an issue for the topic of this PR, let us
know.
Of course, any other feedback is appreciated as well :)

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
Co-authored-by: monsterkrampe <monsterkrampe@users.noreply.github.com>
Co-authored-by: jt0202 <johannes.tantow@gmail.com>
2024-11-08 07:24:58 +00:00
Kim Morrison
1870c003d0 chore: missing @[ext] attribute on monad transformer ext lemmas (#6008) 2024-11-08 06:53:49 +00:00
Kim Morrison
680177049f chore: List.modifyTailIdx naming fix (#6007) 2024-11-08 02:42:06 +00:00
Sebastian Ullrich
1b806c5535 chore: revert "CI: give Linux Debug unlimited test stack size" (#6001)
#5967 was the correct fix

Reverts leanprover/lean4#5953
2024-11-07 21:15:08 +00:00
Sebastian Ullrich
9b18262567 chore: new PR changelog template (#5976)
Enables us to auto-generate the changelog from the list of PRs for a
modicum of summarizing/categorizing work on PR creation.

Does not (yet) allow external contributors to set category labels by
themselves as this creates issues with triggering one workflow from
another, it is not clear whether they should be allowed to create new
categories, and the reviewer/triage team likely is in a better position
to do the categorization anyway.
2024-11-07 16:59:45 +00:00
Henrik Böving
d76d631856 feat: BitVec.sshiftRight' in bv_decide (#5995) 2024-11-07 15:23:45 +00:00
Henrik Böving
17e6f3b3c2 style: fix style in bv_decide normalizer (#5992)
Address comments by Markus in #5987
2024-11-07 11:56:12 +00:00
Sebastian Ullrich
5f7a40ae48 chore: fix test exclusion (#5990)
You cannot pass `-E` to `ctest` multiple times
2024-11-07 10:41:47 +00:00
Joachim Breitner
70435dfb5f refactor: name the default SizeOf instance (#5981)
This PR names the default SizeOf instance `instSizeOfDefault`

I regularly have to debug termination checking failures where I end up
hovering over some termination measure, and seeing `instSizeOfDefault`
is more likely to tell me that the default instance is used than
`instSizeOf`.
2024-11-07 09:21:32 +00:00
Henrik Böving
59ee47ad44 feat: BitVec.getMsbD in bv_decide (#5987)
Closes #5983.
2024-11-07 07:59:14 +00:00
Kim Morrison
ebc02fc6e8 feat: lemmas relating Array.findX and List.findX (#5985)
This PR relates the operations `findSomeM?`, `findM?`, `findSome?`, and
`find?` on `Array` with the corresponding operations on `List`, and also
provides simp lemmas for the `Array` operations `findSomeRevM?`,
`findRevM?`, `findSomeRev?`, `findRev?` (in terms of `reverse` and the
usual forward find operations).
2024-11-07 03:30:11 +00:00
Kim Morrison
05caf1bda9 feat: interactions between List.foldX and List.filterX (#5984)
This PR adds lemmas for `List` for the interactions between {`foldl`,
`foldr`, `foldlM`, `foldlrM`} and {`filter`, `filterMap`}.
2024-11-07 02:37:20 +00:00
Kim Morrison
b1dee4a42e chore: upstream List.insertIdx from Batteries, lemmas from Mathlib, and revise lemmas (#5969)
To follow, connecting this to `Array.insertAt` (and renaming).
2024-11-06 23:29:27 +00:00
Kim Morrison
a54226196d feat: minor lemmas about List.ofFn (#5982)
`List.ofFn` still has very incomplete API.
2024-11-06 23:05:42 +00:00
Henrik Böving
196b1e9250 feat: BitVec.twoPow in bv_decide (#5979) 2024-11-06 17:51:44 +00:00
Sebastian Ullrich
345ecd20c9 chore: tag prerelease builds with -pre (#5943) 2024-11-06 14:47:52 +00:00
dependabot[bot]
7f0fe20315 chore: CI: bump mymindstorm/setup-emsdk from 12 to 14 (#5963)
Bumps
[mymindstorm/setup-emsdk](https://github.com/mymindstorm/setup-emsdk)
from 12 to 14.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mymindstorm/setup-emsdk/releases">mymindstorm/setup-emsdk's
releases</a>.</em></p>
<blockquote>
<h2>Version 14</h2>
<h1>Breaking Changes</h1>
<p>The default cache key naming scheme was changed from
<code>{Emscripten version}-{OS type}-${CPU architecture}-master</code>
to <code>{Github workflow name}-{Emscripten version}-{OS type}-${CPU
architecture}</code>. If <code>actions-cache-folder</code> is defined,
ensure that there are no conflicts with other caches to prevent
issues.</p>
<h1>Changelog</h1>
<ul>
<li>Add option to override cache key naming scheme (<a
href="https://redirect.github.com/mymindstorm/setup-emsdk/issues/20">#20</a>)</li>
<li>Add workflow name to cache key naming scheme (<a
href="https://redirect.github.com/mymindstorm/setup-emsdk/issues/20">#20</a>)</li>
<li>Updated dependencies to latest versions</li>
</ul>
<h2>Version 13</h2>
<ul>
<li>Updated to Node 20</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6ab9eb1bda"><code>6ab9eb1</code></a>
v13 -&gt; v14</li>
<li><a
href="bb630c3bf4"><code>bb630c3</code></a>
Update all dependencies to latest versions</li>
<li><a
href="74881103d0"><code>7488110</code></a>
Add workflow ID to cache key and cache key override option (<a
href="https://redirect.github.com/mymindstorm/setup-emsdk/issues/40">#40</a>)</li>
<li><a
href="d233ac12b0"><code>d233ac1</code></a>
v13</li>
<li><a
href="1749b22b40"><code>1749b22</code></a>
npm audit fix + update runtime to node20</li>
<li>See full diff in <a
href="https://github.com/mymindstorm/setup-emsdk/compare/v12...v14">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=mymindstorm/setup-emsdk&package-manager=github_actions&previous-version=12&new-version=14)](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>
2024-11-06 10:45:31 +00:00
Kim Morrison
1e98fd7f2d feat: add another List.find?_eq_some lemma (#5974)
Inspired by https://github.com/leanprover-community/mathlib4/pull/18593
2024-11-06 10:02:25 +00:00
Markus Himmel
76d32cbd2a chore: exclude leanruntest_task_test_io for now (#5973)
To be reenabled after investigation.
2024-11-06 09:40:20 +00:00
Kim Morrison
15139b6ef6 feat: relate Array.zipWith/zip/unzip with List versions (#5972) 2024-11-06 09:22:08 +00:00
Sebastian Ullrich
14c3d4b1a6 chore: CI: remove link checker for old manual
It started failing frequently after updating it and we're not actively working on this text anyway
2024-11-06 10:27:25 +01:00
Kim Morrison
910b20fb2c chore: consolidate decide_True and decide_true_eq_true (#5949) 2024-11-06 05:12:25 +00:00
Kim Morrison
4df71ed24f feat: relate Array.isPrefixOf with List.isPrefixOf (#5971) 2024-11-06 02:44:14 +00:00
Kyle Miller
406da78fc6 fix: arg conv tactic misreported number of arguments on error (#5968) 2024-11-06 02:13:24 +00:00
Kim Morrison
5d2bd1e2e4 chore: deprecate Array.split in favour of identical Array.partition (#5970) 2024-11-06 00:37:33 +00:00
Kyle Miller
c31daece6c chore: fix all_goals test, simulate the max rec depth error (#5967) 2024-11-05 20:09:06 +00:00
Markus Himmel
c157ddda11 fix: do not link statically against pthread/dl/rt (#5966) 2024-11-05 18:20:42 +00:00
Henrik Böving
c77b6a2c64 feat: define ISize and basic operations on it (#5961) 2024-11-05 15:08:19 +00:00
dependabot[bot]
c6e4947f4a chore: CI: bump dcarbone/install-jq-action from 1.0.1 to 2.1.0 (#5965)
Bumps
[dcarbone/install-jq-action](https://github.com/dcarbone/install-jq-action)
from 1.0.1 to 2.1.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>v2.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Support running action inside containers by <a
href="https://github.com/TaxBusby"><code>@​TaxBusby</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/10">dcarbone/install-jq-action#10</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/TaxBusby"><code>@​TaxBusby</code></a>
made their first contribution in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/10">dcarbone/install-jq-action#10</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dcarbone/install-jq-action/compare/v2.0.2...v2.1.0">https://github.com/dcarbone/install-jq-action/compare/v2.0.2...v2.1.0</a></p>
<h2>v2.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>use curl instead of wget to avoid download failure on macOS by <a
href="https://github.com/vaidyakhil"><code>@​vaidyakhil</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/8">dcarbone/install-jq-action#8</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/vaidyakhil"><code>@​vaidyakhil</code></a> made
their first contribution in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/8">dcarbone/install-jq-action#8</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dcarbone/install-jq-action/compare/v2.0.1...v2.0.2">https://github.com/dcarbone/install-jq-action/compare/v2.0.1...v2.0.2</a></p>
<h2>v2.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>using macos as dl link os prefix in lieu of osx by <a
href="https://github.com/dcarbone"><code>@​dcarbone</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/7">dcarbone/install-jq-action#7</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dcarbone/install-jq-action/compare/v2.0.0...v2.0.1">https://github.com/dcarbone/install-jq-action/compare/v2.0.0...v2.0.1</a></p>
<h2>v2.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>quick &amp; dirty 1.7 support by <a
href="https://github.com/dcarbone"><code>@​dcarbone</code></a> in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/4">dcarbone/install-jq-action#4</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/dcarbone"><code>@​dcarbone</code></a>
made their first contribution in <a
href="https://redirect.github.com/dcarbone/install-jq-action/pull/4">dcarbone/install-jq-action#4</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dcarbone/install-jq-action/compare/v1.0.1...v2.0.0">https://github.com/dcarbone/install-jq-action/compare/v1.0.1...v2.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="8867ddb478"><code>8867ddb</code></a>
remove windows gubbins from container tests</li>
<li><a
href="945d84920f"><code>945d849</code></a>
Support running action inside containers (<a
href="https://redirect.github.com/dcarbone/install-jq-action/issues/10">#10</a>)</li>
<li><a
href="1090b8bd11"><code>1090b8b</code></a>
use curl instead of wget to fix failure on macOS runners (<a
href="https://redirect.github.com/dcarbone/install-jq-action/issues/8">#8</a>)</li>
<li><a
href="ff922c75b7"><code>ff922c7</code></a>
Update example-windows.yaml</li>
<li><a
href="7f4d6f4833"><code>7f4d6f4</code></a>
Update example-macos.yaml</li>
<li><a
href="bfb9fa8e7d"><code>bfb9fa8</code></a>
Update example-linux.yaml</li>
<li><a
href="c1548c666d"><code>c1548c6</code></a>
using macos as dl link os prefix in lieu of osx (<a
href="https://redirect.github.com/dcarbone/install-jq-action/issues/7">#7</a>)</li>
<li><a
href="f07422da1e"><code>f07422d</code></a>
fixing version</li>
<li><a
href="183bc8df0e"><code>183bc8d</code></a>
trying without stupid</li>
<li><a
href="f6b58bacfe"><code>f6b58ba</code></a>
its late.</li>
<li>Additional commits viewable in <a
href="https://github.com/dcarbone/install-jq-action/compare/v1.0.1...v2.1.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=1.0.1&new-version=2.1.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>
2024-11-05 11:23:59 +00:00
dependabot[bot]
01814185a6 chore: CI: bump dawidd6/action-download-artifact from 2 to 6 (#5964)
Bumps
[dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
from 2 to 6.
<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>v6</h2>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v5...v6">https://github.com/dawidd6/action-download-artifact/compare/v5...v6</a></p>
<h2>v5</h2>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v4...v5">https://github.com/dawidd6/action-download-artifact/compare/v4...v5</a></p>
<h2>v4</h2>
<h2>What's Changed</h2>
<ul>
<li><strong>VERSIONING CHANGE</strong>: now there will only be major
releases of this action, e.g. v5, v6 and so on</li>
<li>build(deps): bump undici from 5.28.3 to 5.28.4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/284">dawidd6/action-download-artifact#284</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.4 to
2.1.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/285">dawidd6/action-download-artifact#285</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.5 to
2.1.7 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/287">dawidd6/action-download-artifact#287</a></li>
<li>build(deps): bump adm-zip from 0.5.12 to 0.5.13 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/289">dawidd6/action-download-artifact#289</a></li>
<li>Set allow_forks to false by default by <a
href="https://github.com/timweri"><code>@​timweri</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/290">dawidd6/action-download-artifact#290</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/timweri"><code>@​timweri</code></a> made
their first contribution in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/290">dawidd6/action-download-artifact#290</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v3...v4">https://github.com/dawidd6/action-download-artifact/compare/v3...v4</a></p>
<h2>v3.1.4</h2>
<h2>What's Changed</h2>
<ul>
<li>build(deps): bump adm-zip from 0.5.10 to 0.5.12 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/282">dawidd6/action-download-artifact#282</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.2 to
2.1.4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/280">dawidd6/action-download-artifact#280</a></li>
<li>fix: accept expired artifacts with documentation url by <a
href="https://github.com/wdconinc"><code>@​wdconinc</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/283">dawidd6/action-download-artifact#283</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/wdconinc"><code>@​wdconinc</code></a>
made their first contribution in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/283">dawidd6/action-download-artifact#283</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v3...v3.1.4">https://github.com/dawidd6/action-download-artifact/compare/v3...v3.1.4</a></p>
<h2>v3.1.3</h2>
<h2>What's Changed</h2>
<ul>
<li>node_modules: upgrade by <a
href="https://github.com/dawidd6"><code>@​dawidd6</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/276">dawidd6/action-download-artifact#276</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.1 to
2.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/277">dawidd6/action-download-artifact#277</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v3.1.2...v3.1.3">https://github.com/dawidd6/action-download-artifact/compare/v3.1.2...v3.1.3</a></p>
<h2>v3.1.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Read workflow_search input as a boolean by <a
href="https://github.com/klutchell"><code>@​klutchell</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/273">dawidd6/action-download-artifact#273</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/klutchell"><code>@​klutchell</code></a>
made their first contribution in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/273">dawidd6/action-download-artifact#273</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v3.1.1...v3.1.2">https://github.com/dawidd6/action-download-artifact/compare/v3.1.1...v3.1.2</a></p>
<h2>v3.1.1</h2>
<h2>What's Changed</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bf251b5aa9"><code>bf251b5</code></a>
node_modules: upgrade</li>
<li><a
href="93c6296611"><code>93c6296</code></a>
README: v5</li>
<li><a
href="deb3bb8325"><code>deb3bb8</code></a>
node_modules: upgrade</li>
<li><a
href="1d93f37db2"><code>1d93f37</code></a>
README: v4</li>
<li><a
href="854e2de939"><code>854e2de</code></a>
Set allow_forks to false by default (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/290">#290</a>)</li>
<li><a
href="436c9d3774"><code>436c9d3</code></a>
build(deps): bump adm-zip from 0.5.12 to 0.5.13 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/289">#289</a>)</li>
<li><a
href="14040524bb"><code>1404052</code></a>
build(deps): bump <code>@​actions/artifact</code> from 2.1.5 to 2.1.7
(<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/287">#287</a>)</li>
<li><a
href="8a9be734dc"><code>8a9be73</code></a>
build(deps): bump <code>@​actions/artifact</code> from 2.1.4 to 2.1.5
(<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/285">#285</a>)</li>
<li><a
href="df593bbd04"><code>df593bb</code></a>
build(deps): bump undici from 5.28.3 to 5.28.4 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/284">#284</a>)</li>
<li><a
href="09f2f74827"><code>09f2f74</code></a>
fix: accept expired artifacts with documentation url (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/283">#283</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/dawidd6/action-download-artifact/compare/v2...v6">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=2&new-version=6)](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>
2024-11-05 11:12:20 +00:00
dependabot[bot]
47d0060934 chore: CI: bump actions/github-script from 6 to 7 (#5962)
Bumps [actions/github-script](https://github.com/actions/github-script)
from 6 to 7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/github-script/releases">actions/github-script's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Add base-url option by <a
href="https://github.com/robandpdx"><code>@​robandpdx</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/429">actions/github-script#429</a></li>
<li>Expose async-function argument type by <a
href="https://github.com/viktorlott"><code>@​viktorlott</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/402">actions/github-script#402</a>,
see for details <a
href="https://github.com/actions/github-script#use-scripts-with-jsdoc-support">https://github.com/actions/github-script#use-scripts-with-jsdoc-support</a></li>
<li>Update dependencies and use Node 20 by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/425">actions/github-script#425</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/navarroaxel"><code>@​navarroaxel</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/285">actions/github-script#285</a></li>
<li><a href="https://github.com/robandpdx"><code>@​robandpdx</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/429">actions/github-script#429</a></li>
<li><a
href="https://github.com/viktorlott"><code>@​viktorlott</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/402">actions/github-script#402</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/github-script/compare/v6.4.1...v7.0.0">https://github.com/actions/github-script/compare/v6.4.1...v7.0.0</a></p>
<h2>v6.4.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Add <code>@​octokit/plugin-request-log</code>, to produce debug
output for requests by <a
href="https://github.com/mjpieters"><code>@​mjpieters</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/358">actions/github-script#358</a></li>
<li>fix input handling by <a
href="https://github.com/mjpieters"><code>@​mjpieters</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/357">actions/github-script#357</a></li>
<li>Remove unused dependencies by <a
href="https://github.com/mjpieters"><code>@​mjpieters</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/356">actions/github-script#356</a></li>
<li>Default debug to current runner debug state by <a
href="https://github.com/mjpieters"><code>@​mjpieters</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/363">actions/github-script#363</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/mjpieters"><code>@​mjpieters</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/358">actions/github-script#358</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/github-script/compare/v6.4.0...v6.4.1">https://github.com/actions/github-script/compare/v6.4.0...v6.4.1</a></p>
<h2>v6.4.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump json5 from 2.1.3 to 2.2.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/319">actions/github-script#319</a></li>
<li>Bump minimatch from 3.0.4 to 3.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/320">actions/github-script#320</a></li>
<li>Add node-fetch by <a
href="https://github.com/danmichaelo"><code>@​danmichaelo</code></a> in
<a
href="https://redirect.github.com/actions/github-script/pull/321">actions/github-script#321</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/jongwooo"><code>@​jongwooo</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/313">actions/github-script#313</a></li>
<li><a
href="https://github.com/austinvazquez"><code>@​austinvazquez</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/306">actions/github-script#306</a></li>
<li><a
href="https://github.com/danmichaelo"><code>@​danmichaelo</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/321">actions/github-script#321</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/github-script/compare/v6.3.3...v6.4.0">https://github.com/actions/github-script/compare/v6.3.3...v6.4.0</a></p>
<h2>v6.3.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Update <code>@actions/glob</code> to 0.3.0 by <a
href="https://github.com/nineinchnick"><code>@​nineinchnick</code></a>
in <a
href="https://redirect.github.com/actions/github-script/pull/279">actions/github-script#279</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/nineinchnick"><code>@​nineinchnick</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/279">actions/github-script#279</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/github-script/compare/v6.3.2...v6.3.3">https://github.com/actions/github-script/compare/v6.3.2...v6.3.3</a></p>
<h2>v6.3.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Update <code>@​actions/core</code> to 1.10.0 by <a
href="https://github.com/rentziass"><code>@​rentziass</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/295">actions/github-script#295</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="60a0d83039"><code>60a0d83</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/github-script/issues/440">#440</a>
from actions/joshmgross/v7.0.1</li>
<li><a
href="b7fb2001b4"><code>b7fb200</code></a>
Update version to 7.0.1</li>
<li><a
href="12e22ed06b"><code>12e22ed</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/github-script/issues/439">#439</a>
from actions/joshmgross/avoid-setting-base-url</li>
<li><a
href="d319f8f5b5"><code>d319f8f</code></a>
Avoid setting <code>baseUrl</code> to undefined when input is not
provided</li>
<li><a
href="e69ef5462f"><code>e69ef54</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/github-script/issues/425">#425</a>
from actions/joshmgross/node-20</li>
<li><a
href="ee0914b839"><code>ee0914b</code></a>
Update licenses</li>
<li><a
href="d6fc56f33b"><code>d6fc56f</code></a>
Use <code>@types/node</code> for Node 20</li>
<li><a
href="384d6cf581"><code>384d6cf</code></a>
Fix quotations in tests</li>
<li><a
href="84724927e3"><code>8472492</code></a>
Only validate GraphQL <code>previews</code></li>
<li><a
href="84903f5182"><code>84903f5</code></a>
Remove <code>node-fetch</code> from type</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/github-script/compare/v6...v7">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/github-script&package-manager=github_actions&previous-version=6&new-version=7)](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>
2024-11-05 11:06:39 +00:00
dependabot[bot]
b1c2d851e5 chore: CI: bump lycheeverse/lychee-action from 1.9.0 to 2.0.2 (#5959)
Bumps
[lycheeverse/lychee-action](https://github.com/lycheeverse/lychee-action)
from 1.9.0 to 2.0.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/lycheeverse/lychee-action/releases">lycheeverse/lychee-action's
releases</a>.</em></p>
<blockquote>
<h2>Version 2.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Fix a typos by <a
href="https://github.com/szepeviktor"><code>@​szepeviktor</code></a> in
<a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/257">lycheeverse/lychee-action#257</a></li>
<li>Document and use correct permissions in the GitHub workflows by <a
href="https://github.com/dscho"><code>@​dscho</code></a> in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/258">lycheeverse/lychee-action#258</a></li>
<li>Add security policy by <a
href="https://github.com/mondeja"><code>@​mondeja</code></a> in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/259">lycheeverse/lychee-action#259</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/szepeviktor"><code>@​szepeviktor</code></a>
made their first contribution in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/257">lycheeverse/lychee-action#257</a></li>
<li><a href="https://github.com/mondeja"><code>@​mondeja</code></a> made
their first contribution in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/259">lycheeverse/lychee-action#259</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lycheeverse/lychee-action/compare/v2...v2.0.2">https://github.com/lycheeverse/lychee-action/compare/v2...v2.0.2</a></p>
<h2>Version 2.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Don't remove the lychee config file by <a
href="https://github.com/dmathieu"><code>@​dmathieu</code></a> in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/255">lycheeverse/lychee-action#255</a></li>
<li>Bump lycheeverse/lychee-action from 1 to 2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/252">lycheeverse/lychee-action#252</a></li>
<li>Fix variable name in docs by <a
href="https://github.com/kdeldycke"><code>@​kdeldycke</code></a> in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/253">lycheeverse/lychee-action#253</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/dmathieu"><code>@​dmathieu</code></a>
made their first contribution in <a
href="https://redirect.github.com/lycheeverse/lychee-action/pull/255">lycheeverse/lychee-action#255</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lycheeverse/lychee-action/compare/v2...v2.0.1">https://github.com/lycheeverse/lychee-action/compare/v2...v2.0.1</a></p>
<h2>Version 2.0.0</h2>
<h2>Breaking Changes</h2>
<p><strong>Note:</strong> This release improves the action's robustness
by changing default behaviors. Changes are only required if you want to
opt out of the new failure conditions. Most users won't need to modify
their existing configurations.</p>
<h3>Fail pipeline on error by default</h3>
<p>We've changed the default behavior: pipelines will now fail on broken
links automatically. This addresses user feedback that not failing on
broken links was unexpected (see [issue <a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/71">#71</a>](<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/71">lycheeverse/lychee-action#71</a>)).</p>
<p><strong>What you need to do:</strong></p>
<ul>
<li>Update to version 2 of this action to apply this change.</li>
<li>Users of the <code>lychee-action@master</code> branch don't need to
make any changes, as <code>fail: true</code> has been the default there
for a while.</li>
<li>If you prefer the old behavior, explicitly set <code>fail</code> to
<code>false</code> when updating:</li>
</ul>
<pre lang="yaml"><code>- name: Link Checker
  id: lychee
  uses: lycheeverse/lychee-action@v2
  with:
    fail: false  # Don't fail action on broken links
</code></pre>
<h3>Fail pipeline if no links were found</h3>
<p>Similar to the above change, we now fail the pipeline if no links are
found during a run. This helps warn users about potential configuration
issues.</p>
<p><strong>What you need to do:</strong></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7cd0af4c74"><code>7cd0af4</code></a>
Merge commit from fork</li>
<li><a
href="8ad54d3568"><code>8ad54d3</code></a>
fix link</li>
<li><a
href="762333c189"><code>762333c</code></a>
Create SECURITY.md (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/259">#259</a>)</li>
<li><a
href="71a38a3bd7"><code>71a38a3</code></a>
Document and use correct permissions in the GitHub workflows (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/258">#258</a>)</li>
<li><a
href="f141760066"><code>f141760</code></a>
Fix a typos (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/257">#257</a>)</li>
<li><a
href="2bb232618b"><code>2bb2326</code></a>
don't remove the lychee config file (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/255">#255</a>)</li>
<li><a
href="731bf1a2af"><code>731bf1a</code></a>
Fix variable name (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/253">#253</a>)</li>
<li><a
href="e360f3c891"><code>e360f3c</code></a>
Bump lycheeverse/lychee-action from 1 to 2 (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/252">#252</a>)</li>
<li><a
href="f87f0a6299"><code>f87f0a6</code></a>
Update version to <code>lycheeverse/lychee-action@v2</code> in docs</li>
<li><a
href="7da8ec1fc4"><code>7da8ec1</code></a>
Test latest lychee version tag (<a
href="https://redirect.github.com/lycheeverse/lychee-action/issues/236">#236</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/lycheeverse/lychee-action/compare/v1.9.0...v2.0.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=lycheeverse/lychee-action&package-manager=github_actions&previous-version=1.9.0&new-version=2.0.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>
Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2024-11-05 10:41:16 +00:00
Sebastian Ullrich
970dc6f7aa chore: CI: give Linux Debug unlimited test stack size (#5953) 2024-11-05 10:06:53 +00:00
dependabot[bot]
8e2f92607f chore: CI: bump actions/stale from 8 to 9 (#5958)
Bumps [actions/stale](https://github.com/actions/stale) from 8 to 9.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/stale/releases">actions/stale's
releases</a>.</em></p>
<blockquote>
<h2>v9.0.0</h2>
<h2>Breaking Changes</h2>
<ol>
<li>Action is now stateful: If the action ends because of <a
href="https://github.com/actions/stale#operations-per-run">operations-per-run</a>
then the next run will start from the first unprocessed issue skipping
the issues processed during the previous run(s). The state is reset when
all the issues are processed. This should be considered for scheduling
workflow runs.</li>
<li>Version 9 of this action updated the runtime to Node.js 20. All
scripts are now run with Node.js 20 instead of Node.js 16 and are
affected by any breaking changes between Node.js 16 and 20.</li>
</ol>
<h2>What Else Changed</h2>
<ol>
<li>Performance optimization that removes unnecessary API calls by <a
href="https://github.com/dsame"><code>@​dsame</code></a> <a
href="https://redirect.github.com/actions/stale/pull/1033/">#1033</a>
fixes <a
href="https://redirect.github.com/actions/stale/issues/792">#792</a></li>
<li>Logs displaying current github API rate limit by <a
href="https://github.com/dsame"><code>@​dsame</code></a> <a
href="https://redirect.github.com/actions/stale/pull/1032">#1032</a>
addresses <a
href="https://redirect.github.com/actions/stale/issues/1029">#1029</a></li>
</ol>
<p>For more information, please read the <a
href="https://github.com/actions/stale#readme">action documentation</a>
and its <a href="https://github.com/actions/stale#statefulness">section
about statefulness</a></p>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/jmeridth"><code>@​jmeridth</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/stale/pull/984">actions/stale#984</a></li>
<li><a
href="https://github.com/nikolai-laevskii"><code>@​nikolai-laevskii</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/stale/pull/1020">actions/stale#1020</a></li>
<li><a
href="https://github.com/dusan-trickovic"><code>@​dusan-trickovic</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/stale/pull/1056">actions/stale#1056</a></li>
<li><a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/stale/pull/1110">actions/stale#1110</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/stale/compare/v8...v9.0.0">https://github.com/actions/stale/compare/v8...v9.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/stale/blob/main/CHANGELOG.md">actions/stale's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h1>[7.0.0]</h1>
<p>⚠️ Breaking change ⚠️</p>
<ul>
<li>Allow daysBeforeStale options to be float by <a
href="https://github.com/irega"><code>@​irega</code></a> in <a
href="https://redirect.github.com/actions/stale/pull/841">actions/stale#841</a></li>
<li>Use cache in check-dist.yml by <a
href="https://github.com/jongwooo"><code>@​jongwooo</code></a> in <a
href="https://redirect.github.com/actions/stale/pull/876">actions/stale#876</a></li>
<li>fix print outputs step in existing workflows by <a
href="https://github.com/irega"><code>@​irega</code></a> in <a
href="https://redirect.github.com/actions/stale/pull/859">actions/stale#859</a></li>
<li>Update issue and PR templates, add/delete workflow files by <a
href="https://github.com/IvanZosimov"><code>@​IvanZosimov</code></a> in
<a
href="https://redirect.github.com/actions/stale/pull/880">actions/stale#880</a></li>
<li>Update how stale handles exempt items by <a
href="https://github.com/johnsudol"><code>@​johnsudol</code></a> in <a
href="https://redirect.github.com/actions/stale/pull/874">actions/stale#874</a></li>
</ul>
<h1>[6.0.1]</h1>
<p>Update <code>@​actions/core</code> to v1.10.0 (<a
href="https://redirect.github.com/actions/stale/pull/839">#839</a>)</p>
<h1>[6.0.0]</h1>
<p>⚠️ Breaking change ⚠️</p>
<p>Issues/PRs default <code>close-issue-reason</code> is now
<code>not_planned</code>(<a
href="https://redirect.github.com/actions/stale/issues/789">#789</a>)</p>
<h1>[5.1.0]</h1>
<p><a href="https://redirect.github.com/actions/stale/issues/696">Don't
process stale issues right after they're marked stale</a>
[Add close-issue-reason option]<a
href="https://redirect.github.com/actions/stale/pull/764">#764</a><a
href="https://redirect.github.com/actions/stale/pull/772">#772</a>
Various dependabot/dependency updates</p>
<h2><a
href="https://github.com/actions/stale/compare/v3.0.19...v4.1.0">4.1.0</a>
(2021-07-14)</h2>
<h2>Features</h2>
<ul>
<li><a
href="9912fa74d1">Ability
to exempt draft PRs</a></li>
</ul>
<h2><a
href="https://github.com/actions/stale/compare/v3.0.19...v4.0.0">4.0.0</a>
(2021-07-14)</h2>
<h3>Features</h3>
<ul>
<li><strong>options:</strong> simplify config by removing skip stale
message options (<a
href="https://redirect.github.com/actions/stale/issues/457">#457</a>)
(<a
href="6ec637d238">6ec637d</a>),
closes <a
href="https://redirect.github.com/actions/stale/issues/405">#405</a> <a
href="https://redirect.github.com/actions/stale/issues/455">#455</a></li>
<li><strong>output:</strong> print output parameters (<a
href="https://redirect.github.com/actions/stale/issues/458">#458</a>)
(<a
href="3e6d35b685">3e6d35b</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>dry-run:</strong> forbid mutations in dry-run (<a
href="https://redirect.github.com/actions/stale/issues/500">#500</a>)
(<a
href="f1017f33dd">f1017f3</a>),
closes <a
href="https://redirect.github.com/actions/stale/issues/499">#499</a></li>
<li><strong>logs:</strong> coloured logs (<a
href="https://redirect.github.com/actions/stale/issues/465">#465</a>)
(<a
href="5fbbfba142">5fbbfba</a>)</li>
<li><strong>operations:</strong> fail fast the current batch to respect
the operations limit (<a
href="https://redirect.github.com/actions/stale/issues/474">#474</a>)
(<a
href="5f6f311ca6">5f6f311</a>),
closes <a
href="https://redirect.github.com/actions/stale/issues/466">#466</a></li>
<li><strong>label comparison</strong>: make label comparison case
insensitive <a
href="https://redirect.github.com/actions/stale/pull/517">#517</a>,
closes <a
href="https://redirect.github.com/actions/stale/pull/516">#516</a></li>
<li><strong>filtering comments by actor could have strange
behavior</strong>: &quot;stale&quot; comments are now detected based on
if the message is the stale message not <em>who</em> made the comment(<a
href="https://redirect.github.com/actions/stale/pull/519">#519</a>),
fixes <a
href="https://redirect.github.com/actions/stale/pull/441">#441</a>, <a
href="https://redirect.github.com/actions/stale/pull/509">#509</a>, <a
href="https://redirect.github.com/actions/stale/pull/518">#518</a></li>
</ul>
<h3>Breaking Changes</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="28ca103628"><code>28ca103</code></a>
Upgrade Node to v20 (<a
href="https://redirect.github.com/actions/stale/issues/1110">#1110</a>)</li>
<li><a
href="b69b346013"><code>b69b346</code></a>
build(deps-dev): bump <code>@​types/node</code> from 18.16.18 to 20.5.1
(<a
href="https://redirect.github.com/actions/stale/issues/1079">#1079</a>)</li>
<li><a
href="88a6f4f6cb"><code>88a6f4f</code></a>
build(deps-dev): bump typescript from 5.1.3 to 5.2.2 (<a
href="https://redirect.github.com/actions/stale/issues/1083">#1083</a>)</li>
<li><a
href="796531a7b3"><code>796531a</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/stale/issues/1080">#1080</a>
from akv-platform/fix-delete-cache</li>
<li><a
href="8986f6218b"><code>8986f62</code></a>
Don not try to delete cache if it does not exists</li>
<li><a
href="cab99b362b"><code>cab99b3</code></a>
fix typo proceeded/processed</li>
<li><a
href="184e7afe93"><code>184e7af</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/stale/issues/1064">#1064</a>
from actions/dependabot/npm_and_yarn/typescript-esli...</li>
<li><a
href="523885cf3c"><code>523885c</code></a>
chore: update eslint-plugin, parser and eslint-plugin-jest</li>
<li><a
href="2487a1dc2b"><code>2487a1d</code></a>
build(deps-dev): bump
<code>@​typescript-eslint/eslint-plugin</code></li>
<li><a
href="60c722ee97"><code>60c722e</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/stale/issues/1063">#1063</a>
from actions/dependabot/npm_and_yarn/jest-29.6.2</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/stale/compare/v8...v9">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/stale&package-manager=github_actions&previous-version=8&new-version=9)](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>
2024-11-05 09:53:55 +00:00
dependabot[bot]
ee1fa6eeb7 chore: CI: bump raven-actions/actionlint from 1 to 2 (#5957)
Bumps
[raven-actions/actionlint](https://github.com/raven-actions/actionlint)
from 1 to 2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/raven-actions/actionlint/releases">raven-actions/actionlint's
releases</a>.</em></p>
<blockquote>
<h2>v2.0.0</h2>
<h2>🔄️ What's Changed</h2>
<ul>
<li>node20 support</li>
<li>ci(linter): add workflow permissions <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/24">#24</a>)</li>
<li>ci(deps): Bump actions/cache from 3 to 4 <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/20">#20</a>)</li>
</ul>
<h2>🚀 Features</h2>
<ul>
<li>feat: switch to pipx &amp; add github-token <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/23">#23</a>)</li>
</ul>
<h2>👥 Contributors</h2>
<p><a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>,
<a href="https://github.com/dependabot"><code>@​dependabot</code></a>
and <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]</p>
<p>See details of all code changes: <a
href="https://github.com/raven-actions/actionlint/compare/v1.0.3...v2.0.0">https://github.com/raven-actions/actionlint/compare/v1.0.3...v2.0.0</a>
since previous release.</p>
<h2>v1.0.3</h2>
<h2>🔄️ What's Changed</h2>
<ul>
<li>chore: yamllint config and files lint <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/18">#18</a>)</li>
<li>⬆️ github-actions(deps): Bump actions/github-script from 6 to 7 <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/17">#17</a>)</li>
<li>⬆️ github-actions(deps): bump actions/checkout from 3 to 4 <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/12">#12</a>)</li>
</ul>
<h2>🚀 Features</h2>
<ul>
<li>Make yamllint happy <a
href="https://github.com/bhundven"><code>@​bhundven</code></a> (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/16">#16</a>)</li>
<li>Fix debian install shellcheck <a
href="https://github.com/bhundven"><code>@​bhundven</code></a> (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/15">#15</a>)</li>
</ul>
<h2>🐛 Bug Fixes</h2>
<ul>
<li>fix: user flags parser <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/19">#19</a>)</li>
<li>Fix debian install shellcheck <a
href="https://github.com/bhundven"><code>@​bhundven</code></a> (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/15">#15</a>)</li>
</ul>
<h2>👥 Contributors</h2>
<p><a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>,
<a href="https://github.com/bhundven"><code>@​bhundven</code></a>, <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> and
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]</p>
<p>See details of all code changes: <a
href="https://github.com/raven-actions/actionlint/compare/v1.0.2...v1.0.3">https://github.com/raven-actions/actionlint/compare/v1.0.2...v1.0.3</a>
since previous release.</p>
<h2>v1.0.2</h2>
<h2>🔄️ What's Changed</h2>
<ul>
<li> feat(inputs): group-result <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/10">#10</a>)</li>
<li>👷 chore(github): ci adjustments <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/9">#9</a>)</li>
<li>👷 refactor(ci): change to debug action <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/7">#7</a>)</li>
<li>📝 chore: minor docs and CI adjustments <a
href="https://github.com/DariuszPorowski"><code>@​DariuszPorowski</code></a>
(<a
href="https://redirect.github.com/raven-actions/actionlint/issues/6">#6</a>)</li>
</ul>
<h2>👥 Contributors</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="01fce4f43a"><code>01fce4f</code></a>
ci(linter): add workflow permissions (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/24">#24</a>)</li>
<li><a
href="a30be5376b"><code>a30be53</code></a>
feat: switch to pipx &amp; add github-token (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/23">#23</a>)</li>
<li><a
href="ea4eb57846"><code>ea4eb57</code></a>
ci(deps): Bump actions/cache from 3 to 4 (<a
href="https://redirect.github.com/raven-actions/actionlint/issues/20">#20</a>)</li>
<li>See full diff in <a
href="https://github.com/raven-actions/actionlint/compare/v1...v2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=raven-actions/actionlint&package-manager=github_actions&previous-version=1&new-version=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>
2024-11-05 09:49:23 +00:00
dependabot[bot]
9d2a017704 chore: CI: bump softprops/action-gh-release from 1 to 2 (#5955)
Bumps
[softprops/action-gh-release](https://github.com/softprops/action-gh-release)
from 1 to 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.0.0</h2>
<ul>
<li>update actions.yml declaration to node20 to address warnings</li>
</ul>
</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>0.1.12</h2>
<ul>
<li>fix bug leading to empty strings subsituted for inputs users don't
provide breaking api calls <a
href="https://redirect.github.com/softprops/action-gh-release/pull/144">#144</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e7a8f85e1c"><code>e7a8f85</code></a>
chore: release 2.0.9</li>
<li><a
href="04afa1392e"><code>04afa13</code></a>
chore(deps): bump actions/setup-node from 4.0.4 to 4.1.0 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/535">#535</a>)</li>
<li><a
href="894468a03c"><code>894468a</code></a>
chore(deps): bump actions/checkout from 4.2.1 to 4.2.2 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/534">#534</a>)</li>
<li><a
href="3bd23aa9ec"><code>3bd23aa</code></a>
chore(deps): bump <code>@​types/node</code> from 22.7.5 to 22.8.2 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/533">#533</a>)</li>
<li><a
href="21eb2f9554"><code>21eb2f9</code></a>
chore(deps): bump <code>@​types/jest</code> from 29.5.13 to 29.5.14 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/532">#532</a>)</li>
<li><a
href="cd8b57e572"><code>cd8b57e</code></a>
remove unused imports (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/521">#521</a>)</li>
<li><a
href="820a5adc43"><code>820a5ad</code></a>
chore(deps): bump actions/checkout from 4.2.0 to 4.2.1 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/522">#522</a>)</li>
<li><a
href="9d04f90cd8"><code>9d04f90</code></a>
chore(deps): bump <code>@​octokit/plugin-throttling</code> from 9.3.1 to
9.3.2 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/523">#523</a>)</li>
<li><a
href="aaf1d5f6d5"><code>aaf1d5f</code></a>
chore(deps): bump <code>@​actions/core</code> from 1.10.1 to 1.11.1 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/524">#524</a>)</li>
<li><a
href="7d33a7ecc3"><code>7d33a7e</code></a>
chore(deps): bump <code>@​types/node</code> from 22.5.5 to 22.7.5 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/525">#525</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/softprops/action-gh-release/compare/v1...v2">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=1&new-version=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>
2024-11-05 09:40:03 +00:00
dependabot[bot]
574b86c247 chore: CI: bump nwtgck/actions-netlify from 2.0 to 3.0 (#5956)
Bumps
[nwtgck/actions-netlify](https://github.com/nwtgck/actions-netlify) from
2.0 to 3.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/nwtgck/actions-netlify/releases">nwtgck/actions-netlify's
releases</a>.</em></p>
<blockquote>
<h2>v3.0.0</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
<li>Updates the default runtime to node20</li>
</ul>
<h2>v2.1.0</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
</ul>
<h3>Added</h3>
<ul>
<li>Add &quot;enable-github-deployment&quot; input <a
href="https://redirect.github.com/nwtgck/actions-netlify/pull/901">#901</a>
by <a href="https://github.com/a-tokyo"><code>@​a-tokyo</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/nwtgck/actions-netlify/blob/develop/CHANGELOG.md">nwtgck/actions-netlify's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<p>All notable changes to this project will be documented in this
file.</p>
<p>The format is based on <a
href="https://keepachangelog.com/en/1.0.0/">Keep a Changelog</a></p>
<h2>[Unreleased]</h2>
<h2>[3.0.0] - 2024-03-10</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
<li>Updates the default runtime to node20</li>
</ul>
<h2>[2.1.0] - 2023-08-18</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
</ul>
<h3>Added</h3>
<ul>
<li>Add &quot;enable-github-deployment&quot; input <a
href="https://redirect.github.com/nwtgck/actions-netlify/pull/901">#901</a>
by <a href="https://github.com/a-tokyo"><code>@​a-tokyo</code></a></li>
</ul>
<h2>[2.0.0] - 2022-12-08</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
<li>Updates the default runtime to node16</li>
</ul>
<h2>[1.2.4] - 2022-10-14</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
</ul>
<h2>[1.2.3] - 2021-12-20</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
</ul>
<h2>[1.2.2] - 2021-05-08</h2>
<h3>Fixed</h3>
<ul>
<li>Fix GitHub deployment description</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
</ul>
<h2>[1.2.1] - 2021-05-05</h2>
<h3>Added</h3>
<ul>
<li>Add &quot;fails-without-credentials&quot; input to fail if the
credentials not provided <a
href="https://redirect.github.com/nwtgck/actions-netlify/pull/532">#532</a></li>
</ul>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
</ul>
<h2>[1.2.0] - 2021-04-29</h2>
<h3>Changed</h3>
<ul>
<li>Update dependencies</li>
<li>(breaking change for <code>overwrites-pull-request-comment:
true</code>): Support multiple app deploys in a single PR <a
href="https://redirect.github.com/nwtgck/actions-netlify/pull/484">#484</a>
by <a
href="https://github.com/kaisermann"><code>@​kaisermann</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="4cbaf4c08f"><code>4cbaf4c</code></a>
Merge branch 'release/3.0.0'</li>
<li><a
href="6b45669baf"><code>6b45669</code></a>
bump: 3.0.0</li>
<li><a
href="8d5d80bf73"><code>8d5d80b</code></a>
Merge pull request <a
href="https://redirect.github.com/nwtgck/actions-netlify/issues/1151">#1151</a>
from nwtgck/actions-build/nwtgck-dependabot/npm_and_...</li>
<li><a
href="85c2e8e35a"><code>85c2e8e</code></a>
build</li>
<li><a
href="ea3c314fcd"><code>ea3c314</code></a>
Build(deps): bump <code>@​actions/github</code> from 5.1.1 to 6.0.0</li>
<li><a
href="333815eadd"><code>333815e</code></a>
updates the default runtime to node20</li>
<li><a
href="06de7de77b"><code>06de7de</code></a>
Build(deps-dev): bump <code>@​vercel/ncc</code> from 0.36.1 to 0.38.1
(<a
href="https://redirect.github.com/nwtgck/actions-netlify/issues/1121">#1121</a>)</li>
<li><a
href="a7f64ad4e2"><code>a7f64ad</code></a>
deps: update</li>
<li><a
href="fee801f039"><code>fee801f</code></a>
Build(deps): bump actions/setup-node from 3 to 4 (<a
href="https://redirect.github.com/nwtgck/actions-netlify/issues/1124">#1124</a>)</li>
<li><a
href="e4998d22a0"><code>e4998d2</code></a>
README.md, sample workflow: bump to latest action versions (<a
href="https://redirect.github.com/nwtgck/actions-netlify/issues/1149">#1149</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/nwtgck/actions-netlify/compare/v2.0...v3.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=nwtgck/actions-netlify&package-manager=github_actions&previous-version=2.0&new-version=3.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>
2024-11-05 09:38:06 +00:00
Sebastian Ullrich
75602f7c29 chore: CI: adjust Dependabot prefix 2024-11-05 10:31:37 +01:00
Sebastian Ullrich
0fd90c1283 chore: CI: check for GitHub Actions updates once per month (#5954) 2024-11-05 10:20:23 +01:00
Kim Morrison
128b049904 feat: relate Array.eraseIdx with List.eraseIdx (#5952) 2024-11-05 06:13:29 +00:00
Kim Morrison
0e3f26e6df feat: relate Array.takeWhile with List.takeWhile (#5950) 2024-11-05 05:05:53 +00:00
Kim Morrison
1148e6e142 chore: remove @[simp] from BitVec.ofFin_sub and sub_ofFin (#5951)
Unused, and hurts confluence.
2024-11-05 04:56:21 +00:00
Violeta Hernández
02baaa42ff feat: add Option.or_some' (#5926)
`o.or (some a) = o.getD a`.

As discussed on
[Zulip](https://leanprover.zulipchat.com/#narrow/channel/217875-Is-there-code-for-X.3F/topic/a.2Eor.20.28some.20b.29.20.3D.20a.2EgetD.20b/near/472785093).
2024-11-05 01:39:02 +00:00
Violeta Hernández
e573676db1 feat: List.pmap_eq_self (#5927)
This is a `pmap` analog of
[`List.map_id''`](https://leanprover-community.github.io/mathlib4_docs/Init/Data/List/Lemmas.html#List.map_id'').

As discussed on
[Zulip](https://leanprover.zulipchat.com/#narrow/channel/217875-Is-there-code-for-X.3F/topic/.60pmap_eq_self.60/near/472496933).
2024-11-05 01:38:13 +00:00
Kim Morrison
4dab6a108c chore: port release notes for v4.13.0 to master (#5947) 2024-11-05 01:34:52 +00:00
Kyle Miller
a4d521cf96 fix: make all_goals admit goals on failure (#5934)
New behavior: when in recovery mode, if any tactic fails in `all_goals`
then the metacontext is restored and all goals are admitted.

Without this, it can leave partially-solved metavariables and incomplete
goal lists.
2024-11-04 21:12:59 +00:00
Mac Malone
99070bf304 feat: update toolchain on lake update (#5684)
Lake will now update a package's `lean-toolchain` file on `lake update`
if it finds the package's direct dependencies use a newer compatible
toolchain. To skip this step, use the `--keep-toolchain` CLI option.

Closes #2582. Closes #2752. Closes #5615.

### Toolchain update details

To determine "newest compatible" toolchain, Lake parses the toolchain
listed in the packages' `lean-toolchain` files into four categories:
release , nightly, PR, and other. For newness, release toolchains are
compared by semantic version (e.g., `"v4.4.0" < "v4.8.0"` and
`"v4.6.0-rc1" < "v4.6.0"`) and nightlies are compared by date (e.g.,
`"nightly-2024-01-10" < "nightly-2014-10-01"`). All other toolchain
types and mixtures are incompatible. If there is not a single newest
toolchain, Lake will print a warning and continue updating without
changing the toolchain.

If Lake does find a new toolchain, Lake updates the workspace's
`lean-toolchain` file accordingly and restarts the update process on the
new Lake. If Elan is detected, it will spawn the new Lake process via
`elan run` with the same arguments Lake was initially run with. If Elan
is missing, it will prompt the user to restart Lake manually and exit
with a special error code (4).

### Other changes

To implement this new logic, various other refactors were needed. Here
are some key highlights:

* Logs emitted during package and workspace loading are now eagerly
printed.
* The Elan executable used by Lake is now configurable by the `ELAN`
environment variable.
* The `--lean` CLI option was removed. Use the `LEAN` environment
variable instead.
* `Package.deps` / `Package.opaqueDeps` have been removed. Use
`findPackage?` with a dependency's name instead.
* The dependency resolver now uses a pure breadth-first traversal to
resolve dependencies. It also resolves dependencies in reverse order,
which is done for consistency with targets. Latter targets shadow
earlier ones and latter dependencies take precedence over earlier ones.
**These changes mean the order of dependencies in a Lake manifest will
change after the first `lake update` on this version of Lake.**
2024-11-04 14:31:40 +00:00
Henrik Böving
93dd6f2b36 feat: add Int16/Int32/Int64 (#5885)
This adds all fixed width integers with the exception of `ssize_t` so
the code is quick to review as everything just behaves the same.
2024-11-04 13:18:05 +00:00
Henrik Böving
c61ced3f15 feat: introduce synthetic atoms in bv_decide (#5942)
This introduces a notion of synthetic atoms into `bv_decide`'s
reflection framework. An atom can be declared synthetic if its behavior
is fully specified by additional lemmas that are added in the process of
creating it. This is for example useful in the code that handles `if` as
the entire `if` block is abstracted as an atom and then two lemmas to
describe either branch are added. Previously this had the effect of
creating error messages about potentially unsound counterexamples, now
the synthetic atoms get filtered from the counter example generation.
2024-11-04 10:14:51 +00:00
Kim Morrison
c779f3a039 feat: List.mapFinIdx, lemmas, relate to Array version (#5941) 2024-11-04 05:29:41 +00:00
Kim Morrison
fc17468f78 chore: upstream List.ofFn and relate to Array.ofFn (#5938) 2024-11-04 01:35:29 +00:00
Kim Morrison
8b7e3b8942 chore: upstream lemmas about Fin.foldX (#5937) 2024-11-04 00:52:59 +00:00
Kim Morrison
9129990833 chore: begin development cycle for v4.15 (#5936) 2024-11-03 23:25:03 +00:00
Kyle Miller
1659f3bfe2 fix: .. in patterns should not make use of optparams or autoparams (#5933)
In patterns, ellipsis should always fill in each remaining argument as
an implicit argument, even if it is an optparam or autoparam. This
prevents examples such as the one in #4555 from failing:
```lean
match e with
| .internal .. => sorry
| .error .. => sorry
```
The `internal` constructor has an optparam (`| internal (id :
InternalExceptionId) (extra : KVMap := {})`).

We may consider having ellipsis suppress optparams and autoparams in
general. We avoid doing so for now since it's possible to opt-out of
them individually (for example with `.internal (extra := _) ..`) but
it's not possible to opt-in, and it is plausible that `..` with
optparams is useful in contexts such as the `refine` tactic. With
patterns however, it is hard to imagine a use case that offsets the
inconvenience of optparams being eagerly supplied.

Closes #4555
2024-11-03 18:40:21 +00:00
Lean stage0 autoupdater
87d3f1f2c8 chore: update stage0 2024-11-03 17:21:54 +00:00
Kyle Miller
b75cc35db2 feat: update omega/solve_by_elim to use new tactic syntax, use new tactic syntax (#5932)
Following up #5928, updates the syntax for `omega` and `solve_by_elim`
and restores the syntax quotations in their implementations.

Following up #5898, uses the new tactic syntax in the library, replacing
all uses of `(config := ...)`.
2024-11-03 16:23:37 +00:00
Jens Petersen
3952689fb1 feat: add --short-version (-V) option to display short version (#5930)
This just adds a `--short-version` (`-V`) option to the lean command,
which is useful for external tooling, etc.

Closes #5929
2024-11-03 15:18:23 +00:00
Lean stage0 autoupdater
cd24e9dad4 chore: update stage0 2024-11-03 07:04:44 +00:00
Kyle Miller
0de925eafc chore: prepare omega and solve_by_elim for new tactic config syntax (#5928)
The tactic elaborators match a too-restrictive syntax for the migration
to the new configuration syntax. This generalizes what they accept, and
the code will return to using quotations after a stage0 update and
syntax change.
2024-11-03 06:20:15 +00:00
Mac Malone
79428827b8 feat: add text option for buildFile* utilities (#5924)
Adds an optional `text` argument to the `fetchFile*` and `buildFile*`
definitions that can be used to hash built files as text files (with
normalized line endings) instead of as binary files (the previous
default).

Separately, this change also significantly expands the documentation in
the `Lake.Build.Trace` module and preforms minor touchups of some build
job signatures.
2024-11-03 00:23:39 +00:00
Kyle Miller
3c15ab3c09 feat: make MapDeclarationExtension tolerate multiple insertions (#5911)
Simplifies the definition of `MapDeclarationExtension` so that it only
contains a `NameMap` without an additional `List (Name × α)`. Uses the
`NameMap`'s natural ordering during export rather than sorting.

This fixes issues from inserting into a `MapDeclarationExtension`
multiple times with the same key. Inside a module it appears that each
insertion overwrites the data, since those queries access the `NameMap`.
But across modules, only the first insertion is accessible, since each
insertion was actually pushed to the front of a `List`.

Mathlib needs this for a documentation extension feature, and [they are
considering a PR with a
workaround](https://github.com/leanprover-community/mathlib4/pull/17043)
that digs into the `MapDeclarationExtension` data structures.
2024-11-02 15:28:34 +00:00
Lean stage0 autoupdater
3f33cd6fcd chore: update stage0 2024-11-01 23:33:27 +00:00
David Thrane Christiansen
1f8d7561fa chore: remove unused deriving handler argument syntax (#5265)
As far as I can tell, the ability to pass a structure instance to a
deriving handler is not actually used in practice. It didn't seem to be
used in the test suite, at least.

Do we want to remove this, or do we want to use and document it? This PR
removes it, but that's not something I feel strongly about - but seeing
if it breaks Mathlib is a useful data point.
2024-11-01 22:41:38 +00:00
Alex
16e5e09ffd feat: better error message for invalid induction alternative name (#5888)
Closes #5887
2024-11-01 21:33:15 +00:00
Kyle Miller
5549e0509f feat: on "type mismatch" errors, expose differences in functions and pi types (#5922)
Example: Normally subtype notation pretty prints as `{ x // x > 0 }`,
but now the difference in domains is exposed:
```lean
example (h : {x : Int // x > 0}) : {x : Nat // x > 0} := h
/-
error: type mismatch
  h
has type
  { x : Int // x > 0 } : Type
but is expected to have type
  { x : Nat // x > 0 } : Type
-/
```
2024-11-01 18:42:14 +00:00
Kyle Miller
c7f5fd9a83 feat: make "type mismatch" error add numeric type ascriptions (#5919)
Example:
```lean
example : 0 = (0 : Nat) := by
  exact Eq.refl (0 : Int)
/-
error: type mismatch
  Eq.refl 0
has type
  (0 : Int) = 0 : Prop
but is expected to have type
  (0 : Nat) = 0 : Prop
-/
```
2024-11-01 16:44:52 +00:00
Henrik Böving
a4057d373e fix: bv_normalize loose mvars (#5918)
`bv_normalize` would just silently drop other goals if called while not
focused on a singular goal, for example:
```lean
theorem mvarid (x y : Bool) (h : x ∨ y) : y ∨ x := by
  cases h
  bv_normalize
  -- we want to write another bv_normalize here but all goals are gone
```
Would make the second subgoal disappear and then throw an error about
meta variables in the kernel.
2024-11-01 15:16:11 +00:00
Sebastian Ullrich
fd08c92060 chore: update src/library/module.cpp after update stage0
Co-authored-by: Eric Wieser <wieser.eric@gmail.com>

Update src/library/module.cpp

Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
2024-11-01 22:48:49 +11:00
Kim Morrison
be6507fe5b chore: update stage0 2024-11-01 22:48:49 +11:00
Sebastian Ullrich
c723ae7f97 chore: CI: build 64-bit platforms consistently with GMP
fix

arm64?

try different fix

`uses_gmp` .olean bit, bump .olean version

add lean_version

make sure to use cache gmp on x86 Linux
2024-11-01 22:48:49 +11:00
Lean stage0 autoupdater
0973ba3e42 chore: update stage0 2024-11-01 03:36:00 +00:00
Kim Morrison
a75a03c077 feat: relate for loops over List with foldlM (#5913)
There are many more lemmas about `foldlM`, so this may be useful for
reasoning about for loops by transforming them into folds.

The transformation includes accounting for monad effects, but does have
a mild performance difference in that short-circuiting on
`ForInStep.done` is replaced by traversing the rest of the list with a
noop.
2024-11-01 02:41:05 +00:00
Kim Morrison
6922832327 chore: minor tweaks to Array lemmas (#5912) 2024-11-01 02:20:16 +00:00
Kyle Miller
f1707117f0 feat: conv arg now can access more arguments (#5894)
Specializes the congr lemma generated for the `arg` conv tactic to only
rewrite the chosen argument. This makes it much more likely that the
chosen argument is able to be accessed.

Lets `arg` access the domain and codomain of pi types via `arg 1` and
`arg 2` in more situations. Upstreams `pi_congr` for this from mathlib.

Adds a negative indexing option, where `arg -2` accesses the
second-to-last argument for example, making the behavior of `lhs`
available to `arg`. This works for `enter` as well.

Other improvement: when there is an error in the `enter [...]` tactic,
individual locations get underlined with the error. The tactic info now
also is like `rw`, so you can see the intermediate conv states.

Closes #5871
2024-11-01 02:12:14 +00:00
Kyle Miller
3b80d1eb1f feat: activate new tactic configuration syntax for most tactics (#5898)
PR #5883 added a new syntax for tactic configuration, and this PR
enables it in most tactics. Example: `simp +contextual`.

There will be followup PRs to modify the remaining ones.

Breaking change: Tactics that are macros for `simp` or other core
tactics need to adapt. The easiest way is to replace `(config)?` with
`optConfig` and then in the syntax quotations replace `$[$cfg]?` by
`$cfg:optConfig`. For tactics that manipulate the configuration, see
`erw` for an example:
```lean
macro "erw" c:optConfig s:rwRuleSeq loc:(location)? : tactic => do
  `(tactic| rw $[$(getConfigItems c)]* (transparency := .default) $s:rwRuleSeq $(loc)?)
```
Configuration options are processed left-to-right, so this forces the
`transparency` to always be `.default`.
2024-11-01 02:08:53 +00:00
Luisa Cicolini
7730ddd1a0 feat: add BitVec.(msb, getMsbD, getLsbD)_(neg, abs) (#5721)
Co-authored-by: Alex Keizer <alex@keizer.dev>
Co-authored-by: Tobias Grosser <github@grosser.es>
Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
Co-authored-by: Kyle Miller <kmill31415@gmail.com>
Co-authored-by: Henrik Böving <hargonix@gmail.com>
Co-authored-by: Tobias Grosser <tobias@grosser.es>
Co-authored-by: Kim Morrison <scott.morrison@gmail.com>
Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
Co-authored-by: Marc Huisinga <mhuisi@protonmail.com>
Co-authored-by: Markus Himmel <markus@lean-fro.org>
Co-authored-by: FR <zhao.yu-yang@foxmail.com>
Co-authored-by: Aaron Tomb <aarontomb@gmail.com>
Co-authored-by: Arthur Adjedj <arthur.adjedj@gmail.com>
Co-authored-by: Yann Herklotz <git@yannherklotz.com>
Co-authored-by: Lean stage0 autoupdater <>
2024-11-01 01:27:34 +00:00
Kim Morrison
e4a2c3d8f0 feat: interim implementation of HashMap.modify/alter (#5880)
These implementations could be made more efficient by promoting them to
primitive operations, but I propose installing these in the meantime to
encourage users to avoid non-linearity problems.
2024-11-01 01:21:21 +00:00
Kim Morrison
c2391c45b9 chore: remove @[simp] from Sum.forall and Sum.exists (#5900) 2024-11-01 01:21:04 +00:00
Kyle Miller
465ed8af46 feat: resolve generalized field notation using all parents (#5770)
* Now `getPathToBaseStructure?` can navigate to all parent structures,
not just through subobjects.
* Adds a "resolution order" for methods. This is the order that
generalized field notation visits parent structures when trying to
resolve names. The algorithm to compute a resolution order is the
commonly used C3 (used for instance by Python). By default we use a
relaxed version of the algorithm that tolerates inconsistencies. Using
`set_option structure.strictResolutionOrder true` makes inconsistent
parent orderings into warnings.
* This makes generalized field notation be able to resolve names for all
parent structures, not just those that are embedded as subobjects.
Closes #3467. (And addresses side note in #1881.)
* Modifies `getAllParentStructures` to return *all* parents. This
improves dot completion in the editor.
2024-10-31 21:04:50 +00:00
Joachim Breitner
008537abbd fix: FunInd: unfold aux definitions more carefully (#5904)
fixes #5903
2024-10-31 18:04:36 +00:00
Kyle Miller
f8242fa965 fix: delta derived instances now have declaration ranges (#5899)
Fixes an issue where go-to definition on such instances does not work.

Reported [on
Zulip](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/mystery.20guest/near/479820367)
2024-10-31 15:40:17 +00:00
Henrik Böving
844e7ae7eb chore: remove native code for UInt8.modn (#5901)
Closes #5818
2024-10-31 12:42:24 +00:00
Kim Morrison
218601009b chore: rename Array.back to back! (#5897) 2024-10-31 09:18:18 +00:00
Kim Morrison
4af93813f2 chore: move @[simp] from back_eq_back? to back_push (#5896) 2024-10-31 08:25:19 +00:00
Kim Morrison
34be25620f feat: LawfulBEq (Array α) ↔ LawfulBEq α (#5895) 2024-10-31 08:00:06 +00:00
Kim Morrison
a826de8a3d chore: remove duplicated ForIn instances (#5892)
I'd previously added an instance from `ForIn'` to `ForIn`, but this then
caused some non-defeq duplication. It seems fine to just remove the
concrete `ForIn` instances in cases where the `ForIn'` instance exists
too. We can even remove a number of type-specific lemmas in favour of
the general ones.
2024-10-31 07:40:09 +00:00
Kyle Miller
0fcee100e7 feat: enable recursive structure command (#5783)
Now that the elaborator supports primitive projections for recursive
inductive types (#5822), enable defining recursive inductive types with
the `structure` command, which was set up in #5842.

Example:
```lean
structure Tree where
  n : Nat
  children : Fin n → Tree

def Tree.size : Tree → Nat
  | {n, children} => Id.run do
    let mut s := 0
    for h : i in [0 : n] do
      s := s + (children ⟨i, h.2⟩).size
    pure s
```

Note for kernel re-implementors: recursive structures are exercising the
kernel feature where primitive projections are valid for one-constructor
inductive types in general, so long as the structure isn't a `Prop` and
doesn't have any non-`Prop` fields, not just ones that are non-indexed
and non-recursive.

Closes #2512
2024-10-31 05:23:12 +00:00
Kyle Miller
03c6e99ef7 fix: bring elaborator in line with kernel for primitive projections (#5822)
The kernel supports primitive projections for all inductive types with
one construtor. The elaborator was assuming primitive projections only
work for "structure-likes", non-recursive inductive types with no
indices.

Enables numeric projection notation for general one-constructor
inductives.

Extracted from #5783.
2024-10-31 03:16:52 +00:00
Lean stage0 autoupdater
0c8d28e9ba chore: update stage0 2024-10-31 02:11:42 +00:00
Kyle Miller
66d68484af fix: make structure parent info persist (#5890)
Modifies the `structureExt` from being a `SimplePersistentEnvExtension`
to a `PersistentEnvExtension`. The simple version contains a `List` of
all added entries, which we do not need since we already have a
`PersistentHashMap` of them in the state. The oversight was that this
`List` contained duplicate entries due to `setStructureParents`
re-adding entries.
2024-10-31 01:22:34 +00:00
Kim Morrison
5c70e5d845 chore: (belatedly) begin development cycle for v4.14.0 (#5889)
This hasn't affected release candidates or stables, but I realised that
I haven't been updating `LEAN_VERSION_MINOR` on `master` the last two
months, so it still says v4.12.0. This advances it to v4.14.0.
2024-10-30 23:48:02 +00:00
Kyle Miller
d4b1be094d feat: adds optConfig syntax for tactic configuration (#5883)
This PR adds a new syntax for tactic and command configurations. It also
updates the elaborator construction command to be able to process this
new syntax.

We do not update core tactics yet. Once tactics switch over to it,
rather than (for example) writing `simp (config := { contextual := true,
maxSteps := 22})`, one can write `simp +contextual (maxSteps := 22)`.
The new syntax is reverse compatible in the sense that `(config := ...)`
still sets the entire configuration.

Note to metaprogrammers: Use `optConfig` instead of `(config)?`. The
elaborator generated by `declare_config_elab` accepts both old and new
configurations. The elaborator has also been written to be tolerant to
null nodes, so adapting to `optConfig` should be as easy as changing
just the syntax for your tactics and deleting `mkOptionalNode`.

Breaking change: The new system is mostly reverse compatible, however
the type of the generated elaborator now lands in `TacticM` to make use
of the current recovery state. Commands that wish to elaborate
configurations should now use `declare_command_config_elab` instead of
`declare_config_elab` to get an elaborator landing in `CommandElabM`.
2024-10-30 23:31:34 +00:00
Kyle Miller
c3cbc92a0c feat: upstream and update #where command (#5065)
This command comes from Lean 3, which I had previously ported and
contributed to Batteries (née Std). In this new version, `#where`
produces actual command Syntax for all features of a top-level scope
(rather than splicing together strings), and it also now reports
included variables.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2024-10-30 18:00:08 +00:00
Joachim Breitner
0d12618539 fix: declareSimpLikeTactic macro to use mkSynthetic (#5838)
this fixes #5597
2024-10-30 14:27:56 +00:00
Henrik Böving
ac80e261bd feat: add embedded constraint substitution to bv_decide (#5886)
This adds the embedded constraint substitution preprocessing pass from
Bitwuzla to `bv_decide`.
It looks for hypotheses of the form `h : x = true` and then attempts to
find occurrences of
`x` within other hypotheses to replace them with true.
2024-10-30 11:43:40 +00:00
Kim Morrison
38c39482f4 chore: add missing deprecation dates (#5884) 2024-10-30 05:37:36 +00:00
Kyle Miller
09802e83cd chore: mention #version in bug report template (#5769) 2024-10-30 02:46:48 +00:00
Alex Keizer
b5bbc57059 feat: prove that intMin is indeed the smallest signed bitvector (#5778) 2024-10-30 02:45:16 +00:00
Mac Malone
4714f84fb9 fix: lake: do not delete path dependencies (#5878)
Fixes a serious issue where Lake would delete path dependencies when
attempting to cleanup a dependency required with an incorrect name.

Closes #5876. Originally part of #5684, but also independently
discovered by François.
2024-10-30 02:31:20 +00:00
Kim Morrison
5e7d02e4ea feat: Hashable (BitVec n) (#5881) 2024-10-30 02:26:18 +00:00
Kim Morrison
5357fd2369 chore: rename List.groupBy to splitBy (#5879)
This makes room for adding a function that returns a HashMap, parallel
to `Array.groupByKey` (which I may also rename to `Array.groupBy`.
2024-10-30 00:56:52 +00:00
えび (ebi_chan)
3450c2a8ac feat: add Nat.log2_two_pow (#5756) 2024-10-29 23:46:17 +00:00
Kyle Miller
95d3b4b58f chore: move MessageData.ofConstName earlier (#5877)
Makes `MessageData.ofConstName` available without needing to import the
pretty printer. Any code making use of `MessageData` can write `m!" ...
{.ofConstName n} ... "` to have the name print with hover information.
More error messages now have hover information.

* Now `.ofConstName` also has a boolean flag to make names print fully
qualified. Default: false.
* Now `.ofConstName` will sanitize names that aren't constants. It is OK
to use it in `"unknown constant '{.ofConstName constName}'"` errors.

Usability note: it is more user-friendly to have "has already been
declared" errors report the fully qualified name. For this, write
`m!"{.ofConstName n true} has already been declared"`.
2024-10-29 21:23:51 +00:00
Kyle Miller
cdbe29b46d feat: accurate binder names in signatures (like in output of #check) (#5827)
An important part of the interface of a function is the parameter names,
for making used of named arguments. This PR makes the parameter names
print in a reliable way. The parameters of the type now appear as
hygienic names if they cannot be used as named arguments.

Modifies the heuristic for how parameters are chosen to appear before or
after the colon. The rule is now that parameters start appearing after
the colon at the first non-dependent non-instance-implicit parameter
that has a name unusable as a named argument. This is a refinement of
#2846.

Fixes the issue where consecutive hygienic names pretty print without a
space separating them, so we now have `(x✝ y✝ : Nat)` rather than `(x✝y✝
: Nat)`.

Breaking change: `Lean.PrettyPrinter.Formatter.pushToken` now takes an
additional boolean `ident` argument, which should be `true` for
identifiers. Used to insert discretionary space between consecutive
identifiers.

Closes #5810
2024-10-29 16:43:11 +00:00
Xin Hao
0d471513c5 fix: init git only not inside git work tree (#5789)
Addresses part of #2758.
2024-10-29 13:37:11 +00:00
Lean stage0 autoupdater
d23a231908 chore: update stage0 2024-10-29 12:02:31 +00:00
Joachim Breitner
6514385bb9 feat: attribute [simp ←] (#5870)
This adds the ability to add the converse direction of a rewrite rule
not just in simp arguments `simp [← thm]`, but also as a global
attribute

```lean
attribute [simp ←] thm
```

This fixes #5828.

This can be undone with `attribute [-simp]`, although note that
`[-simp]` wins and cannot be undone at the moment (#5868).

Like `simp [← thm]` (see #4290), this will do an implicit `attribute
[-simp] thm` if the other direction is already defined.
2024-10-29 11:07:08 +00:00
Lean stage0 autoupdater
4ee44ceb1d chore: update stage0 2024-10-29 00:17:47 +00:00
Kyle Miller
1437033e69 fix: prevent addPPExplicitToExposeDiff from assigning metavariables (#5276)
Type mismatch errors have a nice feature where expressions are annotated
with `pp.explicit` to expose differences via `isDefEq` checking.
However, this procedure has side effects since `isDefEq` may assign
metavariables. This PR wraps the procedure with `withoutModifyingState`
to prevent assignments from escaping.

Assignments can lead to confusing behavior. For example, in the
following a higher-order unification fails, but the difference-finding
procedure unifies metavariables in a naive way, producing a baffling
error message:
```lean
theorem test {f g : Nat → Nat} (n : Nat) (hfg : ∀a, f (g a) = a) :
    f (g n) = n := hfg n

example {g2 : ℕ → ℕ} (n2 : ℕ) : (λx => x * 2) (g2 n2) = n2 := by
  with_reducible refine test n2 ?_
  /-
  type mismatch
    test n2 ?m.648
  has type
    (fun x ↦ x * 2) (g2 n2) = n2 : Prop
  but is expected to have type
    (fun x ↦ x * 2) (g2 n2) = n2 : Prop
  -/
```
With the change, it now says `has type ?m.153 (?m.154 n2) = n2`.

Note: this uses `withoutModifyingState` instead of `withNewMCtxDepth`
because we want to know something about where `isDefEq` failed — we are
trying to simulate a very basic version of `isDefEq` for function
applications, and we want the state at the point of failure to know
which argument is "at fault".
2024-10-28 22:51:41 +00:00
Kyle Miller
b308f2bb55 fix: let simp arguments elaborate with error recovery (#5863)
Modifies `simp` to elaborate all simp arguments without disabling error
recovery. Like in #4177, simp arguments with elaboration errors are not
added to the simp set. Error recovery is still disabled when `simp` is
used in combinators such as `first`.

This enables better term info and features like tab completion when
there are elaboration errors.

Also included is a fix to the `all_goals` and `<;>` tactic combinators.
Recall that `try`/`catch` for the Tactic monad restores the state on
failure. This meant that all messages were being cleared on tactic
failure. The fix is to use `Tactic.tryCatch` instead, which doesn't
restore state.

Part of addressing #3831

Closes #4888
2024-10-28 21:39:03 +00:00
Kyle Miller
9eded87462 fix: remove withoutRecover from apply elaboration (#5862)
The assumptions behind disabling error recovery for the `apply` tactic
no longer seem to hold, since tactic combinators like `first` themselves
disable error recovery when it makes sense.

This addresses part of #3831

Breaking change: `elabTermForApply` no longer uses `withoutRecover`.
Tactics using `elabTermForApply` should evaluate whether it makes sense
to wrap it with `withoutRecover`, which is generally speaking when it's
used to elaborate identifiers.
2024-10-28 21:27:14 +00:00
Kyle Miller
19bebfc22f feat: improved calc error messages (#5719)
Makes the error messages report on RHSs and LHSs that do not match the
expected values when the relations are defeq. If the relations are not
defeq, the error message now no longer mentions the value of the whole
`calc` expression.

Adds a field to `mkCoe` with an optional callback to use to generate
error messages.

Note: it is tempting to try to make use of expected types when
elaborating the `calc` expression, but this runs into issue #2073.

Closes #4318
2024-10-28 20:38:45 +00:00
Henrik Böving
c57d054b87 feat: support all the SMTLIB BitVec divison/remainder operations in bv_decide (#5869) 2024-10-28 16:37:06 +00:00
Luisa Cicolini
2f1dc878e4 feat: add BitVec.(msb, getMsbD)_concat (#5865) 2024-10-28 12:10:02 +00:00
Tobias Grosser
f558402ab8 feat: add BitVec.[zero_ushiftRight|zero_sshiftRight|zero_mul] and cle… (#5858)
…an up BVDecide

- Fix names

  shiftLeft_zero_eq -> shiftLeft_zero
  ushiftRight_zero_eq -> ushiftRight_zero

- Remove duplicate prefixes

  BitVec.mul_zero -> mul_zero
  BitVec.mul_add  -> mul_add

- Adapt BVDecide/Normalize/BitVec by reusing the following functions

  zero_add | add_zero
  and_self
  mul_zero | zero_mul
  shiftLeft_zero | zero_shiftLeft
  sshiftRight_zero | zero_sshiftRight
  ushiftRight_zero | zero_ushiftRight
2024-10-28 08:47:29 +00:00
Kyle Miller
62521f4f2d fix: let congr conv tactic handle "over-applied" functions (#5861)
Adds ability to chain congruence lemmas when a function's arity is less
than the number of supplied arguments. This improves `congr` as well as
all conv tactics implemented using `congr`, like `arg` and `enter`.

(The non-conv `congr` tactic still needs to be fixed.)

Toward #2942.
2024-10-28 07:34:33 +00:00
Kyle Miller
9847923f9b feat: record all structure parents in StructureInfo (#5853)
Followup to #5841. Makes the `structure` command populate the new
`parentInfo` field with all the structures in the `extends` clause.

This will require a stage0 update to fully take effect.

Breaking change: now it's a warning if a structure extends a parent
multiple times.

Breaking change: now `getParentStructures` is `getStructureSubobjects`.
Adds `getStructureParentInfo` for getting all the immediate parents.
Note that the set of subobjects is neither a subset nor a superset of
the immediate parents.

Closes #1881
2024-10-28 01:23:48 +00:00
Kyle Miller
709ea6cdf8 feat: make it possible to use dot notation in m! strings (#5857)
This default instance makes it possible to write things like `m!"the
constant is {.ofConstName n}"`.

Breaking change: This weakly causes terms to have a type of
`MessageData` if their type is otherwise unknown. For example:
* `m!"... {x} ..."` can cause `x` to have type `MessageData`, causing
the `let` definition of `x` to fail to elaborate. Fix: give `x` an
explicit type.
* Arithmetic expressions in `m!` strings may need a type ascription. For
example, if the type of `i` is unknown at the time the arithmetic
expression is elaborated, then `m!"... {i + 1} ..."` can fail saying
that it cannot find an `HAdd Nat Nat MessageData` instance. Two fixes:
either ensure that the type of `i` is known, or add a type ascription to
guide the `MessageData` coercion, like `m!"... {(i + 1 : Nat)} ..."`.
2024-10-27 22:55:29 +00:00
Henrik Böving
8c7f7484f9 feat: if support and more in bv_decide (#5855)
Using the same strategy as #5852 this provides `bv_decide` support for
`Bool` and `BitVec` ifs
this in turn instantly enables support for:
- `sdiv`
- `smod`
- `abs`

and thus closes our last discrepancies to QF_BV!
2024-10-27 08:40:38 +00:00
Kyle Miller
c50f04ace0 feat: add delaborators for <|>, <*>, >>, <*, and *> (#5854)
Closes #5668
2024-10-26 23:49:16 +00:00
Henrik Böving
8b5443eb22 feat: support BitVec.ofBool in bv_decide (#5852)
This is the first step towards fixing the issue of not having mutual
recursion between the `Bool` and `BitVec` fragment of `QF_BV` in
`bv_decide`. This PR adds support for `BitVec.ofBool` by doing the
following:
1. Introduce a new mechanism into the reification engine that allows us
to add additional lemmas to the top level on the fly as we are
traversing the expression tree.
2. If we encounter an expression `BitVec.ofBool boolExpr` we reify
`boolExpr` and then abstract `BitVec.ofBool boolExpr` as some atom `a`
3. We add two lemmas `boolExpr = true -> a = 1#1` and `boolExpr = false
-> a = 0#1`. This mirrors the full behavior of `BitVec.ofBool` and thus
makes our atom `a` correctly interpreted again.

In order to do the reification in step 2 mutual recursion in the
reification engine is required. For this reason I started pulling out
logic from the, now rather large, mutual block into other files and
document the invariants that they assume explicitly.
2024-10-26 19:08:07 +00:00
Luisa Cicolini
08c36e4306 feat: add (msb, getMsbD)_twoPow (#5851) 2024-10-26 17:27:37 +00:00
Joachim Breitner
8f0328b777 fix: deprecations in Init.Data.Array.Basic (#5848) 2024-10-26 10:33:47 +00:00
Joachim Breitner
38490a4ac7 refactor: Predefinition.Structural code cleanup (#5850)
useful bits from the shelved #5849
2024-10-26 10:21:47 +00:00
Kyle Miller
13036655e9 fix: reduce types when constructing default values in structure instance notation (#5844)
A step of expanding structure instances is to determine all the default
values, and part of this is reducing projections that appear in the
default values so that they get replaced with the user-provided values.
Binder types in foralls, lambdas, and lets have to be reduced too.

Closes #2186
2024-10-26 00:45:21 +00:00
Kyle Miller
4068cf00ee chore: remove unnecessary private Inhabited instance (#5846)
Since `partial` inhabitation is stronger in #5821, this private instance
is no longer needed.
2024-10-25 23:31:18 +00:00
Kyle Miller
abe6d5bca7 fix: declaration ranges changed after stage0 update (#5845)
Recently declaration ranges have changed slightly to include attribute
lists. Fixes a test that broke.
2024-10-25 21:38:06 +00:00
Lean stage0 autoupdater
f292184642 chore: update stage0 2024-10-25 20:35:09 +00:00
Kyle Miller
a310488b7f chore: refactor structure command, fixes (#5842)
Refactors the `structure` command to support recursive structures. These
are disabled for now, pending additional elaborator support in #5822.
This refactor is also a step toward `structure` appearing in `mutual`
blocks.

Error reporting is now more precise, and this fixes an issue where
general errors could appear on the last field. Adds "don't know how to
synthesize placeholder" errors for default values.

Closes #2512
2024-10-25 19:46:17 +00:00
Joachim Breitner
57a95c8b5f test: test case for #5836 (#5843) 2024-10-25 19:34:09 +00:00
Kyle Miller
266ae428dc feat: preliminary work for parent projections in StructureInfo (#5841)
This adds a `parentInfo` field to the `StructureInfo`, which will
eventually be populated with the actual parents of a structure. This is
work toward #1881. Also documents fields of the structure info data
structures.

Requires a stage0 update before the next steps.
2024-10-25 18:54:32 +00:00
Kim Morrison
4c0d12b3f1 chore: cleanup some deprecations in tests (#5834) 2024-10-25 11:11:22 +00:00
Sebastian Ullrich
748f0d6c15 fix: instantiateMVars slowdown in the language server (#5805)
Fixes #5614
2024-10-25 09:35:41 +00:00
Kim Morrison
07ea626560 feat: Array.forIn', and relate to List (#5833)
Adds support for `for h : x in my_array do`, and relates this to the
existing `List` version.
2024-10-25 07:24:39 +00:00
Henrik Böving
193b6f2bec feat: define Int8 (#5790) 2024-10-25 06:06:40 +00:00
Yann Herklotz
19ce2040a2 fix: wildcard generalize only generalizes visible theorems (#4846)
`generalize ... at *` sometimes will try to modify the recursive
hypothesis corresponding to the current theorem being defined, which may
not be the expected behaviour. It should only try to `generalize`
hypotheses that it can actually modify and are visible, not
implementation details. Otherwise this means that there are
discrepancies between `generalize ... at *` and `generalize ... at H`,
even though `H` is the only hypothesis in the context.

This commit uses `getLocalHyps` instead of `getFVarIds` to get the
current valid `FVarIds` in the context. This uses
`isImplementationDetail` to filter out `FVarIds` that are implementation
details in the context and are not visible to the user and should not be
manipulated by `generalize`.

Closes #4845
2024-10-25 05:09:28 +00:00
Kim Morrison
059674d967 chore: minor fixes in Array lemmas (#5832) 2024-10-25 04:28:41 +00:00
Arthur Adjedj
7150a0d538 fix: reduce let-bodies correctly in StructInst (#3152)
Closes #3146

Reduction doesn't trigger correctly on the bodies of `let`-expressions
in `StructInst`, leading some meta-variables to linger in the terms of
some fields. Because of this, default fields may try multiple times (and
fail) to be generated, leading to an unexpected error.

The solution implemented here is to modify the values of the introduced
variables in the local context so as to reduce them correctly.
2024-10-24 23:33:33 +00:00
Kyle Miller
0725cd39a2 fix: liftCommandElabM now carries more state over (#5800)
The `liftCommandElabM : CommandElabM α -> CoreM α` function now carries
over macro scopes, the name generator, info trees, and messages.

Adds a flag `throwOnError`, which is true by default. When it is true,
then if the messages contain an error message, it is converted into an
exception. In this case, the infotrees and messages are not carried
over; the motivation is that `throwOnError` is likely used for synthetic
syntax, and so the info and messages on errors will just be noise.
2024-10-24 23:19:06 +00:00
Kyle Miller
e07272a53a chore: review delaborators, make sure they respond to pp.explicit (#5830)
Rule: if an expression contains an implicit argument that the
delaborator would omit, only use the delaborator if `pp.explicit` is
false.
2024-10-24 22:56:47 +00:00
Sebastian Ullrich
9157c1f279 test: big_omega benchmark (#5817)
Extracted from #5614
2024-10-24 07:26:29 +00:00
Kim Morrison
09e1a05ee9 chore: cleanup imports (#5825) 2024-10-23 23:51:13 +00:00
Henrik Böving
8822b0fca7 feat: bv_decide BitVec.sdiv (#5823) 2024-10-23 21:10:27 +00:00
Kyle Miller
249530f3c1 feat: partial inhabitation uses local Inhabited instances created from parameters (#5821)
Rather than having a special pass where `mkInhabitantFor` uses the
`assumption` tactic, it creates `Inhabited` instances for each parameter
and just searches for an `Inhabited`/`Nonempty` instance for the return
type.

This makes examples like the following work:
```lean
partial def f (x : X) : Bool × X := ...
```

Removes the strategy where it looks for `Inhabited`/`Nonempty` instances
for every suffix of the signature.

This is a follow-up to #5780. Motivated [by
Zulip](https://leanprover.zulipchat.com/#narrow/channel/113489-new-members/topic/Why.20return.20type.20of.20partial.20function.20MUST.20.60inhabited.60.3F/near/477905312).
2024-10-23 18:15:31 +00:00
Sebastian Ullrich
174a5f345a refactor: nicer modifiers/ranges API (#5788)
Cleanup of #5650 

* default `Modifiers.stx` to missing
* rename and clarify `addDeclarationRangesFromSyntax` as the main
convenience function for user metaprograms
2024-10-23 09:21:50 +00:00
Aaron Tomb
45b1b367ca test: add a benchmark that is slow to elaborate (#5656)
Add an example Lean file that includes an unusually large definition
that takes a long time to elaborate.

It may be that it's difficult to process it more efficiently, but
perhaps someone will discover a way to improve it if it's in the
benchmark suite. Improved performance on this benchmark will likely make
some program analysis and verification tasks within Lean more feasible.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2024-10-23 08:20:15 +00:00
Kim Morrison
c1143d9432 feat: more lemmas for List.modify (#5816) 2024-10-23 06:45:20 +00:00
Kyle Miller
66dbad911e fix: improve error message for partial inhabitation and add delta deriving (#5780)
Example new output:
```text
failed to compile 'partial' definition 'checkMyList', could not prove that the type
  ListNode → Bool × ListNode
is nonempty.

This process uses multiple strategies:
- It looks for a parameter that matches the return type.
- It tries synthesizing 'Inhabited' and 'Nonempty' instances for the return type.
- It tries unfolding the return type.

If the return type is defined using the 'structure' or 'inductive' command, you can try
adding a 'deriving Nonempty' clause to it.
```
The inhabitation prover now also unfolds definitions when trying to
prove inhabitation. For example,
```lean
def T (α : Type) := α × α

partial def f (n : Nat) : T Nat := f n
```

Motivated [by
Zulip](https://leanprover.zulipchat.com/#narrow/channel/113489-new-members/topic/Why.20return.20type.20of.20partial.20function.20MUST.20.60inhabited.60.3F/near/477905312)
2024-10-23 06:32:11 +00:00
FR
fad57cf5a2 chore: remove redundant Decidable assumptions (#5812) 2024-10-23 04:52:54 +00:00
Kyle Miller
83129b7e3a fix: inductive elaboration should keep track of universe level parameters created in binders (#5814)
Refactors `inductive` elaborator to keep track of universe level
parameters created during elaboration of `variable`s and binders. This
fixes an issue in Mathlib where its `Type*` elaborator can result in
unexpected universe levels.

For example, in
```lean4
variable {F : Type*}
inductive I1 (A B : Type*) (x : F) : Type
```
before this change the signature would be
```
I1.{u_1, u_2} {F : Type u_1} (A : Type u_1) (B : Type u_2) (x : F) : Type
```
but now it is
```
I1.{u_1, u_2, u_3} {F : Type u_1} (A : Type u_2) (B : Type u_3) (x : F) : Type
```
Fixes this for the `axiom` elaborator too.

Adds more accurate universe level validation for mutual inductives.

Breaking change: removes `Lean.Elab.Command.expandDeclId`. Use
`Lean.Elab.Term.expandDeclId` from within `runCommandElabM`.
2024-10-23 04:07:40 +00:00
Kyle Miller
fa711253d6 feat: improved error message for unfold (#5815)
When `unfold` is trying to unfold a local variable that's not a local
definition, throws an error.

For issue from
[Zulip](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Unqualified.20unfold.20no.20longer.20works/near/478387250)
2024-10-23 03:35:15 +00:00
Joachim Breitner
eddbdd77b8 doc: refine rwa docstring (#5811)
fixes #5792
2024-10-22 16:02:39 +00:00
Markus Himmel
f0c190239a feat: compile against Windows SDK headers under Windows (#5753)
Breaking changes:

To build Lean from source on Windows, it is now necessary to install the
[Windows
SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/).
The build instructions have been updated to reflect this. Note that the
Windows SDK is **not** needed to compile Lean programs using a Lean
toolchain obtained using `elan`. The Windows SDK is only needed to build
Lean itself from source.

Furthermore, we are dropping support for Windows versions older than
Windows 10 1903 (released in May 2019).

No Windows version that is still supported by Microsoft as part of
mainstream support is affected by this.

The following Windows versions are still supported by Microsoft as part
of commercial extended support but are no longer supported by Lean:

- Windows 10 Enterprise LTSC 2015
- Windows 10 Enterprise LTSC 2016
- Windows 10 Enterprise LTSC 2019
- Windows Server 2019
2024-10-22 13:00:02 +00:00
Joachim Breitner
bab6aff173 chore: nix-ci.yml: fix test-results.xml path (#5804) 2024-10-22 11:18:40 +00:00
Joachim Breitner
5bea46deb0 fix: FunInd: withLetDecl and mkLetVar don’t mix (#5803)
Fixes: #5767
2024-10-22 10:15:14 +00:00
Marc Huisinga
462e52d0c0 feat: use "eureka!" icon for theorem completions (#5801)
It's difficult to distinguish theorems from regular definitions in the
completion menu, which is annoying when using completion for searching
one or the other. This PR makes theorem completions use the "Eureka!"
icon (![eureka
icon](https://code.visualstudio.com/assets/docs/editor/intellisense/symbol-event.svg))
to distinguish them more clearly from other completions.

NB: We are very limited in terms of which icons we can pick here since
[the completion kinds provided by LSP / VS
Code](https://code.visualstudio.com/docs/editor/intellisense#_types-of-completions)
are optimized for object-oriented programming languages, but I think
this choice strikes a nice balance between being easy to identify,
having some visual connection to theorem proving and not being used a
lot in other languages and thus not clashing with pre-existing
associations.
2024-10-22 10:07:37 +00:00
Sebastian Ullrich
d0abe1d382 fix: restore synchronous fast-forwarding path in language processor (#5802)
Between #3106 and this, it was possible that reparsing the file up to
the current position was stuck waiting in the threadpool queue,
displaying a yellow bar and not displaying any info on the unchanged
prefix.
2024-10-22 09:50:30 +00:00
Eric Wieser
f752ce2db9 doc: stub for ellipsis notation (#5794)
This is certainly better than no documentation, though it's not obvious
to me whether the `_` insertion is greedy, lazy, or somewhere in
between.
2024-10-22 01:33:46 +00:00
Kim Morrison
07c09ee579 feat: relate Array.forIn and List.forIn (#5799) 2024-10-22 01:20:13 +00:00
Kim Morrison
919f64b2e6 chore: upstream List.modify, add lemmas, relate to Array.modify (#5798)
Note that the order of arguments still differs between `List.modify` and
`Array.modify`. I'll settle this later.
2024-10-22 01:01:32 +00:00
Kim Morrison
71122696a1 feat: rename Array.shrink to take, and relate to List.take (#5796) 2024-10-21 23:35:32 +00:00
Tobias Grosser
8d789f7b63 feat: add BitVec.toInt_sub, simplify BitVec.toInt_neg (#5772)
This also requires us to expand the theory of `Int.bmod`.

---------

Co-authored-by: Alex Keizer <alex@keizer.dev>
2024-10-21 22:38:29 +00:00
Leonardo de Moura
82d31a1793 perf: has_univ_mvar, has_univ_mvar, and has_fvar in C++ (#5793)
`instantiate_mvars` is now implemented in C/C++, and makes many calls to
`has_fvar`, `has_mvar`. The new C/C++ implementations are inlined and
avoid unnecessary RC inc/decs.
2024-10-21 16:56:30 +00:00
Joachim Breitner
76164b284b fix: RecursorVal.getInduct to return name of major argument’s type (#5679)
Previously `RecursorVal.getInduct` would return the prefix of the
recursor’s name, which is unlikely the right value for the “derived”
recursors in nested recursion. The code using `RecursorVal.getInduct`
seems to expect the name of the inductive type of major argument here.

If we return that name, this fixes #5661.

This bug becomes more visible now that we have structural mutual
recursion.

Also, to avoid confusion, renames the function to ``getMajorInduct`.
2024-10-21 08:45:18 +00:00
Kim Morrison
51377afd6c feat: simp lemmas for Array.isEqv and beq (#5786)
- [ ] depends on: #5785
2024-10-21 07:37:40 +00:00
Kim Morrison
6f642abe70 feat: Nat.forall_lt_succ and variants (#5785) 2024-10-21 06:51:23 +00:00
Kim Morrison
8151ac79d6 chore: Array cleanup (#5782)
More cleanup of Array API. More to come.
2024-10-21 06:00:37 +00:00
Kim Morrison
4f18c29cb4 chore: make 'while' available earlier (#5784) 2024-10-21 05:56:37 +00:00
Kim Morrison
5d155d8b02 chore: simplify signature of Array.mapIdx (#5749)
This PR simplifies the signature of `Array.mapIdx`, to take a function
`f : Nat \to \a \to \b` rather than a function `f : Fin as.size \to \a
\to \b`.

Lean doesn't actually use the extra generality anywhere (so in fact this
change *simplifies* all the call sites of `Array.mapIdx`, since we no
longer need to throw away the proof).

This change would make the function signature equivalent to
`List.mapIdx`, hence making it easier to write verification lemmas.

We keep the original behaviour as `Array.mapFinIdx`.
2024-10-21 05:48:42 +00:00
Henrik Böving
def81076de feat: bv_decide introduces uninterpreted symbols everywhere (#5781)
Co-authored-by: Tobias Grosser <tobias@grosser.es>
2024-10-20 21:01:21 +00:00
Kyle Miller
46f1335b80 fix: have Lake not create core aliases into Lake namespace (#5688)
This replaces `export Lean (Name NameMap)` and `export System
(SearchPath FilePath)` with the relevant `open` commands. This fixes
docgen output so that it can refer to, for example, `Lean.Name` instead
of `Lake.Name`.

The reason for these `export`s was convenience: by doing `open Lake` you
could get these aliases for free. However, aliases affect pretty
printing, and the Lake aliases took precedence. We don't want to disable
pretty printing re-exported names because this can be a valid pattern
(names could incrementally get re-exported from namespace to parent
namespace).

In the future we might implement a feature to be able to `scoped open`
some names.

Breaking change: Lakefiles that refer to `FilePath` may need to change
this to `System.FilePath` or otherwise add `open System (FilePath)`.

Closes #2524
2024-10-20 18:40:44 +00:00
Kyle Miller
682173d7c0 feat: #version command (#5768)
Prints `Lean.versionString` and target/platform information. Example:
```
Lean 4.12.0, commit 8218940152
Target: arm64-apple-darwin23.5.0 macOS
```
2024-10-18 20:17:52 +00:00
Joachim Breitner
26df545598 fix: structural nested recursion confused when nested type appears first (#5766)
this fixes #5726
2024-10-18 19:41:24 +00:00
Sebastian Ullrich
11ae8bae42 fix: include references in attributes in call hierarchy (#5650)
By ensuring all `declModifiers` are included in `addDeclarationRanges`,
`implementedBy` references etc are included in the call hierarchy
2024-10-18 15:38:32 +00:00
Henrik Böving
a167860e3b chore: @hargoniX Std.Sat codeowner, fix Kim's user name (#5765) 2024-10-18 11:13:28 +00:00
Markus Himmel
cc76496050 chore: check-prelude also for Std (#5764) 2024-10-18 10:53:52 +00:00
Sebastian Ullrich
41b35baea2 fix: duplicate info trees from IO.processCommandsIncrementally (#5763)
As reported in https://github.com/leanprover-community/repl/pull/57
2024-10-18 10:17:30 +00:00
Kim Morrison
a6243f6076 chore: deprecation for Array.data (#5687) 2024-10-18 03:16:38 +00:00
Kyle Miller
fd15d8f9ed feat: Lean.Expr.name? (#5760)
Adds a recognizer for `Name` literal expressions. Handles `Name`
constructors as well as the `Lean.Name.mkStr*` functions.
2024-10-18 02:40:26 +00:00
Kyle Miller
1d66ff8231 fix: app unexpander for sorryAx (#5759)
Fixes a long-standing bug in the the `sorryAx` app unexpander that
prevented it from applying. Now `sorry` pretty prints as `sorry`.
2024-10-18 01:44:52 +00:00
Kim Morrison
51ab162a5a chore: upstream Array.reduceOption (#5758) 2024-10-18 00:41:09 +00:00
Kim Morrison
41797a78c3 chore: deprecate Nat.sum (#5746) 2024-10-18 00:03:36 +00:00
David Thrane Christiansen
d6a7eb3987 feat: add Hashable instance for Char (#5747)
I needed this in downstream code, and it seems to make the most sense to
just contribute it here.
2024-10-17 14:46:10 +00:00
Sebastian Ullrich
fc5e3cc66e fix: do not force snapshot tree too early (#5752)
This turns out to be the issue behind #5736, though really it is yet
another indicator of a general thread pool weakness.
2024-10-17 12:23:34 +00:00
Marc Huisinga
372f344155 fix: some goal state issues (#5677)
This PR resolves the following issues related to goal state display:
1. In a new line after a `case` tactic with a completed proof, the state
of the proof in the `case` would be displayed, not the proof state after
the `case`
1. In the range of `next =>` / `case' ... =>`, the state of the proof in
the corresponding case would not be displayed, whereas this is true for
`case`
1. In the `suffices ... by` tactic, the tactic state of the `by` block
was not displayed after the `by` and before the first tactic

The incorrect goal state after `case` was caused by `evalCase` adding a
`TacticInfo` with the full block proof state for the full range of the
`case` block that the goal state selection has no means of
distinguishing from the `TacticInfo` with the same range that contains
the state after the whole `case` block. Narrowing the range of this
`TacticInfo` to `case ... =>` fixed this issue.

The lack of a case proof state on `next =>` was caused by the `case`
syntax that `next` expands to receiving noncanonical synthetic
`SourceInfo`, which is usually ignored by the language server. Adding a
token antiquotation for `next` fixed this issue.

The lack of a case proof state on `case' ... =>` was caused by
`evalCase'` not adding a `TacticInfo` with the full block state to the
range of `case' ... =>`. Adding this `TacticInfo` fixed this issue.

The tactic state of the block not being displayed after the `by` was
caused by the macro expansion of `suffices` to `have` not transferring
the trailing whitespace of the `by`. Ensuring that this trailing
whitespace information is transferred fixed this issue.

Fixes #2881.
2024-10-17 12:09:54 +00:00
Sebastian Ullrich
f2ac0d03c6 perf: do not lint unused variables defined in tactics by default (#5338)
Should ensure we visit at most as many expr nodes as in the final expr
instead of many possibly overlapping mvar assignments. This is likely
the only way we can ensure acceptable performance in all cases.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2024-10-17 09:55:11 +00:00
Joachim Breitner
08d8a0873e doc: remove docstring from implicitDefEqProofs (#5751)
this option was added in fb97275dcb to
prepare for #4595, due to boostrapping issues, but #4595 has not landed
yet. This is be very confusing when people discover this option and try
to use it (as I did).

So let's clearly mark this as not yet implemented on `master`, and add
the
docstring only with #4595.
2024-10-17 09:38:52 +00:00
Sebastian Ullrich
68b0471de9 chore: remove SplitIf.ext cache (#5571)
Incompatible as is with parallelism; let's first check if it has any
impact at all
2024-10-17 09:36:00 +00:00
Kim Morrison
3a34a8e0d1 chore: move Array.mapIdx lemmas to new file (#5748) 2024-10-17 05:54:25 +00:00
Kim Morrison
6fa75e346a chore: upstream List.foldxM_map (#5697) 2024-10-17 04:30:08 +00:00
Eric Wieser
2669fb525f feat: change lake new math to use autoImplicit false (#5715)
The reality is that almost every math project uses this setting already,
even if it is not the default:

*
36b7d4a6d0/lakefile.lean (L7)
*
9ea3a96243/lakefile.lean (L45)
*
97755eaae3/lakefile.toml (L6)
*
fb92dbf97f/lakefile.lean (L7)
*
c8569b3d39/lakefile.toml (L6)
*
c7fae107fd/lakefile.lean (L8)
*
1d891c770d/lakefile.lean (L27)

The fact that MIL uses it is particularly notable, as it means that
newcomers have an unexpected surprise when they want to take on a brand
new project.

---

I don't know whether this is `chore`, `feat`, `fix`, `refactor`, or
something else.
2024-10-17 04:29:48 +00:00
Eric Wieser
8632b79023 doc: point out that OfScientific is called with raw literals (#5725) 2024-10-17 04:29:00 +00:00
Kim Morrison
e8970463d1 fix: change String.dropPrefix? signature (#5745) 2024-10-17 03:51:45 +00:00
Kim Morrison
69e8cd3d8a chore: cleanup in Array/Lemmas (#5744) 2024-10-17 03:36:26 +00:00
Kim Morrison
565ac23b78 chore: move Antisymm to Std.Antisymm (#5740) 2024-10-17 02:26:55 +00:00
Kim Morrison
c1750f4316 chore: upstream basic material on Sum (#5741) 2024-10-17 01:27:41 +00:00
Kim Morrison
092c87a70f chore: upstream ne_of_apply_ne (#5743) 2024-10-17 01:24:01 +00:00
Kim Morrison
b8fc6c593a chore: upstream ne_of_mem_of_not_mem (#5742) 2024-10-17 01:18:23 +00:00
Kim Morrison
7c2425605c chore: upstream material on Prod (#5739) 2024-10-16 23:03:44 +00:00
Kim Morrison
3f7854203a chore: rename List.pure to List.singleton (#5732) 2024-10-16 22:11:07 +00:00
Sebastian Ullrich
79583d63f3 fix: don't block on snapshot tree if tracing is not enabled (#5736)
While there appears to be an underlying issue of blocking tasks that
this specific PR is not resolving, it should alleviate the problems
described in
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/reliable.20file.20desync.20on.20Linux.20Mint
as it effectively reverts the relevant change introduced in 4.13.0-rc1
when the trace option is not set.
2024-10-16 13:12:42 +00:00
Henrik Böving
741040d296 feat: UIntX.[val_ofNat, toBitVec_ofNat] (#5735) 2024-10-16 12:39:41 +00:00
Luisa Cicolini
b69377cc42 feat: add BitVec.(getMSbD, msb)_(add, sub) and BitVec.getLsbD_sub (#5691)
Since `getMsbD_add`, `getMsbD_sub`, `getLsbD_sub`, `msb_sub` , `msb_add`
depend on `getLsbD_add` (which lives in`BitBlast.lean`) and on each
other, I put all of these in `BitBlast.lean`.
2024-10-16 11:47:20 +00:00
Kim Morrison
ef05bdc449 chore: rename List.bind and Array.concatMap to flatMap (#5731) 2024-10-16 11:30:49 +00:00
Lean stage0 autoupdater
50594aa932 chore: update stage0 2024-10-16 13:35:31 +02:00
Joachim Breitner
032c0257c3 feat: DiscrTree: index the domain of
It bothered me that inferring instances of the shape `Decidable (∀ (x : Fin _), _)`
will go linearly through all instances of that shape, even those that are
about `∀ (x : Nat), …`. And that  `Decidable (∃ (x : Fin _), _)` gets better
indexing than `Decidable (∀ (x : Fin _), _)`.

Judging from code comments, the discr tree used to index arrow types
with two arguments (domain and body), and that led to bugs due to the
dependency, so the arguments were removed. But it seems that indexing
the domain is completely simple and innocent.

So let’s see what happens…

Mostly only insignificant perf improvements, unfortunately (~Mathlib.Data.Matroid.IndepAxioms — instructions -11.4B, overall build instructions -0.097 %):
http://speed.lean-fro.org/mathlib4/compare/dd333cc1-fa26-42f2-96c6-b0e66047d0b6/to/6875ff8f-a17c-431d-8b8b-2f00799be794

This is just a small baby step compared to the more invasive improvements
done in the [`RefinedDiscrTree` by  J. W. Gerbscheid](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Tactic/FunProp/RefinedDiscrTree.html) in mathlib.
2024-10-16 13:35:31 +02:00
Joachim Breitner
a2d2977228 fix: ac_nf0, simp_arith: don't tempt the kernel to reduce atoms (#5708)
this fixes #5699 and fixes #5384.
2024-10-16 08:52:58 +00:00
Jerry Wu
b333de1a36 fix: make applyEdit optional in WorkspaceClientCapabilities of LSP (#5224)
The `applyEdit` field should be optional in
`WorkspaceClientCapabilities` by the LSP spec and some clients don't
populate it in requests

Closes #4541
2024-10-16 08:38:11 +00:00
Henrik Böving
19e06acc65 refactor: redefine unsigned fixed width integers in terms of BitVec (#5323)
I made a few choices so far that can probably be discussed:
- got rid of `modn` on `UInt`, nobody seems to use it apart from the
definition of `shift` which can use normal `mod`
- removed the previous defeq optimized definition of `USize.size` in
favor for a normal one. The motivation was to allow `OfNat` to work
which doesn't seem to be necessary anymore afaict.
- Minimized uses of `.val`, should we maybe mark it deprecated?
- Mostly got rid of `.val` in basically all theorems as the proper next
level of API would now be `.toBitVec`. We could probably re-prove them
but it would be more annoying given the change of definition.
- Did not yet redefine `log2` in terms of `BitVec` as this would require
a `log2` in `BitVec` as well, do we want this?
- I added a couple of theorems around the relation of `<` on `UInt` and
`Nat`. These were previously not needed because defeq was used all over
the place to save us. I did not yet generalize these to all types as I
wasn't sure if they are the appropriate lemma that we want to have.
2024-10-16 07:28:23 +00:00
Kim Morrison
a04b476431 chore: remove instBEqNat, which is redundant with instBEqOfDecidableEq but not defeq (#5694) 2024-10-16 04:42:22 +00:00
Kyle Miller
eea953b94f feat: push/pop tactic API (#5720)
Adds `pushGoal`/`pushGoals` and `popGoal` for manipulating the goal
state. These are an alternative to `replaceMainGoal` and `getMainGoal`,
and with them you don't need to worry about making sure nothing clears
assigned metavariables from the goal list between assigning the main
goal and using `replaceMainGoal`.

Modifies `closeMainGoalUsing`, which is like a `TacticM` version of
`liftMetaTactic`. Now the callback is run in a context where the main
goal is removed from the goal list, and the callback is free to modify
the goal list. Furthermore, the `checkUnassigned` argument has been
replaced with `checkNewUnassigned`, which checks whether the value
assigned to the goal has any *new* metavariables, relative to the start
of execution of the callback. This API is sufficient for the `exact`
tactic for example.

Modifies `withCollectingNewGoalsFrom` to take the `parentTag` argument
explicitly rather than indirectly via `getMainTag`. This is needed when
used under `closeMainGoalUsing`.

Modifies `elabTermWithHoles` to optionally take `parentTag?`. It
defaults to `getMainTag` if it is `none`.

Renames `Tactic.tryCatch` to `Tactic.tryCatchRestore`, and adds a
`Tactic.tryCatch` that doesn't do backtracking.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2024-10-16 03:54:58 +00:00
Kim Morrison
dec1262697 chore: upstream classical tactic (#5730) 2024-10-16 03:35:41 +00:00
Kim Morrison
487c2a937a feat: Expr helper functions (#5729)
`getNumHeadForalls` and `getNumHeadLambdas` were both duplicated
downstream with different names; I'll clean up those next.

Also adds `getAppNumArgs'`.
2024-10-16 03:07:34 +00:00
Kim Morrison
831fa0899f chore: upstream String.dropPrefix? (#5728)
Useful String helper functions widely used in tactic implementations.
2024-10-16 02:41:17 +00:00
Kim Morrison
94053c9b1b chore: make getIntrosize public (#5727)
This is the most popular target of `open private`, and seems a
reasonable part of the public API.
2024-10-16 02:35:12 +00:00
Joachim Breitner
94b1e512da fix: simpproc to reduce Fin literals consistently (#5632)
previously, it would not reduce `25 : Fin 25` to  `0 : Fin 25`.

fixes #5630
2024-10-15 15:59:50 +00:00
Joachim Breitner
5a87b104f6 refactor: remove mkRecursorInfoForKernelRec (#5681)
it seems to be unused, arguably even for kernel recursors their type
should be usable with `mkRecursorInfo`, and removing this will help
understand the impact of #5679.
2024-10-15 15:59:04 +00:00
Kim Morrison
dc83a607b2 fix: List.drop_drop addition order (#5716) 2024-10-15 10:14:02 +00:00
Tobias Grosser
7234ab79ed feat: add BitVec.sdiv_[zero|one|self] theorems (#5718)
Co-authored-by: Siddharth <siddu.druid@gmail.com>
2024-10-15 09:47:21 +00:00
Markus Himmel
c27e671036 chore: rename instDecidableEqQuotientOfDecidableEquiv to Quotient.decidableEq (#5722)
Mathlib has a duplicate of this instance as `Quotient.decidableEq` (with
the same implementation) and refers to it by name a few times, so let's
just rename our version to the mathlib name so that the copy in mathlib
can be dropped.
2024-10-15 09:46:25 +00:00
Alex Keizer
94dd1d61bd feat: bv_decide inequality regression tests (#5714)
This takes a few standalone bitvector problems, about inequalties, from
LNSym, and adds them as a benchmark to prevent further regressions with
bv_decide.

These problems are particularly interesting, because they've previously
had a bad interaction with bv_decides normalization pass, see
https://github.com/leanprover/lean4/issues/5664.

---------

Co-authored-by: Henrik Böving <hargonix@gmail.com>
2024-10-15 08:51:14 +00:00
Kim Morrison
4409e39c43 chore: upstream List.sum, planning to later deprecate Nat.sum (#5703) 2024-10-15 08:41:35 +00:00
Kim Morrison
0bfe1a8c1a chore: better default value for Array.swapAt! (#5705) 2024-10-15 01:18:51 +00:00
Kyle Miller
a026bc7edb feat: let dot notation see through CoeFun instances (#5692)
Projects like mathlib like to define projection functions with extra
structure, for example one could imagine defining `Multiset.card :
Multiset α →+ Nat`, which bundles the fact that `Multiset.card (m1 + m2)
= Multiset.card m1 + Multiset.card m2` for all `m1 m2 : Multiset α`. A
problem though is that so far this has prevented dot notation from
working: you can't write `(m1 + m2).card = m1.card + m2.card`.

With this PR, now you can. The way it works is that "LValue resolution"
will apply CoeFun instances when trying to resolve which argument should
receive the object of dot notation.

A contrived-yet-representative example:
```lean
structure Equiv (α β : Sort _) where
  toFun : α → β
  invFun : β → α

infixl:25 " ≃ " => Equiv

instance: CoeFun (α ≃ β) fun _ => α → β where
  coe := Equiv.toFun

structure Foo where
  n : Nat

def Foo.n' : Foo ≃ Nat := ⟨Foo.n, Foo.mk⟩

variable (f : Foo)
#check f.n'
-- Foo.n'.toFun f : Nat
```

Design note 1: While LValue resolution attempts to make use of named
arguments when positional arguments cannot be used, when we apply CoeFun
instances we disallow making use of named arguments. The rationale is
that argument names for CoeFun instances tend to be random, which could
lead dot notation randomly succeeding or failing. It is better to be
uniform, and so it uniformly fails in this case.

Design note 2: There is a limitation in that this will *not* make use of
the values of any of the provided arguments when synthesizing the CoeFun
instances (see the tests for an example), since argument elaboration
takes place after LValue resolution. However, we make sure that
synthesis will fail rather than choose the wrong CoeFun instance.

Performance note: Such instances will be synthesized twice, once during
LValue resolution, and again when applying arguments.

This also adds in a small optimization to the parameter list computation
in LValue resolution so that it lazily reduces when a relevant parameter
hasn't been found yet, rather than using `forallTelescopeReducing`. It
also switches to using `forallMetaTelescope` to make sure the CoeFun
synthesis will fail if multiple instances could apply.

Getting this to pretty print will be deferred to future work.

Closes #1910
2024-10-14 21:49:33 +00:00
Kyle Miller
36c2511b27 feat: options pp.mvars.anonymous and pp.mvars.levels (#5711)
Gives more control over pretty printing metavariables.

- When `pp.mvars.levels` is false, then universe level metavariables
pretty print as `_` rather than `?u.22`
- When `pp.mvars.anonymous` is false, then anonymous metavariables
pretty print as `?_` rather than `?m.22`. Named metavariables still
pretty print with their names. When this is false, it also sets
`pp.mvars.levels` to false, since every level metavariable is anonymous.
- When `pp.mvars` is false, then all metavariables pretty print as `?_`
or `_`.

Modifies TryThis to use `pp.mvars.anonymous` rather than doing a
post-delaboration modification. This incidentally improves TryThis since
it now prints universe level metavariables as `_` rather than `?u.22`.
2024-10-14 21:44:15 +00:00
Henrik Böving
adfbc56f91 chore: disable ac_nf by default (#5673)
We trust that the users read the error messages or tactic docs to
discover the option.
AWS problems have shown that this can be too eager of an operation to
do.
Given that we have the luxury of interactivity let's go for an approach
where the users
can optionally enable it.
2024-10-14 21:23:18 +00:00
Tobias Grosser
9f8ce47699 feat: add BitVec.[udiv|umod]_[zero|one|self] theorems (#5712)
Co-authored-by: Siddharth <siddu.druid@gmail.com>
2024-10-14 20:27:05 +00:00
Kyle Miller
3d175ab25f fix: the elaboration warning did not mention pp.maxSteps (#5710)
This also adds in the tip that hovering over `⋯` gives the option that
led to its presence.
2024-10-14 17:28:28 +00:00
Henrik Böving
9b6696be1d feat: use libuv for tempfiles (#5135)
This is currently broken because of linker issues. CC @TwoFX

---------

Co-authored-by: Markus Himmel <markus@lean-fro.org>
2024-10-14 13:56:56 +00:00
Marc Huisinga
057482eb1c feat: denote deprecations in completion items (#5707)
This PR ensures that deprecated declarations are displayed with a
strikethrough markup in the completion popup of VS Code and that the
docstring of a completion item denotes the meta-data of the deprecation.
2024-10-14 13:05:16 +00:00
Kim Morrison
16e2a785aa chore: remove @[simp] from Option.isSome_eq_isSome (#5704) 2024-10-14 12:28:43 +00:00
Johan Commelin
2580694e26 chore: mark prefix_append_right_inj as simp lemma (#5706) 2024-10-14 11:49:38 +00:00
Kim Morrison
9ec29b4e3a chore: update stage0 2024-10-14 22:28:12 +11:00
Kim Morrison
aa2360a41d chore: rename List.join to List.flatten
one more

one more

one more

fix test
2024-10-14 22:28:12 +11:00
Siddharth
65637b7683 feat: lemmas about BitVector arithmetic inequalities (#5646)
These lemmas are peeled from `leanprover/lnsym`.
Moreover, note that these lemmas only hold when we do not have overflow
in their operands, and thus, we are able to treat the operands as if
they were 'regular' natural numbers.

---------

Co-authored-by: Tobias Grosser <github@grosser.es>
Co-authored-by: Kim Morrison <scott@tqft.net>
2024-10-14 08:14:11 +00:00
Kim Morrison
20ea855e50 feat: upstream List.mapIdx, and add lemmas (#5696) 2024-10-14 07:25:02 +00:00
Kim Morrison
225e08965d chore: import orphaned Lean.Replay (#5693)
As noticed on
[zulip](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/.E2.9C.94.20Reverse.20FFI.20undefined.20reference.20for.20mathlib/near/475824204).
2024-10-14 01:29:03 +00:00
Tobias Grosser
7fd2aa04ae chore: move BitVec.udiv/umod/sdiv/smod after add/sub/mul/lt (#5623)
Divison proofs are more likely to depend on add/sub/mul proofs than the
other way around. This cleans up
https://github.com/leanprover/lean4/pull/5609, which added division
proofs that rely on negation to already be defined.
2024-10-13 20:11:31 +00:00
Luisa Cicolini
47e0430b07 feat: complete BitVec.[getMsbD|getLsbD|msb] for shifts (#5604)
Co-authored-by: Tobias Grosser <github@grosser.es>
2024-10-13 17:45:19 +00:00
Tobias Grosser
5d6553029c feat: expand relationship with BitVec and toFin (#5680) 2024-10-13 16:28:28 +00:00
James Oswald
1d8555fe0b fix: help message flags, removes -f flag and adds -g flag (#5685)
Closes #5682

- Removes the broken `-f` flag from the help message which doesn't
behave as expected as an alternative to `--features`.
- Adds the `-g` flag to the help message which is a working alternative
to the `--githash` flag.
2024-10-13 06:37:09 +00:00
Mac Malone
068208091f refactor: lake: restrict cache fetch to leanprover* (#5642)
Lake will now only automatically fetch Reservoir build caches for
package in the the `leanprover` and `leanprover-community`
organizations. We are not planning to expand the Reservoir build cache
to other packages until farther in the future.
2024-10-12 22:56:49 +00:00
Marc Huisinga
a3bc4d2359 fix: make IO-bound tasks dedicated (#5678)
This PR ensures that all I/O-bound tasks in the language server use
dedicated tasks.
2024-10-11 15:23:11 +00:00
Henrik Böving
087219bf5d feat: make bv_decide error when the LRAT proof is invalid (#5676) 2024-10-11 15:04:23 +00:00
Henrik Böving
e5bbda1c3d fix: context tracking in bv_decide counter example (#5675)
Closes #5674.
2024-10-11 08:57:06 +00:00
Kyle Miller
742ca6afa7 feat: support let rec in #eval (#5663)
Makes `#eval` use the `elabMutualDef` machinery to process all the `let
rec`s that might appear in the expression. This now works:
```lean
#eval
  let rec fact (n : Nat) : Nat :=
    match n with
    | 0 => 1
    | n' + 1 => n * fact n'
  fact 5
```

Closes #2374
2024-10-11 06:46:16 +00:00
Kyle Miller
fe0fbc6bf7 feat: decide! tactic for using kernel reduction (#5665)
The `decide!` tactic is like `decide`, but when it tries reducing the
`Decidable` instance it uses kernel reduction rather than the
elaborator's reduction.

The kernel ignores transparency, so it can unfold all definitions (for
better or for worse). Furthermore, by using kernel reduction we can
cache the result as an auxiliary lemma — this is more efficient than
`decide`, which needs to reduce the instance twice: once in the
elaborator to check whether the tactic succeeds, and once again in the
kernel during final typechecking.

While RFC #5629 proposes a `decide!` that skips checking altogether
during elaboration, with this PR's `decide!` we can use `decide!` as
more-or-less a drop-in replacement for `decide`, since the tactic will
fail if kernel reduction fails.

This PR also includes two small fixes:
- `blameDecideReductionFailure` now uses `withIncRecDepth`.
- `Lean.Meta.zetaReduce` now instantiates metavariables while zeta
reducing.

Some profiling:
```lean
set_option maxRecDepth 2000
set_option trace.profiler true
set_option trace.profiler.threshold 0

theorem thm1 : 0 < 1 := by decide!
theorem thm1' : 0 < 1 := by decide
theorem thm2 : ∀ x < 400, x * x ≤ 160000 := by decide!
theorem thm2' : ∀ x < 400, x * x ≤ 160000 := by decide
/-
[Elab.command] [0.003655] theorem thm1 : 0 < 1 := by decide!
[Elab.command] [0.003164] theorem thm1' : 0 < 1 := by decide
[Elab.command] [0.133223] theorem thm2 : ∀ x < 400, x * x ≤ 160000 := by decide!
[Elab.command] [0.252310] theorem thm2' : ∀ x < 400, x * x ≤ 160000 := by decide
-/
```

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
2024-10-11 06:40:57 +00:00
Kyle Miller
8e88e8061a chore: deprecate := variants of inductive and structure (#5542)
Deprecates `inductive ... :=`, `structure ... :=`, and `class ... :=` in
favor of the `... where` variant. Currently this syntax produces a
warning, controlled by the `linter.deprecated` option.

Breaking change: modifies `Lean.Linter.logLintIf` to use
`Lean.Linter.getLinterValue` to determine if a linter value is set. This
means that the `linter.all` option now is taken into account when the
linter option is not set.

Part of #5236
2024-10-11 05:54:18 +00:00
Henrik Böving
96e996e16d feat: ~~~(-x) bv_decide (#5670)
Co-authored-by: Siddharth <siddu.druid@gmail.com>
2024-10-10 19:44:31 +00:00
Kyle Miller
4614b758e1 fix: make @[elab_as_elim] require at least one discriminant (#5671)
This is an oversight in `getElabElimExprInfo`. If there are no
discriminants, then there is no point in elaborating as an eliminator.
2024-10-10 17:20:35 +00:00
Marc Huisinga
3930100b67 feat: whitespace tactic completion & tactic completion docs (#5666)
This PR enables tactic completion in the whitespace of a tactic proof
and adds tactic docstrings to the completion menu.

Future work:
- A couple of broken tactic completions: This is due to tactic
completion now using @david-christiansen's `Tactic.Doc.allTacticDocs` to
obtain the tactic docstrings and should be fixed soon.
- Whitespace tactic completion in tactic combinators: This requires
changing the syntax of tactic combinators to produce a syntax node that
makes it clear that a tactic is expected at the given position.

Closes #1651.
2024-10-10 13:28:34 +00:00
Kyle Miller
d10d41bc07 fix: store local context for 'don't know how to synthesize implicit argument' errors (#5658)
When named arguments introduce eta arguments, the full application
contains fvars for these eta arguments, so `MVarErrorKind.implicitArg`
needs to keep a local context for its error messages. This is because
the local context of the mvar associated to the `MVarErrorKind` is not
sufficient, since when an eta argument come after an implicit argument,
the implicit argument's mvar doesn't contain the eta argument's fvar in
its local context.

Closes #5475
2024-10-09 08:40:21 +00:00
Kyle Miller
79930af11e feat: allow explicit mode with field notation (#5528)
Now one can write `@x.f`, `@(x).f`, `@x.1`, `@(x).1`, and so on.

This fixes an issue where structure instance update notation (like `{x
with a := a'}`) could fail if the field `a` had a type with implicit,
optional, or auto parameters.

Closes #5406
2024-10-09 07:03:46 +00:00
Eric Wieser
b814be6d6a fix: use MessageData.tagged to mark maxHeartbeat exceptions (#5566)
Fixes #5565, by using tags instead of trying to string match on a
`MessageData`. This ends up reverting some unwanted test output changes
from #4781 too.

This changes `isMaxRecDepth` for good measure too.

This was a regression in Lean 4.11.0, so may be worth backporting to
4.12.x, if not also 4.11.x.
2024-10-09 02:08:50 +00:00
Kyle Miller
feb8185a83 fix: upgrade instance synth order issues to hard errors (#5399)
Motivated [by a user's
question](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Confusing.20instance.20error/near/471539940),
this increases the severity of the "cannot find synthesization order"
message from a log error to throwing an exception. This saves some
confusion about whether the instance was added or not.
2024-10-08 23:29:59 +00:00
Mac Malone
7942b9eaae fix: lake: make package extraDep intransitive (#5641)
A Lake build of target within a a package will no longer build a
package's dependencies package-level extra targets dependencies. At the
technical level, a package's `extraDep` facet no longer transitively
builds its dependencies' `extraDep` facet.

Closes #5633.
2024-10-08 23:20:05 +00:00
Kyle Miller
15bb8a26d5 fix: have simpa ... using ... do exact-like checks (#5648)
Closes #5634. Before assigning the simplified `using` clause expression
to the goal, this adds a check that the expression has no new
metavariables. It also adjusts how new hypotheses are added to the goal
to prevent spurious "don't know how to synthesize placeholder" errors on
that goal metavariable. We also throw in an occurs check immediately
after elaboration to avoid some counterintuitive behavior when
simplifying such a term closes the goal.

Closes #4101. This also improves the type mismatch error message,
showing the elaborated `using` clause rather than `h✝`:
```lean
example : False := by
  simpa using (fun x : True => x)
/-
error: type mismatch, term
  fun x => x
after simplification has type
  True : Prop
but is expected to have type
  False : Prop
-/
```
2024-10-08 23:09:00 +00:00
Kyle Miller
a35e6f4af7 feat: infer Prop for inductive/structure when defining syntactic subsingletons (#5517)
A `Prop`-valued inductive type is a syntactic subsingleton if it has at
most one constructor and all the arguments to the constructor are in
`Prop`. Such types have large elimination, so they could be defined in
`Type` or `Prop` without any trouble, though users tend to expect that
such types define a `Prop` and need to learn to insert `: Prop`.

Currently, the default universe for types is `Type`. This PR adds a
heuristic: if a type is a syntactic subsingleton with exactly one
constructor, and the constructor has at least one parameter, then the
`inductive` command will prefer creating a `Prop` instead of a `Type`.
For `structure`, we ask for at least one field.

More generally, for mutual inductives, each type needs to be a syntactic
subsingleton, at least one type must have one constructor, and at least
one constructor must have at least one parameter. The motivation for
this restriction is that every inductive type starts with a zero
constructors and each constructor starts with zero fields, and
stubbed-out types shouldn't be `Prop`.

Thanks to @arthur-adjedj for the investigation in #2695 and to @digama0
for formulating the heuristic.

Closes #2690
2024-10-08 22:39:38 +00:00
Kyle Miller
fdd5aec172 feat: better #eval command (#5627)
This refactors and improves the `#eval` command, introducing some new
features.
* Now evaluated results can be represented using `ToExpr` and pretty
printing. This means **hoverable output**. If `ToExpr` fails, it then
tries `Repr` and then `ToString`. The `eval.pp` option controls whether
or not to try `ToExpr`.
* There is now **auto-derivation** of `Repr` instances, enabled with the
`pp.derive.repr` option (default to **true**). For example:
  ```lean
  inductive Baz
    | a | b

  #eval Baz.a
  -- Baz.a
  ```
It simply does `deriving instance Repr for Baz` when there's no way to
represent `Baz`. If core Lean gets `ToExpr` derive handlers, they could
be used here as well.
* The option `eval.type` controls whether or not to include the type in
the output. For now the default is false.
* Now things like `#eval do return 2` work. It tries using
`CommandElabM`, `TermElabM`, or `IO` when the monad is unknown.
* Now there is no longer `Lean.Eval` or `Lean.MetaEval`. These each used
to be responsible for both adapting monads and printing results. The
concerns have been split into two. (1) The `MonadEval` class is
responsible for adapting monads for evaluation (it is similar to
`MonadLift`, but instances are allowed to use default data when
initializing state) and (2) finding a way to represent results is
handled separately.
* Error messages about failed instance synthesis are now more precise.
Once it detects that a `MonadEval` class applies, then the error message
will be specific about missing `ToExpr`/`Repr`/`ToString` instances.
* Fixes a bug where `Repr`/`ToString` instances can't be found by
unfolding types "under the monad". For example, this works now:
  ```lean
  def Foo := List Nat
  def Foo.mk (l : List Nat) : Foo := l
  #eval show Lean.CoreM Foo from do return Foo.mk [1,2,3]
  ```
* Elaboration errors now abort evaluation. This eliminates some
not-so-relevant error messages.
* Now evaluating a value of type `m Unit` never prints a blank message.
* Fixes bugs where evaluating `MetaM` and `CoreM` wouldn't collect log
messages.

The `run_cmd`, `run_elab`, and `run_meta` commands are now frontends for
`#eval`.
2024-10-08 20:51:46 +00:00
Henrik Böving
81743d80e5 chore: reduce error on bv_check to warning (#5655) 2024-10-08 19:49:44 +00:00
Henrik Böving
248864c716 perf: benchmark for modulo on bv_decide (#5653)
This verifies a bit hack from here:
https://en.wikipedia.org/wiki/Lehmer_random_number_generator#Sample_C99_code

I previously ran the SMTLIB equivalent this with Bitwuzla in my crypto
class and got the following numbers:
- 22s with Bitwuzla
- Z3 and CVC5 don't yet terminate after > 2min

Now with`bv_decide` the overall timing is 33.7s, consisting of:
- 5s of checking the LRAT cert
- 5s of trimming the LRAT cert from 800k to 300k proof steps
- remainder actual solving time

So running `bv_decide` like a normal SMT solver without verifying the
result of the SAT solver would yield approximately ~24s.
2024-10-08 18:58:15 +00:00
Kyle Miller
bd46319aee feat: add option pp.mvars.delayed (#5643)
Where before we had
```lean
#check fun x : Nat => ?a
-- fun x ↦ ?m.7 x : (x : Nat) → ?m.6 x
```
Now by default we have
```lean
#check fun x : Nat => ?a
-- fun x => ?a : (x : Nat) → ?m.6 x
```
In particular, delayed assignment metavariables such as `?m.7` pretty
print using the name of the metavariable they are delayed assigned to,
suppressing the bound variables used in the delayed assignment (hence
`?a` rather than `?a x`). Hovering over `?a` shows `?m.7 x`.

The benefit is that users can see the user-provided name in local
contexts. A justification for this pretty printing choice is that `?m.7
x` is supposed to stand for `?a`, and furthermore it is just as opaque
to assignment in defeq as `?a` is (however, when synthetic opaque
metavariables are made assignable, delayed assignments can be a little
less assignable than true synthetic opaque metavariables).

The original pretty printing behavior can be recovered using `set_option
pp.mvars.delayed true`.

This PR also extends the documentation for holes and synthetic holes,
with some technical details about what delayed assignments are. This
likely should be moved to the reference manual, but for now it is
included in this docstring.

(This PR is a simplified version of #3494, which has a round-trippable
notation for delayed assignments. The pretty printing in this PR is
unlikely to round trip, but it is better than the current situation,
which is that delayed assignment metavariables never round trip, and
plus it does not require introducing a new notation.)
2024-10-08 17:48:52 +00:00
Kyle Miller
6cdede33fb fix: make sure name literals use escaping when pretty printing (#5639)
The app unexpanders for `Name.mkStr1` through `Name.mkStr8` weren't
respecting the escaping rules for names. For example, ``#check `«a.b»``
would show `` `a.b``.

This PR folds the unexpanders into the name literal delaborator, where
escaping is already handled.
2024-10-08 17:36:49 +00:00
Kyle Miller
f1d3527fe8 fix: have Lean.Meta.ppGoal use hard newlines (#5640)
This function uses soft newlines in many places where hard newlines are
more appropriate. Pointed out by @gebner in #1967.
2024-10-08 17:36:08 +00:00
Kyle Miller
b2b450d7cb fix: now linters in general do not run on #guard_msgs itself (#5644)
The `#guard_msgs` command runs the command it is attached to as if it
were a top-level command. This is because the top-level command
elaborator runs linters, and we are interested in capturing linter
warnings using `#guard_msgs`. However, the linters will run on
`#guard_msgs` itself, leading sometimes to duplicate warnings (like for
the unused variable linter).

Rather than special-casing `#guard_msgs` in every affected linter, this
PR special-cases it in the top-level command elaborator itself. **Now
linters are only run if the command doesn't contain `#guard_msgs`.**
This way, the linters are only run on the sub-command that `#guard_msgs`
runs itself. This rule also keeps linters from running multiple times in
cases such as `set_option pp.mvars false in /-- ... -/ #guard_msgs in
...`.
2024-10-08 17:35:07 +00:00
Henrik Böving
abae95e170 feat: support umod in bv_decide (#5652) 2024-10-08 12:47:03 +00:00
Henrik Böving
e9ea99f6c6 feat: support udiv in bv_decide (#5628)
Co-authored-by: Siddharth <siddu.druid@gmail.com>
2024-10-08 10:40:00 +00:00
Siddharth
2ed7924bae chore: define udiv normal form to be /, resp. umod and % (#5645)
This follows the norm for all other Bitvector operations, and makes the
symbols `/` and `%` the simp normal form.

I'd imagine that @hargonix would prefer that this be merged after
https://github.com/leanprover/lean4/pull/5628, so as to prevent churn
for his PR. I'm happy to rebase the PR once the other PR lands.

---------

Co-authored-by: Henrik Böving <hargonix@gmail.com>
2024-10-08 08:49:46 +00:00
Siddharth
4415a81f35 chore: add Siddharth to authors list of BitVec (#5647)
Add @bollu to the authors list of the BitVec files :)
2024-10-08 08:01:17 +00:00
Joachim Breitner
3e75d8f742 fix: FunInd: avoid over-eta-expanding in preprocessing step (#5619)
fixes #5602
2024-10-07 19:47:43 +00:00
Henrik Böving
f1ff9cebf2 feat: more getLsbD bitblaster theory (#5637) 2024-10-07 17:26:23 +00:00
Henrik Böving
99a9d9b381 doc: remarks about multiplication (#5636) 2024-10-07 17:25:22 +00:00
Henrik Böving
1914a2b3f2 feat: add auxiliary bitblasters for negation and subtraction (#5635) 2024-10-07 16:33:06 +00:00
Siddharth
6312787c30 feat: lemmas for Bitvector division when denominator is zero (#5609)
These lemmas explain what happens when the denominator is zero with
`udiv`, `umod`, `sdiv`, `smod`. A follow-up PR will show what happens
with `smtUDiv` and `smtSMod`, since these need some more bitvector
theory.
These lemmas will be used by `bv_decide` for bitblasting.

The theorems `{sdiv, smod}_zero` are located after `neg` theory has been
built for the purpose of writing terse proofs.

---------

Co-authored-by: Tobias Grosser <github@grosser.es>
Co-authored-by: Tobias Grosser <tobias@grosser.es>
2024-10-07 15:58:12 +00:00
Marc Huisinga
ec5f206d80 fix: shutdown deadlock and crash desync (#5340)
This PR fixes three problems:
- When the language server is being stopped in a non-normal way without
going through the regular LSP shutdown protocol (e.g. by closing VS
Code), it could sometimes happen that both the watchdog and the file
worker were not properly terminated and lingered around forever,
resulting in zombie processes (#5296)
- When the file worker crashes and the user restarts it by making a
change to the document, the file worker would produce incorrect
diagnostics for the document until the file is restarted.
- (Minor) When the file worker would crash during initialization, the
error diagnostic would be reported on stderr instead of stdout

The deadlock-induced termination issue from #5296 should be resolved by
the following measures:
- The watchdog main task is always terminated with `IO.Process.exit` to
ensure that it terminates even if some other tasks in the process are
still running.
- The file worker communication task in the watchdog no longer waits for
the file worker process to terminate when writing to the client fails,
only when reading from the file worker fails.
- When the watchdog shuts down (either as a result of an orderly or a
non-normal shutdown), instead of waiting for the file worker
communication tasks to complete, it kills the file worker process. The
rationale behind this is that the file worker currently should have no
essential work to complete if the server is being stopped anyways, and
so waiting for the communication task is not necessary.

The file worker diagnostic desync after a crash was caused by us
tracking changes to the document of a crashed file worker twice: Once as
part of the document, and once as part of the queued messages to the
file worker. This meant that when the file worker was restarted, it
would receive the changes made to the document while the file worker was
crashed twice, leading to a desynced document state.

(Probably) fixes #5296.
2024-10-07 14:10:42 +00:00
Markus Himmel
d835616573 chore: fix MSYS2 build instructions (#5617) 2024-10-07 12:42:37 +00:00
Siddharth
9dac514c2f feat: Document Bitblasting in a documentation comment (#5620)
As requested by @kim-em at
https://github.com/leanprover/lean4/pull/5281#issuecomment-2376102963.
We provide a high-level overview of the workflow for adding new
bitblasting theorems, by using the `BitVec.mul` as a prototypical
example.
2024-10-07 11:44:04 +00:00
Tobias Grosser
c0617da18d feat: support at in ac_nf and use it in bv_normalize (#5618)
... while at it also call `trivial` to close goals that can be trivially
closed.

---------

Co-authored-by: Siddharth <siddu.druid@gmail.com>
Co-authored-by: Henrik Böving <hargonix@gmail.com>
2024-10-07 11:37:17 +00:00
Sebastian Ullrich
a3ee11103c chore: update stage0 2024-10-07 13:26:07 +02:00
Sebastian Ullrich
13e3a3839c fix: Lake: brittle dependency on env ext name 2024-10-07 13:26:07 +02:00
Lean stage0 autoupdater
0178f2b70d chore: update stage0 2024-10-04 15:25:08 +00:00
Lean stage0 autoupdater
4f5f39294d chore: update stage0 2024-10-04 13:55:42 +00:00
Joachim Breitner
d4fdb5d7c0 fix: getFunInfo, inferType to use withAtLeastTransparency, not withTransparency (#5563)
when the transparency mode is `.all`, then one expects `getFunInfo` and
`inferType` to also work with that transparency mode.

Fixes #5562
Fixes #2975 
Fixes #2194
2024-10-04 13:04:35 +00:00
Siddharth
f9048c132d chore: add bv_toNat tag for toNat_ofInt (#5608)
These were missing from the `bv_toNat` simp-set,
discovered when refactoring LNSym's simp-set:
https://github.com/leanprover/LNSym/pull/208
2024-10-03 19:20:50 +00:00
Henrik Böving
53c5470200 perf: remove List.redLength (#5605) 2024-10-03 14:57:33 +00:00
Sebastian Ullrich
3584a62411 fix: call hierarchy into (builtin_)initialize (#5560)
While `initialize` pretended it had the declaration name of the constant
to be initialized, missing declaration ranges for the latter led call
hierarchy etc. to ignore the definition
2024-10-03 12:03:44 +00:00
Kim Morrison
a4fda010f3 feat: Array/Option.unattach (#5586)
More support for automatically removing `.attach`, for `Array` and
`Option`.
2024-10-03 07:29:00 +00:00
Kim Morrison
b7d6a4b222 feat: adding Insert/Singleton/Union instances for HashMap/Set.Raw (#5590)
These were missing from https://github.com/leanprover/lean4/pull/5581.
2024-10-03 06:26:21 +00:00
Lean stage0 autoupdater
341c64a306 chore: update stage0 2024-10-03 06:56:06 +00:00
Mac Malone
a01166f045 refactor: reduce Reservoir build fetch attempts & warnings (#5600)
Lake no longer attempts to fetch the Reservoir build cache if the build
directory is already present. Plus, failure of the automatic fetch now
only produces a trace message, not a warning.
2024-10-03 01:12:53 +00:00
Kim Morrison
14f80172bc chore: typo in fix-pr-release.yml (#5601) 2024-10-02 23:04:39 +00:00
euprunin
8f88d94d97 chore: fix spelling mistakes (#5599)
Co-authored-by: euprunin <euprunin@users.noreply.github.com>
2024-10-02 21:32:22 +00:00
Markus Himmel
09dfe1c71c chore: induction-friendly List.min?_cons (#5594)
@kim-em, I'm happy to keep any subset of `foldl_min`, `foldl_min_right`,
`foldl_min_le`, `foldl_min_min_of_le` (should that one have been called
`foldl_min_le_of_le`?). Which ones do you like?
2024-10-02 14:10:15 +00:00
Kim Morrison
1b115eea42 feat: HashSet.Raw.all/any (#5591)
These were missing from #5582.
2024-10-02 06:04:59 +00:00
Kim Morrison
8da278e141 feat: variant of MVarId.tryClearMany (#5588)
Used in Aesop.
2024-10-02 05:26:40 +00:00
3892 changed files with 218218 additions and 45743 deletions

View File

@@ -39,7 +39,7 @@ Please put an X between the brackets as you perform the following steps:
### Versions
[Output of `#eval Lean.versionString`]
[Output of `#version` or `#eval Lean.versionString`]
[OS version, if not using live.lean-lang.org.]
### Additional Information

View File

@@ -5,6 +5,10 @@
* Include the link to your `RFC` or `bug` issue in the description.
* If the issue does not already have approval from a developer, submit the PR as draft.
* The PR title/description will become the commit message. Keep it up-to-date as the PR evolves.
* For `feat/fix` PRs, the first paragraph starting with "This PR" must be present and will become a
changelog entry unless the PR is labeled with `no-changelog`. If the PR does not have this label,
it must instead be categorized with one of the `changelog-*` labels (which will be done by a
reviewer for external PRs).
* A toolchain of the form `leanprover/lean4-pr-releases:pr-release-NNNN` for Linux and M-series Macs will be generated upon build. To generate binaries for Windows and Intel-based Macs as well, write a comment containing `release-ci` on its own line.
* If you rebase your PR onto `nightly-with-mathlib` then CI will test Mathlib against your PR.
* You can manage the `awaiting-review`, `awaiting-author`, and `WIP` labels yourself, by writing a comment containing one of these labels on its own line.
@@ -12,4 +16,6 @@
---
Closes #0000 (`RFC` or `bug` issue number fixed by this PR, if any)
This PR <short changelog summary for feat/fix, see above>.
Closes <`RFC` or `bug` issue number fixed by this PR, if any>

8
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
commit-message:
prefix: "chore: CI"

View File

@@ -17,6 +17,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: actionlint
uses: raven-actions/actionlint@v1
uses: raven-actions/actionlint@v2
with:
pyflakes: false # we do not use python scripts

20
.github/workflows/awaiting-mathlib.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: Check awaiting-mathlib label
on:
merge_group:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
jobs:
check-awaiting-mathlib:
runs-on: ubuntu-latest
steps:
- name: Check awaiting-mathlib label
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const { labels } = context.payload.pull_request;
if (labels.some(label => label.name == "awaiting-mathlib") && !labels.some(label => label.name == "builds-mathlib")) {
core.setFailed('PR is marked "awaiting-mathlib" but "builds-mathlib" label has not been applied yet by the bot');
}

246
.github/workflows/build-template.yml vendored Normal file
View File

@@ -0,0 +1,246 @@
name: build-template
on:
workflow_call:
inputs:
check-level:
type: string
required: true
config:
type: string
required: true
nightly:
type: string
required: true
LEAN_VERSION_MAJOR:
type: string
required: true
LEAN_VERSION_MINOR:
type: string
required: true
LEAN_VERSION_PATCH:
type: string
required: true
LEAN_SPECIAL_VERSION_DESC:
type: string
required: true
RELEASE_TAG:
type: string
required: true
jobs:
build:
if: github.event_name != 'schedule' || github.repository == 'leanprover/lean4'
strategy:
matrix:
include: ${{fromJson(inputs.config)}}
# complete all jobs
fail-fast: false
runs-on: ${{ matrix.os }}
defaults:
run:
shell: ${{ matrix.shell || 'nix develop -c bash -euxo pipefail {0}' }}
name: ${{ matrix.name }}
env:
# must be inside workspace
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_COMPRESS: true
# current cache limit
CCACHE_MAXSIZE: 200M
# squelch error message about missing nixpkgs channel
NIX_BUILD_SHELL: bash
LSAN_OPTIONS: max_leaks=10
# somehow MinGW clang64 (or cmake?) defaults to `g++` even though it doesn't exist
CXX: c++
MACOSX_DEPLOYMENT_TARGET: 10.15
steps:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
if: runner.os == 'Linux' && !matrix.cmultilib
- name: Install MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: clang64
# `:` means do not prefix with msystem
pacboy: "make: python: cmake clang ccache gmp libuv git: zip: unzip: diffutils: binutils: tree: zstd tar:"
if: runner.os == 'Windows'
- name: Install Brew Packages
run: |
brew install ccache tree zstd coreutils gmp libuv
if: runner.os == 'macOS'
- name: Checkout
uses: actions/checkout@v4
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: Open Nix shell once
run: true
if: runner.os == 'Linux'
# Do check out some CI-relevant files from virtual merge commit to accommodate CI changes on
# master (as the workflow files themselves are always taken from the merge)
# (needs to be after "Install *" to use the right shell)
- name: CI Merge Checkout
run: |
git fetch --depth=1 origin ${{ github.sha }}
git checkout FETCH_HEAD flake.nix flake.lock
if: github.event_name == 'pull_request'
# (needs to be after "Checkout" so files don't get overridden)
- name: Setup emsdk
uses: mymindstorm/setup-emsdk@v14
with:
version: 3.1.44
actions-cache-folder: emsdk
if: matrix.wasm
- name: Install 32bit c libs
run: |
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y gcc-multilib g++-multilib ccache libuv1-dev:i386 pkgconf:i386
if: matrix.cmultilib
- name: Cache
if: matrix.name != 'Linux Lake'
uses: actions/cache@v4
with:
path: |
.ccache
key: ${{ matrix.name }}-build-v3-${{ github.event.pull_request.head.sha }}
# fall back to (latest) previous cache
restore-keys: |
${{ matrix.name }}-build-v3
save-always: true
- name: Cache
if: matrix.name == 'Linux Lake'
uses: actions/cache@v4
with:
path: |
.ccache
build/stage1/**/*.trace
build/stage1/**/*.olean
build/stage1/**/*.ilean
build/stage1/**/*.c
build/stage1/**/*.c.o*
key: ${{ matrix.name }}-build-v3-${{ github.event.pull_request.head.sha }}
# fall back to (latest) previous cache
restore-keys: |
${{ matrix.name }}-build-v3
save-always: true
# open nix-shell once for initial setup
- name: Setup
run: |
ccache --zero-stats
if: runner.os == 'Linux'
- name: Set up NPROC
run: |
echo "NPROC=$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || echo 4)" >> $GITHUB_ENV
- name: Build
run: |
ulimit -c unlimited # coredumps
[ -d build ] || mkdir build
cd build
# arguments passed to `cmake`
# this also enables githash embedding into stage 1 library
OPTIONS=(-DCHECK_OLEAN_VERSION=ON)
OPTIONS+=(-DLEAN_EXTRA_MAKE_OPTS=-DwarningAsError=true)
if [[ -n '${{ matrix.cross_target }}' ]]; then
# used by `prepare-llvm`
export EXTRA_FLAGS=--target=${{ matrix.cross_target }}
OPTIONS+=(-DLEAN_PLATFORM_TARGET=${{ matrix.cross_target }})
fi
if [[ -n '${{ matrix.prepare-llvm }}' ]]; then
wget -q ${{ matrix.llvm-url }}
PREPARE="$(${{ matrix.prepare-llvm }})"
eval "OPTIONS+=($PREPARE)"
fi
if [[ -n '${{ matrix.release }}' && -n '${{ inputs.nightly }}' ]]; then
OPTIONS+=(-DLEAN_SPECIAL_VERSION_DESC=${{ inputs.nightly }})
fi
if [[ -n '${{ matrix.release }}' && -n '${{ inputs.RELEASE_TAG }}' ]]; then
OPTIONS+=(-DLEAN_VERSION_MAJOR=${{ inputs.LEAN_VERSION_MAJOR }})
OPTIONS+=(-DLEAN_VERSION_MINOR=${{ inputs.LEAN_VERSION_MINOR }})
OPTIONS+=(-DLEAN_VERSION_PATCH=${{ inputs.LEAN_VERSION_PATCH }})
OPTIONS+=(-DLEAN_VERSION_IS_RELEASE=1)
OPTIONS+=(-DLEAN_SPECIAL_VERSION_DESC=${{ inputs.LEAN_SPECIAL_VERSION_DESC }})
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
- name: Install
run: |
make -C build install
- name: Check Binaries
run: ${{ matrix.binary-check }} lean-*/bin/* || true
- name: Count binary symbols
run: |
for f in lean-*/bin/*; do
echo "$f: $(nm $f | grep " T " | wc -l) exported symbols"
done
if: matrix.name == 'Windows'
- name: List Install Tree
run: |
# omit contents of Init/, ...
tree --du -h lean-*-* | grep -E ' (Init|Lean|Lake|LICENSE|[a-z])'
- name: Pack
run: |
dir=$(echo lean-*-*)
mkdir pack
# high-compression tar.zst + zip for release, fast tar.zst otherwise
if [[ '${{ startsWith(github.ref, 'refs/tags/') && matrix.release }}' == true || -n '${{ inputs.nightly }}' || -n '${{ inputs.RELEASE_TAG }}' ]]; then
${{ matrix.tar || 'tar' }} cf - $dir | zstd -T0 --no-progress -19 -o pack/$dir.tar.zst
zip -rq pack/$dir.zip $dir
else
${{ matrix.tar || 'tar' }} cf - $dir | zstd -T0 --no-progress -o pack/$dir.tar.zst
fi
- uses: actions/upload-artifact@v4
if: matrix.release
with:
name: build-${{ matrix.name }}
path: pack/*
- name: Lean stats
run: |
build/stage1/bin/lean --stats src/Lean.lean
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
- name: Test Summary
uses: test-summary/action@v2
with:
paths: build/stage1/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
run: ${{ matrix.binary-check }} tests/compiler/534.lean.out
if: (!matrix.cross) && steps.test.conclusion != 'skipped'
- name: Build Stage 2
run: |
make -C build -j$NPROC stage2
if: matrix.test-speedcenter
- name: Check Stage 3
run: |
make -C build -j$NPROC check-stage3
if: matrix.test-speedcenter
- name: Test Speedcenter Benchmarks
run: |
# Necessary for some timing metrics but does not work on Namespace runners
# and we just want to test that the benchmarks run at all here
#echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid
export BUILD=$PWD/build PATH=$PWD/build/stage1/bin:$PATH
cd tests/bench
nix shell .#temci -c temci exec --config speedcenter.yaml --included_blocks fast --runs 1
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
if: matrix.name == 'Linux' && inputs.check-level >= 1
- name: CCache stats
run: ccache -s
- name: Show stacktrace for coredumps
if: failure() && runner.os == 'Linux'
run: |
for c in $(find . -name core); do
progbin="$(file $c | sed "s/.*execfn: '\([^']*\)'.*/\1/")"
echo bt | $GDB/bin/gdb -q $progbin $c || true
done

View File

@@ -11,7 +11,10 @@ jobs:
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 }}
sparse-checkout: src/Lean
sparse-checkout: |
src/Lean
src/Std
src/lake/Lake
- name: Check Prelude
run: |
failed_files=""
@@ -19,8 +22,8 @@ jobs:
if ! grep -q "^prelude$" "$file"; then
failed_files="$failed_files$file\n"
fi
done < <(find src/Lean -name '*.lean' -print0)
done < <(find src/Lean src/Std src/lake/Lake -name '*.lean' -print0)
if [ -n "$failed_files" ]; then
echo -e "The following files should use 'prelude':\n$failed_files"
exit 1
fi
fi

View File

@@ -20,9 +20,7 @@ jobs:
- name: Identify stage0 changes
run: |
git diff "${BASE:-HEAD^}..HEAD" --name-only -- stage0 |
grep -v -x -F $'stage0/src/stdlib_flags.h\nstage0/src/lean.mk.in' \
> "$RUNNER_TEMP/stage0" || true
git diff "${BASE:-HEAD^}..HEAD" --name-only -- stage0/stdlib > "$RUNNER_TEMP/stage0" || true
if test -s "$RUNNER_TEMP/stage0"
then
echo "CHANGES=yes" >> "$GITHUB_ENV"

View File

@@ -36,7 +36,9 @@ jobs:
# 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.result }}
matrix: ${{ steps.set-matrix.outputs.matrix }}
# secondary build jobs that should not block the CI success/merge queue
matrix-secondary: ${{ steps.set-matrix.outputs.matrix-secondary }}
# Should we make a nightly release? If so, this output contains the lean version string, else it is empty
nightly: ${{ steps.set-nightly.outputs.nightly }}
# Should this be the CI for a tagged release?
@@ -135,9 +137,9 @@ jobs:
console.log(`level: ${level}`);
// use large runners where available (original repo)
let large = ${{ github.repository == 'leanprover/lean4' }};
const isPr = "${{ github.event_name }}" == "pull_request";
let matrix = [
{
// portable release build: use channel with older glibc (2.27)
"name": "Linux LLVM",
"os": "ubuntu-latest",
"release": false,
@@ -152,6 +154,7 @@ jobs:
"CMAKE_OPTIONS": "-DLLVM=ON -DLLVM_CONFIG=${GITHUB_WORKSPACE}/build/llvm-host/bin/llvm-config"
},
{
// portable release build: use channel with older glibc (2.26)
"name": "Linux release",
"os": large ? "nscloud-ubuntu-22.04-amd64-4x8" : "ubuntu-latest",
"release": true,
@@ -163,6 +166,14 @@ jobs:
// foreign code may be linked against more recent glibc
"CTEST_OPTIONS": "-E 'foreign'"
},
{
"name": "Linux Lake",
"os": large ? "nscloud-ubuntu-22.04-amd64-4x8" : "ubuntu-latest",
// just a secondary PR build job for now
"check-level": isPr ? 0 : 3,
"secondary": true,
"CMAKE_OPTIONS": "-DUSE_LAKE=ON"
},
{
"name": "Linux",
"os": large ? "nscloud-ubuntu-22.04-amd64-4x8" : "ubuntu-latest",
@@ -175,8 +186,8 @@ jobs:
"os": "ubuntu-latest",
"check-level": 2,
"CMAKE_PRESET": "debug",
// exclude seriously slow tests
"CTEST_OPTIONS": "-E 'interactivetest|leanpkgtest|laketest|benchtest|bv_bitblast_stress'"
// exclude seriously slow/stackoverflowing tests
"CTEST_OPTIONS": "-E 'interactivetest|leanpkgtest|laketest|benchtest|bv_bitblast_stress|3807'"
},
// TODO: suddenly started failing in CI
/*{
@@ -204,12 +215,18 @@ jobs:
"os": "macos-14",
"CMAKE_OPTIONS": "-DLEAN_INSTALL_SUFFIX=-darwin_aarch64",
"release": true,
"check-level": 0,
"shell": "bash -euxo pipefail {0}",
"llvm-url": "https://github.com/leanprover/lean-llvm/releases/download/15.0.1/lean-llvm-aarch64-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
// Special handling for MacOS aarch64, we want:
// 1. To run it in PRs so Mac devs get PR toolchains (so secondary is sufficient)
// 2. To skip it in merge queues as it takes longer than the Linux build and adds
// little value in the merge queue
// 3. To run it in release (obviously)
"check-level": isPr ? 0 : 2,
"secondary": isPr,
},
{
"name": "Windows",
@@ -217,7 +234,7 @@ jobs:
"release": true,
"check-level": 2,
"shell": "msys2 {0}",
"CMAKE_OPTIONS": "-G \"Unix Makefiles\" -DUSE_GMP=OFF",
"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/15.0.1/lean-llvm-x86_64-w64-windows-gnu.tar.zst",
@@ -227,7 +244,7 @@ jobs:
{
"name": "Linux aarch64",
"os": "nscloud-ubuntu-22.04-arm64-4x8",
"CMAKE_OPTIONS": "-DUSE_GMP=OFF -DLEAN_INSTALL_SUFFIX=-linux_aarch64",
"CMAKE_OPTIONS": "-DLEAN_INSTALL_SUFFIX=-linux_aarch64",
"release": true,
"check-level": 2,
"shell": "nix develop .#oldGlibcAArch -c bash -euxo pipefail {0}",
@@ -238,221 +255,66 @@ jobs:
"name": "Linux 32bit",
"os": "ubuntu-latest",
// Use 32bit on stage0 and stage1 to keep oleans compatible
"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/",
"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,
"cross": true,
"shell": "bash -euxo pipefail {0}"
},
{
"name": "Web Assembly",
"os": "ubuntu-latest",
// Build a native 32bit binary in stage0 and use it to compile the oleans and the wasm build
"CMAKE_OPTIONS": "-DCMAKE_C_COMPILER_WORKS=1 -DSTAGE0_USE_GMP=OFF -DSTAGE0_LEAN_EXTRA_CXX_FLAGS='-m32' -DSTAGE0_LEANC_OPTS='-m32' -DSTAGE0_CMAKE_CXX_COMPILER=clang++ -DSTAGE0_CMAKE_C_COMPILER=clang -DSTAGE0_CMAKE_EXECUTABLE_SUFFIX=\"\" -DUSE_GMP=OFF -DMMAP=OFF -DSTAGE0_MMAP=OFF -DCMAKE_AR=../emsdk/emsdk-main/upstream/emscripten/emar -DCMAKE_TOOLCHAIN_FILE=../emsdk/emsdk-main/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DLEAN_INSTALL_SUFFIX=-linux_wasm32 -DSTAGE0_CMAKE_LIBRARY_PATH=/usr/lib/i386-linux-gnu/",
"wasm": true,
"cmultilib": true,
"release": true,
"check-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_libuv\\.lean\""
}
// {
// "name": "Web Assembly",
// "os": "ubuntu-latest",
// // Build a native 32bit binary in stage0 and use it to compile the oleans and the wasm build
// "CMAKE_OPTIONS": "-DCMAKE_C_COMPILER_WORKS=1 -DSTAGE0_USE_GMP=OFF -DSTAGE0_LEAN_EXTRA_CXX_FLAGS='-m32' -DSTAGE0_LEANC_OPTS='-m32' -DSTAGE0_CMAKE_CXX_COMPILER=clang++ -DSTAGE0_CMAKE_C_COMPILER=clang -DSTAGE0_CMAKE_EXECUTABLE_SUFFIX=\"\" -DUSE_GMP=OFF -DMMAP=OFF -DSTAGE0_MMAP=OFF -DCMAKE_AR=../emsdk/emsdk-main/upstream/emscripten/emar -DCMAKE_TOOLCHAIN_FILE=../emsdk/emsdk-main/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DLEAN_INSTALL_SUFFIX=-linux_wasm32 -DSTAGE0_CMAKE_LIBRARY_PATH=/usr/lib/i386-linux-gnu/",
// "wasm": true,
// "cmultilib": true,
// "release": true,
// "check-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\""
// }
];
console.log(`matrix:\n${JSON.stringify(matrix, null, 2)}`)
return matrix.filter((job) => level >= job["check-level"])
console.log(`matrix:\n${JSON.stringify(matrix, null, 2)}`);
matrix = matrix.filter((job) => level >= job["check-level"]);
core.setOutput('matrix', matrix.filter((job) => !job["secondary"]));
core.setOutput('matrix-secondary', matrix.filter((job) => job["secondary"]));
build:
needs: [configure]
if: github.event_name != 'schedule' || github.repository == 'leanprover/lean4'
strategy:
matrix:
include: ${{fromJson(needs.configure.outputs.matrix)}}
# complete all jobs
fail-fast: false
runs-on: ${{ matrix.os }}
defaults:
run:
shell: ${{ matrix.shell || 'nix develop -c bash -euxo pipefail {0}' }}
name: ${{ matrix.name }}
env:
# must be inside workspace
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_COMPRESS: true
# current cache limit
CCACHE_MAXSIZE: 200M
# squelch error message about missing nixpkgs channel
NIX_BUILD_SHELL: bash
LSAN_OPTIONS: max_leaks=10
# somehow MinGW clang64 (or cmake?) defaults to `g++` even though it doesn't exist
CXX: c++
MACOSX_DEPLOYMENT_TARGET: 10.15
steps:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
if: runner.os == 'Linux' && !matrix.cmultilib
- name: Install MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: clang64
# `:` means do not prefix with msystem
pacboy: "make: python: cmake clang ccache gmp libuv git: zip: unzip: diffutils: binutils: tree: zstd tar:"
if: runner.os == 'Windows'
- name: Install Brew Packages
run: |
brew install ccache tree zstd coreutils gmp libuv
if: runner.os == 'macOS'
- name: Checkout
uses: actions/checkout@v4
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 }}
# Do check out some CI-relevant files from virtual merge commit to accommodate CI changes on
# master (as the workflow files themselves are always taken from the merge)
# (needs to be after "Install *" to use the right shell)
- name: CI Merge Checkout
run: |
git fetch --depth=1 origin ${{ github.sha }}
git checkout FETCH_HEAD flake.nix flake.lock
if: github.event_name == 'pull_request'
# (needs to be after "Checkout" so files don't get overridden)
- name: Setup emsdk
uses: mymindstorm/setup-emsdk@v12
with:
version: 3.1.44
actions-cache-folder: emsdk
if: matrix.wasm
- name: Install 32bit c libs
run: |
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y gcc-multilib g++-multilib ccache libuv1-dev:i386
if: matrix.cmultilib
- name: Cache
uses: actions/cache@v4
with:
path: .ccache
key: ${{ matrix.name }}-build-v3-${{ github.event.pull_request.head.sha }}
# fall back to (latest) previous cache
restore-keys: |
${{ matrix.name }}-build-v3
save-always: true
# open nix-shell once for initial setup
- name: Setup
run: |
ccache --zero-stats
if: runner.os == 'Linux'
- name: Set up NPROC
run: |
echo "NPROC=$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || echo 4)" >> $GITHUB_ENV
- name: Build
run: |
mkdir build
cd build
# arguments passed to `cmake`
# this also enables githash embedding into stage 1 library
OPTIONS=(-DCHECK_OLEAN_VERSION=ON)
OPTIONS+=(-DLEAN_EXTRA_MAKE_OPTS=-DwarningAsError=true)
if [[ -n '${{ matrix.cross_target }}' ]]; then
# used by `prepare-llvm`
export EXTRA_FLAGS=--target=${{ matrix.cross_target }}
OPTIONS+=(-DLEAN_PLATFORM_TARGET=${{ matrix.cross_target }})
fi
if [[ -n '${{ matrix.prepare-llvm }}' ]]; then
wget -q ${{ matrix.llvm-url }}
PREPARE="$(${{ matrix.prepare-llvm }})"
eval "OPTIONS+=($PREPARE)"
fi
if [[ -n '${{ matrix.release }}' && -n '${{ needs.configure.outputs.nightly }}' ]]; then
OPTIONS+=(-DLEAN_SPECIAL_VERSION_DESC=${{ needs.configure.outputs.nightly }})
fi
if [[ -n '${{ matrix.release }}' && -n '${{ needs.configure.outputs.RELEASE_TAG }}' ]]; then
OPTIONS+=(-DLEAN_VERSION_MAJOR=${{ needs.configure.outputs.LEAN_VERSION_MAJOR }})
OPTIONS+=(-DLEAN_VERSION_MINOR=${{ needs.configure.outputs.LEAN_VERSION_MINOR }})
OPTIONS+=(-DLEAN_VERSION_PATCH=${{ needs.configure.outputs.LEAN_VERSION_PATCH }})
OPTIONS+=(-DLEAN_VERSION_IS_RELEASE=1)
OPTIONS+=(-DLEAN_SPECIAL_VERSION_DESC=${{ needs.configure.outputs.LEAN_SPECIAL_VERSION_DESC }})
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
- name: Install
run: |
make -C build install
- name: Check Binaries
run: ${{ matrix.binary-check }} lean-*/bin/* || true
- name: Count binary symbols
run: |
for f in lean-*/bin/*; do
echo "$f: $(nm $f | grep " T " | wc -l) exported symbols"
done
if: matrix.name == 'Windows'
- name: List Install Tree
run: |
# omit contents of Init/, ...
tree --du -h lean-*-* | grep -E ' (Init|Lean|Lake|LICENSE|[a-z])'
- name: Pack
run: |
dir=$(echo lean-*-*)
mkdir pack
# high-compression tar.zst + zip for release, fast tar.zst otherwise
if [[ '${{ startsWith(github.ref, 'refs/tags/') && matrix.release }}' == true || -n '${{ needs.configure.outputs.nightly }}' || -n '${{ needs.configure.outputs.RELEASE_TAG }}' ]]; then
${{ matrix.tar || 'tar' }} cf - $dir | zstd -T0 --no-progress -19 -o pack/$dir.tar.zst
zip -rq pack/$dir.zip $dir
else
${{ matrix.tar || 'tar' }} cf - $dir | zstd -T0 --no-progress -o pack/$dir.tar.zst
fi
- uses: actions/upload-artifact@v4
if: matrix.release
with:
name: build-${{ matrix.name }}
path: pack/*
- name: Lean stats
run: |
build/stage1/bin/lean --stats src/Lean.lean
if: ${{ !matrix.cross }}
- name: Test
id: test
run: |
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) && needs.configure.outputs.check-level >= 1
- name: Test Summary
uses: test-summary/action@v2
with:
paths: build/stage1/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
run: ${{ matrix.binary-check }} tests/compiler/534.lean.out
if: (!matrix.cross) && steps.test.conclusion != 'skipped'
- name: Build Stage 2
run: |
make -C build -j$NPROC stage2
if: matrix.test-speedcenter
- name: Check Stage 3
run: |
make -C build -j$NPROC check-stage3
if: matrix.test-speedcenter
- name: Test Speedcenter Benchmarks
run: |
# Necessary for some timing metrics but does not work on Namespace runners
# and we just want to test that the benchmarks run at all here
#echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid
export BUILD=$PWD/build PATH=$PWD/build/stage1/bin:$PATH
cd tests/bench
nix shell .#temci -c temci exec --config speedcenter.yaml --included_blocks fast --runs 1
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
if: matrix.name == 'Linux' && needs.configure.outputs.check-level >= 1
- name: CCache stats
run: ccache -s
needs: [configure]
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 }}
LEAN_VERSION_PATCH: ${{ needs.configure.outputs.LEAN_VERSION_PATCH }}
LEAN_SPECIAL_VERSION_DESC: ${{ needs.configure.outputs.LEAN_SPECIAL_VERSION_DESC }}
RELEASE_TAG: ${{ needs.configure.outputs.RELEASE_TAG }}
secrets: inherit
# build jobs that should not be considered by `all-done` below
build-secondary:
needs: [configure]
if: needs.configure.outputs.matrix-secondary != '[]'
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 }}
LEAN_VERSION_PATCH: ${{ needs.configure.outputs.LEAN_VERSION_PATCH }}
LEAN_SPECIAL_VERSION_DESC: ${{ needs.configure.outputs.LEAN_SPECIAL_VERSION_DESC }}
RELEASE_TAG: ${{ needs.configure.outputs.RELEASE_TAG }}
secrets: inherit
# This job collects results from all the matrix jobs
# This can be made the required job, instead of listing each
# This can be made the "required" job, instead of listing each
# matrix job separately
all-done:
name: Build matrix complete
@@ -492,7 +354,7 @@ jobs:
with:
path: artifacts
- name: Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
files: artifacts/*/*
fail_on_unmatched_files: true
@@ -536,7 +398,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@v1
uses: softprops/action-gh-release@v2
with:
body_path: diff.md
prerelease: true

View File

@@ -1,7 +1,8 @@
# This workflow allows any user to add one of the `awaiting-review`, `awaiting-author`, `WIP`,
# or `release-ci` labels by commenting on the PR or issue.
# `release-ci`, or a `changelog-XXX` label by commenting on the PR or issue.
# If any labels from the set {`awaiting-review`, `awaiting-author`, `WIP`} are added, other labels
# from that set are removed automatically at the same time.
# Similarly, if any `changelog-XXX` label is added, other `changelog-YYY` labels are removed.
name: Label PR based on Comment
@@ -11,7 +12,7 @@ on:
jobs:
update-label:
if: github.event.issue.pull_request != null && (contains(github.event.comment.body, 'awaiting-review') || contains(github.event.comment.body, 'awaiting-author') || contains(github.event.comment.body, 'WIP') || contains(github.event.comment.body, 'release-ci'))
if: github.event.issue.pull_request != null && (contains(github.event.comment.body, 'awaiting-review') || contains(github.event.comment.body, 'awaiting-author') || contains(github.event.comment.body, 'WIP') || contains(github.event.comment.body, 'release-ci') || contains(github.event.comment.body, 'changelog-'))
runs-on: ubuntu-latest
steps:
@@ -20,13 +21,14 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { owner, repo, number: issue_number } = context.issue;
const { owner, repo, number: issue_number } = context.issue;
const commentLines = context.payload.comment.body.split('\r\n');
const awaitingReview = commentLines.includes('awaiting-review');
const awaitingAuthor = commentLines.includes('awaiting-author');
const wip = commentLines.includes('WIP');
const releaseCI = commentLines.includes('release-ci');
const changelogMatch = commentLines.find(line => line.startsWith('changelog-'));
if (awaitingReview || awaitingAuthor || wip) {
await github.rest.issues.removeLabel({ owner, repo, issue_number, name: 'awaiting-review' }).catch(() => {});
@@ -47,3 +49,19 @@ jobs:
if (releaseCI) {
await github.rest.issues.addLabels({ owner, repo, issue_number, labels: ['release-ci'] });
}
if (changelogMatch) {
const changelogLabel = changelogMatch.trim();
const { data: existingLabels } = await github.rest.issues.listLabelsOnIssue({ owner, repo, issue_number });
const changelogLabels = existingLabels.filter(label => label.name.startsWith('changelog-'));
// Remove all other changelog labels
for (const label of changelogLabels) {
if (label.name !== changelogLabel) {
await github.rest.issues.removeLabel({ owner, repo, issue_number, name: label.name }).catch(() => {});
}
}
// Add the new changelog label
await github.rest.issues.addLabels({ owner, repo, issue_number, labels: [changelogLabel] });
}

View File

@@ -96,7 +96,7 @@ jobs:
nix build $NIX_BUILD_ARGS .#cacheRoots -o push-build
- name: Test
run: |
nix build --keep-failed $NIX_BUILD_ARGS .#test -o push-test || (ln -s /tmp/nix-build-*/source/src/build/ ./push-test; false)
nix build --keep-failed $NIX_BUILD_ARGS .#test -o push-test || (ln -s /tmp/nix-build-*/build/source/src/build ./push-test; false)
- name: Test Summary
uses: test-summary/action@v2
with:
@@ -110,14 +110,6 @@ jobs:
# https://github.com/netlify/cli/issues/1809
cp -r --dereference ./result ./dist
if: matrix.name == 'Nix Linux'
- name: Check manual for broken links
id: lychee
uses: lycheeverse/lychee-action@v1.9.0
with:
fail: false # report errors but do not block CI on temporary failures
# gmplib.org consistently times out from GH actions
# the GitHub token is to avoid rate limiting
args: --base './dist' --no-progress --github-token ${{ secrets.GITHUB_TOKEN }} --exclude 'gmplib.org' './dist/**/*.html'
- name: Rebuild Nix Store Cache
run: |
rm -rf nix-store-cache || true
@@ -129,7 +121,7 @@ jobs:
python3 -c 'import base64; print("alias="+base64.urlsafe_b64encode(bytes.fromhex("${{github.sha}}")).decode("utf-8").rstrip("="))' >> "$GITHUB_OUTPUT"
echo "message=`git log -1 --pretty=format:"%s"`" >> "$GITHUB_OUTPUT"
- name: Publish manual to Netlify
uses: nwtgck/actions-netlify@v2.0
uses: nwtgck/actions-netlify@v3.0
id: publish-manual
with:
publish-dir: ./dist

25
.github/workflows/pr-body.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Check PR body for changelog convention
on:
merge_group:
pull_request:
types: [opened, synchronize, reopened, edited, labeled, converted_to_draft, ready_for_review]
jobs:
check-pr-body:
runs-on: ubuntu-latest
steps:
- name: Check PR body
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const { title, body, labels, draft } = context.payload.pull_request;
if (!draft && /^(feat|fix):/.test(title) && !labels.some(label => label.name == "changelog-no")) {
if (!labels.some(label => label.name.startsWith("changelog-"))) {
core.setFailed('feat/fix PR must have a `changelog-*` label');
}
if (!/^This PR [^<]/.test(body)) {
core.setFailed('feat/fix PR must have changelog summary starting with "This PR ..." as first line.');
}
}

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@v2 # https://github.com/marketplace/actions/download-workflow-artifact
uses: dawidd6/action-download-artifact@v9 # https://github.com/marketplace/actions/download-workflow-artifact
with:
run_id: ${{ github.event.workflow_run.id }}
path: artifacts
@@ -60,7 +60,7 @@ jobs:
GH_TOKEN: ${{ secrets.PR_RELEASES_TOKEN }}
- name: Release
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
name: Release for PR ${{ steps.workflow-info.outputs.pullRequestNumber }}
# There are coredumps files here as well, but all in deeper subdirectories.
@@ -75,7 +75,7 @@ jobs:
- name: Report release status
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: actions/github-script@v6
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createCommitStatus({
@@ -111,7 +111,7 @@ jobs:
- name: 'Setup jq'
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
uses: dcarbone/install-jq-action@v1.0.1
uses: dcarbone/install-jq-action@v3.0.1
# Check that the most recently nightly coincides with 'git merge-base HEAD master'
- name: Check merge-base and nightly-testing-YYYY-MM-DD
@@ -155,6 +155,20 @@ jobs:
fi
if [[ -n "$MESSAGE" ]]; then
# Check if force-mathlib-ci label is present
LABELS="$(curl --retry 3 --location --silent \
-H "Authorization: token ${{ secrets.MATHLIB4_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-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"
FORCE_CI=true
else
MESSAGE="$MESSAGE You can force Mathlib CI using the \`force-mathlib-ci\` label."
fi
echo "Checking existing messages"
@@ -201,14 +215,19 @@ jobs:
else
echo "The message already exists in the comment body."
fi
echo "mathlib_ready=false" >> "$GITHUB_OUTPUT"
if [[ "$FORCE_CI" == "true" ]]; then
echo "mathlib_ready=true" >> "$GITHUB_OUTPUT"
else
echo "mathlib_ready=false" >> "$GITHUB_OUTPUT"
fi
else
echo "mathlib_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@v6
uses: actions/github-script@v7
with:
script: |
const description =
@@ -252,7 +271,7 @@ jobs:
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 "This shouldn't be possible: couldn't find a 'nightly-testing-${MOST_RECENT_NIGHTLY}' tag at Batteries. Falling back to 'nightly-testing'."
echo "Couldn't find a 'nightly-testing-${MOST_RECENT_NIGHTLY}' tag at Batteries. Falling back to 'nightly-testing'."
BASE=nightly-testing
fi
@@ -316,7 +335,7 @@ jobs:
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 "This shouldn't be possible: couldn't find a 'nightly-testing-${MOST_RECENT_NIGHTLY}' branch at Mathlib. Falling back to 'nightly-testing'."
echo "Couldn't find a 'nightly-testing-${MOST_RECENT_NIGHTLY}' branch at Mathlib. Falling back to 'nightly-testing'."
BASE=nightly-testing
fi
@@ -340,7 +359,7 @@ jobs:
# (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
lake update batteries
get add lake-manifest.json
git add lake-manifest.json
git commit --allow-empty -m "Trigger CI for https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
fi

View File

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

14
.gitpod.Dockerfile vendored Normal file
View File

@@ -0,0 +1,14 @@
# You can find the new timestamped tags here: https://hub.docker.com/r/gitpod/workspace-full/tags
FROM gitpod/workspace-full
USER root
RUN apt-get update && apt-get install git libgmp-dev libuv1-dev cmake ccache clang -y && apt-get clean
USER gitpod
# Install and configure elan
RUN curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh -s -- -y --default-toolchain none
ENV PATH="/home/gitpod/.elan/bin:${PATH}"
# Create a dummy toolchain so that we can pre-register it with elan
RUN mkdir -p /workspace/lean4/build/release/stage1/bin && touch /workspace/lean4/build/release/stage1/bin/lean && elan toolchain link lean4 /workspace/lean4/build/release/stage1
RUN mkdir -p /workspace/lean4/build/release/stage0/bin && touch /workspace/lean4/build/release/stage0/bin/lean && elan toolchain link lean4-stage0 /workspace/lean4/build/release/stage0

11
.gitpod.yml Normal file
View File

@@ -0,0 +1,11 @@
image:
file: .gitpod.Dockerfile
vscode:
extensions:
- leanprover.lean4
tasks:
- name: Release build
init: cmake --preset release
command: make -C build/release -j$(nproc || sysctl -n hw.logicalcpu)

View File

@@ -15,7 +15,7 @@ foreach(var ${vars})
# must forward options that generate incompatible .olean format
list(APPEND STAGE0_ARGS "-D${var}=${${var}}")
endif()
if("${var}" MATCHES "LLVM*")
if("${var}" MATCHES "LLVM*|PKG_CONFIG|USE_LAKE")
list(APPEND STAGE0_ARGS "-D${var}=${${var}}")
endif()
elseif(("${var}" MATCHES "CMAKE_.*") AND NOT ("${var}" MATCHES "CMAKE_BUILD_TYPE") AND NOT ("${var}" MATCHES "CMAKE_HOME_DIRECTORY"))
@@ -44,10 +44,11 @@ if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
string(APPEND CADICAL_CXXFLAGS " -DNUNLOCKED")
endif()
string(APPEND CADICAL_CXXFLAGS " -DNCLOSEFROM")
ExternalProject_add(cadical
PREFIX cadical
GIT_REPOSITORY https://github.com/arminbiere/cadical
GIT_TAG rel-1.9.5
GIT_TAG rel-2.1.2
CONFIGURE_COMMAND ""
# https://github.com/arminbiere/cadical/blob/master/BUILD.md#manual-build
BUILD_COMMAND $(MAKE) -f ${CMAKE_SOURCE_DIR}/src/cadical.mk CMAKE_EXECUTABLE_SUFFIX=${CMAKE_EXECUTABLE_SUFFIX} CXX=${CADICAL_CXX} CXXFLAGS=${CADICAL_CXXFLAGS}
@@ -64,8 +65,8 @@ ExternalProject_add(stage0
SOURCE_SUBDIR src
BINARY_DIR stage0
# do not rebuild stage0 when git hash changes; it's not from this commit anyway
# (however, `CHECK_OLEAN_VERSION=ON` in CI will override this as we need to
# embed the githash into the stage 1 library built by stage 0)
# (however, CI will override this as we need to embed the githash into the stage 1 library built
# by stage 0)
CMAKE_ARGS -DSTAGE=0 -DUSE_GITHASH=OFF ${PLATFORM_ARGS} ${STAGE0_ARGS}
BUILD_ALWAYS ON # cmake doesn't auto-detect changes without a download method
INSTALL_COMMAND "" # skip install
@@ -79,6 +80,7 @@ ExternalProject_add(stage1
BUILD_ALWAYS ON
INSTALL_COMMAND ""
DEPENDS stage0
STEP_TARGETS configure
)
ExternalProject_add(stage2
SOURCE_DIR "${LEAN_SOURCE_DIR}"

View File

@@ -26,7 +26,7 @@
"displayName": "Sanitize build config",
"cacheVariables": {
"LEAN_EXTRA_CXX_FLAGS": "-fsanitize=address,undefined",
"LEANC_EXTRA_FLAGS": "-fsanitize=address,undefined -fsanitize-link-c++-runtime",
"LEANC_EXTRA_CC_FLAGS": "-fsanitize=address,undefined -fsanitize-link-c++-runtime",
"SMALL_ALLOCATOR": "OFF",
"BSYMBOLIC": "OFF"
},

View File

@@ -4,22 +4,20 @@
# Listed persons will automatically be asked by GitHub to review a PR touching these paths.
# If multiple names are listed, a review by any of them is considered sufficient by default.
/.github/ @Kha @semorrison
/RELEASES.md @semorrison
/.github/ @kim-em
/RELEASES.md @kim-em
/src/kernel/ @leodemoura
/src/lake/ @tydeu
/src/Lean/Compiler/ @leodemoura
/src/Lean/Data/Lsp/ @mhuisi
/src/Lean/Elab/Deriving/ @semorrison
/src/Lean/Elab/Tactic/ @semorrison
/src/Lean/Elab/Deriving/ @kim-em
/src/Lean/Elab/Tactic/ @kim-em
/src/Lean/Language/ @Kha
/src/Lean/Meta/Tactic/ @leodemoura
/src/Lean/Parser/ @Kha
/src/Lean/PrettyPrinter/ @Kha
/src/Lean/PrettyPrinter/Delaborator/ @kmill
/src/Lean/PrettyPrinter/ @kmill
/src/Lean/Server/ @mhuisi
/src/Lean/Widget/ @Vtec234
/src/Init/Data/ @semorrison
/src/Init/Data/ @kim-em
/src/Init/Data/Array/Lemmas.lean @digama0
/src/Init/Data/List/Lemmas.lean @digama0
/src/Init/Data/List/BasicAux.lean @digama0
@@ -45,3 +43,4 @@
/src/Std/ @TwoFX
/src/Std/Tactic/BVDecide/ @hargoniX
/src/Lean/Elab/Tactic/BVDecide/ @hargoniX
/src/Std/Sat/ @hargoniX

View File

@@ -6,7 +6,8 @@ This is the repository for **Lean 4**.
- [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/)
- [Manual](https://lean-lang.org/lean4/doc/)
- [Documentation Overview](https://lean-lang.org/lean4/doc/)
- [Language Reference](https://lean-lang.org/doc/reference/latest/)
- [Release notes](RELEASES.md) starting at v4.0.0-m3
- [Examples](https://lean-lang.org/lean4/doc/examples.html)
- [External Contribution Guidelines](CONTRIBUTING.md)

File diff suppressed because it is too large Load Diff

View File

@@ -1 +0,0 @@
[0829/202002.254:ERROR:crashpad_client_win.cc(868)] not connected

View File

@@ -13,61 +13,13 @@
- [The Well-Typed Interpreter](examples/interp.lean.md)
- [Dependent de Bruijn Indices](examples/deBruijn.lean.md)
- [Parametric Higher-Order Abstract Syntax](examples/phoas.lean.md)
# Language Manual
<!-- - [Using Lean](./using_lean.md) -->
<!-- - [Lexical Structure](./lexical_structure.md) -->
<!-- - [Expressions](./expressions.md) -->
<!-- - [Declarations](./declarations.md) -->
- [Organizational features](./organization.md)
- [Sections](./sections.md)
- [Namespaces](./namespaces.md)
- [Implicit Arguments](./implicit.md)
- [Auto Bound Implicit Arguments](./autobound.md)
<!-- - [Dependent Types](./deptypes.md) -->
<!-- - [Simple Type Theory](./simptypes.md) -->
<!-- - [Types as objects](./typeobjs.md) -->
<!-- - [Function Abstraction and Evaluation](./funabst.md) -->
<!-- - [Introducing Definitions](./introdef.md) -->
<!-- - [What makes dependent type theory dependent?](./dep.md) -->
<!-- - [Tactics](./tactics.md) -->
- [Syntax Extensions](./syntax.md)
- [The `do` Notation](./do.md)
- [String Interpolation](./stringinterp.md)
- [User-Defined Notation](./notation.md)
- [Macro Overview](./macro_overview.md)
- [Elaborators](./elaborators.md)
- [Examples](./syntax_examples.md)
- [Syntax Examples](./syntax_examples.md)
- [Balanced Parentheses](./syntax_example.md)
- [Arithmetic DSL](./metaprogramming-arith.md)
- [Declaring New Types](./decltypes.md)
- [Enumerated Types](./enum.md)
- [Inductive Types](./inductive.md)
- [Structures](./struct.md)
- [Type classes](./typeclass.md)
- [Unification Hints](./unifhint.md)
- [Builtin Types](./builtintypes.md)
- [Natural number](./nat.md)
- [Integer](./int.md)
- [Fixed precision unsigned integer](./uint.md)
- [Float](./float.md)
- [Array](./array.md)
- [List](./list.md)
- [Character](./char.md)
- [String](./string.md)
- [Option](./option.md)
- [Thunk](./thunk.md)
- [Task and Thread](./task.md)
- [Functions](./functions.md)
- [Monads](./monads/intro.md)
- [Functor](./monads/functors.lean.md)
- [Applicative](./monads/applicatives.lean.md)
- [Monad](./monads/monads.lean.md)
- [Reader](./monads/readers.lean.md)
- [State](./monads/states.lean.md)
- [Except](./monads/except.lean.md)
- [Transformers](./monads/transformers.lean.md)
- [Laws](./monads/laws.lean.md)
# Language Manual
- [The Lean Reference Manual](./reference.md)
# Other

View File

@@ -1,77 +0,0 @@
# Arrays
The `Array` type implements a *dynamic* (aka growable) array.
It is defined as
```lean
# namespace hidden
structure Array (α : Type u) where
data : List α
# end hidden
```
but its execution time representation is optimized, and it is similar to C++ `std::vector<T>` and Rust `Vec<T>`.
The Lean type checker has no special support for reducing `Array`s.
You can create arrays in several ways. You can create a small array by listing consecutive values between
`#[` and `]` and separated by commas, as shown in the following examples.
```lean
#check #[1, 2, 3] -- Array Nat
#check #[] -- Array ?m
```
The type of the array elements is inferred from the literals used and must be consistent.
```lean
#check #["hello", "world"] -- Array String
-- The following is not valid
#check_failure #[10, "hello"]
```
Recall that the command `#check_failure <term>` only succeeds when the given term is not type correct.
To create an array of size `n` in which all the elements are initialized to some value `a`, use `mkArray`.
```lean
#eval mkArray 5 'a'
-- #['a', 'a', 'a', 'a', 'a']
```
## Accessing elements
You can access array elements by using brackets (`[` and `]`).
```lean
def f (a : Array Nat) (i : Fin a.size) :=
a[i] + a[i]
```
Note that the index `i` has type `Fin a.size`, i.e., it is natural number less than `a.size`.
You can also write
```lean
def f (a : Array Nat) (i : Nat) (h : i < a.size) :=
a[i] + a[i]
```
The bracket operator is whitespace sensitive.
```lean
def f (xs : List Nat) : List Nat :=
xs ++ xs
def as : Array Nat :=
#[1, 2, 3, 4]
def idx : Fin 4 :=
2
#eval f [1, 2, 3] -- This is a function application
#eval as[idx] -- This is an array access
```
The notation `a[i]` has two variants: `a[i]!` and `a[i]?`. In both cases, `i` has type `Nat`. The first one
produces a panic error message if the index `i` is out of bounds. The latter returns an `Option` type.
```lean
#eval #['a', 'b', 'c'][1]?
-- some 'b'
#eval #['a', 'b', 'c'][5]?
-- none
#eval #['a', 'b', 'c'][1]!
-- 'b!
```

View File

@@ -1,47 +0,0 @@
## Auto Bound Implicit Arguments
In the previous section, we have shown how implicit arguments make functions more convenient to use.
However, functions such as `compose` are still quite verbose to define. Note that the universe
polymorphic `compose` is even more verbose than the one previously defined.
```lean
universe u v w
def compose {α : Type u} {β : Type v} {γ : Type w}
(g : β γ) (f : α β) (x : α) : γ :=
g (f x)
```
You can avoid the `universe` command by providing the universe parameters when defining `compose`.
```lean
def compose.{u, v, w}
{α : Type u} {β : Type v} {γ : Type w}
(g : β γ) (f : α β) (x : α) : γ :=
g (f x)
```
Lean 4 supports a new feature called *auto bound implicit arguments*. It makes functions such as
`compose` much more convenient to write. When Lean processes the header of a declaration,
any unbound identifier is automatically added as an implicit argument *if* it is a single lower case or
greek letter. With this feature, we can write `compose` as
```lean
def compose (g : β γ) (f : α β) (x : α) : γ :=
g (f x)
#check @compose
-- {β : Sort u_1} → {γ : Sort u_2} → {α : Sort u_3} → (β → γ) → (α → β) → αγ
```
Note that, Lean inferred a more general type using `Sort` instead of `Type`.
Although we love this feature and use it extensively when implementing Lean,
we realize some users may feel uncomfortable with it. Thus, you can disable it using
the command `set_option autoImplicit false`.
```lean
set_option autoImplicit false
/- The following definition produces `unknown identifier` errors -/
-- def compose (g : β → γ) (f : α → β) (x : α) : γ :=
-- g (f x)
```
The Lean language server provides [semantic highlighting](./semantic_highlighting.md) information to editors, and it provides
visual feedback whether an identifier has been interpreted as an auto bound implicit argument.

View File

@@ -3,7 +3,7 @@ authors = ["Leonardo de Moura", "Sebastian Ullrich"]
language = "en"
multilingual = false
src = "."
title = "Lean Manual"
title = "Lean Documentation Overview"
[build]
build-dir = "out"

View File

@@ -1,25 +0,0 @@
# Builtin Types
## Numeric Operations
Lean supports the basic mathematical operations youd expect for all of the number types: addition, subtraction, multiplication, division, and remainder.
The following code shows how youd use each one in a `def` commands:
```lean
-- addition
def sum := 5 + 10
-- subtraction
def difference := 95.5 - 4.3
-- multiplication
def product := 4 * 30
-- division
def quotient := 53.7 / 32.2
-- remainder/modulo
def modulo := 43 % 5
```
Each expression in these statements uses a mathematical operator and evaluates to a single value.

View File

@@ -1,11 +0,0 @@
# Characters
A value of type `Char`, also known as a character, is a [Unicode scalar value](https://www.unicode.org/glossary/#unicode_scalar_value). It is represented using an unsigned 32-bit integer and is statically guaranteed to be a valid Unicode scalar value.
Syntactically, character literals are enclosed in single quotes.
```lean
#eval 'a' -- 'a'
#eval '' -- '∀'
```
Characters are ordered and can be decidably compared using the relational operators `=`, `<`, `≤`, `>`, `≥`.

View File

@@ -590,9 +590,9 @@ This table should be read as follows:
* No other proofs were attempted, either because the parameter has a type without a non-trivial ``WellFounded`` instance (parameter 3), or because it is already clear that no decreasing measure can be found.
Lean will print the termination argument it found if ``set_option showInferredTerminationBy true`` is set.
Lean will print the termination measure it found if ``set_option showInferredTerminationBy true`` is set.
If Lean does not find the termination argument, or if you want to be explicit, you can append a `termination_by` clause to the function definition, after the function's body, but before the `where` clause if present. It is of the form
If Lean does not find the termination measure, or if you want to be explicit, you can append a `termination_by` clause to the function definition, after the function's body, but before the `where` clause if present. It is of the form
```
termination_by e
```
@@ -672,7 +672,7 @@ def num_consts_lst : List Term → Nat
end
```
In a set of mutually recursive function, either all or no functions must have an explicit termination argument (``termination_by``). A change of the default termination tactic (``decreasing_by``) only affects the proofs about the recursive calls of that function, not the other functions in the group.
In a set of mutually recursive function, either all or no functions must have an explicit termination measure (``termination_by``). A change of the default termination tactic (``decreasing_by``) only affects the proofs about the recursive calls of that function, not the other functions in the group.
```
mutual
@@ -764,11 +764,12 @@ Structures and Records
The ``structure`` command in Lean is used to define an inductive data type with a single constructor and to define its projections at the same time. The syntax is as follows:
```
structure Foo (a : α) extends Bar, Baz : Sort u :=
structure Foo (a : α) : Sort u extends Bar, Baz :=
constructor :: (field₁ : β₁) ... (fieldₙ : βₙ)
```
Here ``(a : α)`` is a telescope, that is, the parameters to the inductive definition. The name ``constructor`` followed by the double colon is optional; if it is not present, the name ``mk`` is used by default. The keyword ``extends`` followed by a list of previously defined structures is also optional; if it is present, an instance of each of these structures is included among the fields to ``Foo``, and the types ``βᵢ`` can refer to their fields as well. The output type, ``Sort u``, can be omitted, in which case Lean infers to smallest non-``Prop`` sort possible. Finally, ``(field₁ : β₁) ... (fieldₙ : βₙ)`` is a telescope relative to ``(a : α)`` and the fields in ``bar`` and ``baz``.
Here ``(a : α)`` is a telescope, that is, the parameters to the inductive definition. The name ``constructor`` followed by the double colon is optional; if it is not present, the name ``mk`` is used by default. The keyword ``extends`` followed by a list of previously defined structures is also optional; if it is present, an instance of each of these structures is included among the fields to ``Foo``, and the types ``βᵢ`` can refer to their fields as well. The output type, ``Sort u``, can be omitted, in which case Lean infers to smallest non-``Prop`` sort possible (unless all the fields are ``Prop``, in which case it infers ``Prop``).
Finally, ``(field₁ : β₁) ... (fieldₙ : βₙ)`` is a telescope relative to ``(a : α)`` and the fields in ``bar`` and ``baz``.
The declaration above is syntactic sugar for an inductive type declaration, and so results in the addition of the following constants to the environment:

View File

@@ -1,29 +0,0 @@
# Declaring New Types
In Lean's library, every concrete type other than the universes and every type constructor other than the dependent function type is
an instance of a general family of type constructions known as *inductive types*. It is remarkable that it is possible to develop
complex programs and formalize mathematics based on nothing more than the type universes, dependent function types,
and inductive types; everything else follows from those.
Intuitively, an inductive type is built up from a specified list of constructors. In Lean, the basic syntax for specifying such a type is as follows:
```
inductive NewType where
| constructor_1 : ... → NewType
| constructor_2 : ... → NewType
...
| constructor_n : ... → NewType
```
The intuition is that each constructor specifies a way of building new objects of ``NewType``, possibly from previously constructed values.
The type ``NewType`` consists of nothing more than the objects that are constructed in this way.
We will see below that the arguments to the constructors can include objects of type ``NewType``,
subject to a certain "positivity" constraint, which guarantees that elements of ``NewType`` are built
from the bottom up. Roughly speaking, each ``...`` can be any function type constructed from ``NewType``
and previously defined types, in which ``NewType`` appears, if at all, only as the "target" of the function type.
We will provide a number of examples of inductive types. We will also consider slight generalizations of the scheme above,
to mutually defined inductive types, and so-called *inductive families*.
Every inductive type comes with constructors, which show how to construct an element of the type, and elimination rules,
which show how to "use" an element of the type in another construction.

View File

@@ -103,10 +103,21 @@ your PR using rebase merge, bypassing the merge queue.
As written above, changes in meta code in the current stage usually will only
affect later stages. This is an issue in two specific cases.
* For the special case of *quotations*, it is desirable to have changes in builtin parsers affect them immediately: when the changes in the parser become active in the next stage, builtin macros implemented via quotations should generate syntax trees compatible with the new parser, and quotation patterns in builtin macros and elaborators should be able to match syntax created by the new parser and macros.
Since quotations capture the syntax tree structure during execution of the current stage and turn it into code for the next stage, we need to run the current stage's builtin parsers in quotations via the interpreter for this to work.
Caveats:
* We activate this behavior by default when building stage 1 by setting `-Dinternal.parseQuotWithCurrentStage=true`.
We force-disable it inside `macro/macro_rules/elab/elab_rules` via `suppressInsideQuot` as they are guaranteed not to run in the next stage and may need to be run in the current one, so the stage 0 parser is the correct one to use for them.
It may be necessary to extend this disabling to functions that contain quotations and are (exclusively) used by one of the mentioned commands. A function using quotations should never be used by both builtin and non-builtin macros/elaborators. Example: https://github.com/leanprover/lean4/blob/f70b7e5722da6101572869d87832494e2f8534b7/src/Lean/Elab/Tactic/Config.lean#L118-L122
* The parser needs to be reachable via an `import` statement, otherwise the version of the previous stage will silently be used.
* Only the parser code (`Parser.fn`) is affected; all metadata such as leading tokens is taken from the previous stage.
For an example, see https://github.com/leanprover/lean4/commit/f9dcbbddc48ccab22c7674ba20c5f409823b4cc1#diff-371387aed38bb02bf7761084fd9460e4168ae16d1ffe5de041b47d3ad2d22422R13
* For *non-builtin* meta code such as `notation`s or `macro`s in
`Notation.lean`, we expect changes to affect the current file and all later
files of the same stage immediately, just like outside the stdlib. To ensure
this, we need to build the stage using `-Dinterpreter.prefer_native=false` -
this, we build stage 1 using `-Dinterpreter.prefer_native=false` -
otherwise, when executing a macro, the interpreter would notice that there is
already a native symbol available for this function and run it instead of the
new IR, but the symbol is from the previous stage!
@@ -124,26 +135,11 @@ affect later stages. This is an issue in two specific cases.
further stages (e.g. after an `update-stage0`) will then need to be compiled
with the flag set to `false` again since they will expect the new signature.
For an example, see https://github.com/leanprover/lean4/commit/da4c46370d85add64ef7ca5e7cc4638b62823fbb.
When enabling `prefer_native`, we usually want to *disable* `parseQuotWithCurrentStage` as it would otherwise make quotations use the interpreter after all.
However, there is a specific case where we want to set both options to `true`: when we make changes to a non-builtin parser like `simp` that has a builtin elaborator, we cannot have the new parser be active outside of quotations in stage 1 as the builtin elaborator from stage 0 would not understand them; on the other hand, we need quotations in e.g. the builtin `simp` elaborator to produce the new syntax in the next stage.
As this issue usually affects only tactics, enabling `debug.byAsSorry` instead of `prefer_native` can be a simpler solution.
* For the special case of *quotations*, it is desirable to have changes in
built-in parsers affect them immediately: when the changes in the parser
become active in the next stage, macros implemented via quotations should
generate syntax trees compatible with the new parser, and quotation patterns
in macro and elaborators should be able to match syntax created by the new
parser and macros. Since quotations capture the syntax tree structure during
execution of the current stage and turn it into code for the next stage, we
need to run the current stage's built-in parsers in quotation via the
interpreter for this to work. Caveats:
* Since interpreting full parsers is not nearly as cheap and we rarely change
built-in syntax, this needs to be opted in using `-Dinternal.parseQuotWithCurrentStage=true`.
* The parser needs to be reachable via an `import` statement, otherwise the
version of the previous stage will silently be used.
* Only the parser code (`Parser.fn`) is affected; all metadata such as leading
tokens is taken from the previous stage.
For an example, see https://github.com/leanprover/lean4/commit/f9dcbbddc48ccab22c7674ba20c5f409823b4cc1#diff-371387aed38bb02bf7761084fd9460e4168ae16d1ffe5de041b47d3ad2d22422
(from before the flag defaulted to `false`).
For a `prefer_native` example, see https://github.com/leanprover/lean4/commit/da4c46370d85add64ef7ca5e7cc4638b62823fbb.
To modify either of these flags both for building and editing the stdlib, adjust
the code in `stage0/src/stdlib_flags.h`. The flags will automatically be reset

View File

@@ -33,6 +33,9 @@ Format of the commit message
- chore (maintain, ex: travis-ci)
- perf (performance improvement, optimization, ...)
Every `feat` or `fix` commit must have a `changelog-*` label, and a commit message
beginning with "This PR " that will be included in the changelog.
``<subject>`` has the following constraints:
- use imperative, present tense: "change" not "changed" nor "changes"
@@ -44,6 +47,7 @@ Format of the commit message
- just as in ``<subject>``, use imperative, present tense
- includes motivation for the change and contrasts with previous
behavior
- If a `changelog-*` label is present, the body must begin with "This PR ".
``<footer>`` is optional and may contain two items:
@@ -60,17 +64,21 @@ Examples
fix: add declarations for operator<<(std::ostream&, expr const&) and operator<<(std::ostream&, context const&) in the kernel
This PR adds declarations `operator<<` for raw printing.
The actual implementation of these two operators is outside of the
kernel. They are implemented in the file 'library/printer.cpp'. We
declare them in the kernel to prevent the following problem. Suppose
there is a file 'foo.cpp' that does not include 'library/printer.h',
but contains
kernel. They are implemented in the file 'library/printer.cpp'.
expr a;
...
std::cout << a << "\n";
...
We declare them in the kernel to prevent the following problem.
Suppose there is a file 'foo.cpp' that does not include 'library/printer.h',
but contains
```cpp
expr a;
...
std::cout << a << "\n";
...
```
The compiler does not generate an error message. It silently uses the
operator bool() to coerce the expression into a Boolean. This produces
counter-intuitive behavior, and may confuse developers.

View File

@@ -49,8 +49,9 @@ In the case of `@[extern]` all *irrelevant* types are removed first; see next se
is represented by the representation of that parameter's type.
For example, `{ x : α // p }`, the `Subtype` structure of a value of type `α` and an irrelevant proof, is represented by the representation of `α`.
* `Nat` is represented by `lean_object *`.
Its runtime value 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 (`lean_box`/`lean_unbox`).
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)`
* 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.
@@ -139,7 +140,7 @@ lean_object * initialize_C(uint8_t builtin, lean_object *);
...
lean_initialize_runtime_module();
//lean_initialize(); // necessary if you (indirectly) access the `Lean` package
//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

View File

@@ -80,3 +80,10 @@ Unlike most Lean projects, all submodules of the `Lean` module begin with the
`prelude` keyword. This disables the automated import of `Init`, meaning that
developers need to figure out their own subset of `Init` to import. This is done
such that changing files in `Init` doesn't force a full rebuild of `Lean`.
### Testing against Mathlib/Batteries
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.
See https://leanprover-community.github.io/contribute/tags_and_branches.html for more details.

View File

@@ -5,11 +5,8 @@ See below for the checklist for release candidates.
We'll use `v4.6.0` as the intended release version as a running example.
- One week before the planned release, ensure that
(1) someone has written the release notes and
(2) someone has written the first draft of the release blog post.
If there is any material in `./releases_drafts/` on the `releases/v4.6.0` branch, then the release notes are not done.
(See the section "Writing the release notes".)
- Run `scripts/release_checklist.py v4.6.0` to check the status of the release.
This script is purely informational, idempotent, and safe to run at any stage of the release process.
- `git checkout releases/v4.6.0`
(This branch should already exist, from the release candidates.)
- `git pull`
@@ -25,14 +22,28 @@ We'll use `v4.6.0` as the intended release version as a running example.
- This step can take up to an hour.
- If you are intending to cut the next release candidate on the same day,
you may want to start on the release candidate checklist now.
- Next we need to prepare the release notes.
- If the stable release is identical to the last release candidate (this should usually be the case),
you can reuse the release notes from `RELEASES.md`.
- If you want to regenerate the release notes,
use `script/release_notes.py --since v4.5.0`, run on the `releases/v4.6.0` branch,
and see the section "Writing the release notes" below for more information.
- Release notes should go in `RELEASES.md` on the `releases/v4.6.0` branch,
and should also be PR'd to `master` (suggested title: "chore: update release notes for v4.6.0").
- Go to https://github.com/leanprover/lean4/releases and verify that the `v4.6.0` release appears.
- Edit the release notes on Github to select the "Set as the latest release".
- Follow the instructions in creating a release candidate for the "GitHub release notes" step,
now that we have a written `RELEASES.md` section.
Do a quick sanity check.
- Verify on Github that "Set as the latest release" is checked.
- Copy the generated release note into the text box, adding the header
```
v4.6.0
----------
```
- Next, we will move a curated list of downstream repos to the latest stable release.
- In order to have the access rights to push to these repositories and merge PRs,
you will need to be a member of the `lean-release-managers` team at both `leanprover-community` and `leanprover`.
Contact Kim Morrison (@kim-em) to arrange access.
- For each of the repositories listed below:
- Make a PR to `master`/`main` changing the toolchain to `v4.6.0`
- The usual branch name would be `bump_to_v4.6.0`.
- Update the toolchain file
- In the Lakefile, if there are dependencies on specific version tags of dependencies that you've already pushed as part of this process, update them to the new tag.
If they depend on `main` or `master`, don't change this; you've just updated the dependency, so it will work and be saved in the manifest
@@ -42,16 +53,38 @@ We'll use `v4.6.0` as the intended release version as a running example.
- Create the tag `v4.6.0` from `master`/`main` and push it.
- Merge the tag `v4.6.0` into the `stable` branch and push it.
- We do this for the repositories:
- [lean4checker](https://github.com/leanprover/lean4checker)
- No dependencies
- Toolchain bump PR
- Create and push the tag
- Merge the tag into `stable`
- [Batteries](https://github.com/leanprover-community/batteries)
- No dependencies
- Toolchain bump PR
- Create and push the tag
- Merge the tag into `stable`
- [lean4checker](https://github.com/leanprover/lean4checker)
- No dependencies
- Toolchain bump PR
- Create and push the tag
- Merge the tag into `stable`
- [quote4](https://github.com/leanprover-community/quote4)
- No dependencies
- Toolchain bump PR
- Create and push the tag
- Merge the tag into `stable`
- [doc-gen4](https://github.com/leanprover/doc-gen4)
- Dependencies: exist, but they're not part of the release workflow
- Toolchain bump PR including updated Lake manifest
- Create and push the tag
- There is no `stable` branch; skip this step
- [Verso](https://github.com/leanprover/verso)
- Dependencies: exist, but they're not part of the release workflow
- The `SubVerso` dependency should be compatible with _every_ Lean release simultaneously, rather than following this workflow
- Warnings during `lake update` and `lake build` are expected.
- Toolchain bump PR including updated Lake manifest
- Create and push the tag
- There is no `stable` branch; skip this step
- [Cli](https://github.com/leanprover/lean4-cli)
- No dependencies
- Toolchain bump PR
- Create and push the tag
- There is no `stable` branch; skip this step
- [ProofWidgets4](https://github.com/leanprover-community/ProofWidgets4)
- Dependencies: `Batteries`
- Note on versions and branches:
@@ -66,27 +99,19 @@ We'll use `v4.6.0` as the intended release version as a running example.
- Toolchain bump PR including updated Lake manifest
- Create and push the tag
- Merge the tag into `stable`
- [doc-gen4](https://github.com/leanprover/doc-gen4)
- Dependencies: exist, but they're not part of the release workflow
- Toolchain bump PR including updated Lake manifest
- Create and push the tag
- There is no `stable` branch; skip this step
- [Verso](https://github.com/leanprover/verso)
- Dependencies: exist, but they're not part of the release workflow
- The `SubVerso` dependency should be compatible with _every_ Lean release simultaneously, rather than following this workflow
- Toolchain bump PR including updated Lake manifest
- Create and push the tag
- There is no `stable` branch; skip this step
- [import-graph](https://github.com/leanprover-community/import-graph)
- Toolchain bump PR including updated Lake manifest
- Create and push the tag
- There is no `stable` branch; skip this step
- [plausible](https://github.com/leanprover-community/plausible)
- Toolchain bump PR including updated Lake manifest
- Create and push the tag
- There is no `stable` branch; skip this step
- [Mathlib](https://github.com/leanprover-community/mathlib4)
- Dependencies: `Aesop`, `ProofWidgets4`, `lean4checker`, `Batteries`, `doc-gen4`, `import-graph`
- Dependencies: `Aesop`, `ProofWidgets4`, `lean4checker`, `Batteries`, `doc-gen4`, `quote4`, `import-graph`
- Toolchain bump PR notes:
- In addition to updating the `lean-toolchain` and `lakefile.lean`,
in `.github/workflows/lean4checker.yml` update the line
`git checkout v4.6.0` to the appropriate tag.
- Upstream dependencies should use their `main` or `master` branch, not toolchain tags.
(Unlike for other repos.)
- Push the PR branch to the main Mathlib repository rather than a fork, or CI may not work reliably
- Create and push the tag
- Create a new branch from the tag, push it, and open a pull request against `stable`.
@@ -98,16 +123,12 @@ We'll use `v4.6.0` as the intended release version as a running example.
- Toolchain bump PR including updated Lake manifest
- Create and push the tag
- Merge the tag into `stable`
- The `v4.6.0` section of `RELEASES.md` is out of sync between
`releases/v4.6.0` and `master`. This should be reconciled:
- Replace the `v4.6.0` section on `master` with the `v4.6.0` section on `releases/v4.6.0`
and commit this to `master`.
- Merge the release announcement PR for the Lean website - it will be deployed automatically
- Run `script/release_checklist.py v4.6.0` again to check that everything is in order.
- Finally, make an announcement!
This should go in https://leanprover.zulipchat.com/#narrow/stream/113486-announce, with topic `v4.6.0`.
Please see previous announcements for suggested language.
You will want a few bullet points for main topics from the release notes.
Link to the blog post from the Zulip announcement.
If there is a blog post, link to that from the zulip announcement.
- Make sure that whoever is handling social media knows the release is out.
## Optimistic(?) time estimates:
@@ -127,6 +148,8 @@ We'll use `v4.7.0-rc1` as the intended release version in this example.
- Decide which nightly release you want to turn into a release candidate.
We will use `nightly-2024-02-29` in this example.
- It is essential to choose the nightly that will become the release candidate as early as possible, to avoid confusion.
- Throughout this process you can use `script/release_checklist.py v4.7.0-rc1` to track progress.
- It is essential that Batteries and Mathlib already have reviewed branches compatible with this nightly.
- Check that both Batteries and Mathlib's `bump/v4.7.0` branch contain `nightly-2024-02-29`
in their `lean-toolchain`.
@@ -139,24 +162,19 @@ We'll use `v4.7.0-rc1` as the intended release version in this example.
git checkout -b releases/v4.7.0
```
- In `RELEASES.md` replace `Development in progress` in the `v4.7.0` section with `Release notes to be written.`
- We will rely on automatically generated release notes for release candidates,
and the written release notes will be used for stable versions only.
It is essential to choose the nightly that will become the release candidate as early as possible, to avoid confusion.
- In `src/CMakeLists.txt`,
- verify that you see `set(LEAN_VERSION_MINOR 7)` (for whichever `7` is appropriate); this should already have been updated when the development cycle began.
- `set(LEAN_VERSION_IS_RELEASE 1)` (this should be a change; on `master` and nightly releases it is always `0`).
- change the `LEAN_VERSION_IS_RELEASE` line to `set(LEAN_VERSION_IS_RELEASE 1)` (this should be a change; on `master` and nightly releases it is always `0`).
- Commit your changes to `src/CMakeLists.txt`, and push.
- `git tag v4.7.0-rc1`
- `git push origin v4.7.0-rc1`
- Ping the FRO Zulip that release notes need to be written. The release notes do not block completing the rest of this checklist.
- Now wait, while CI runs.
- You can monitor this at `https://github.com/leanprover/lean4/actions/workflows/ci.yml`, looking for the `v4.7.0-rc1` tag.
- This step can take up to an hour.
- (GitHub release notes) Once the release appears at https://github.com/leanprover/lean4/releases/
- Verify that the release is marked as a prerelease (this should have been done automatically by the CI release job).
- In the "previous tag" dropdown, select `v4.6.0`, and click "Generate release notes".
This will add a list of all the commits since the last stable version.
- Delete "update stage0" commits, and anything with a completely inscrutable commit message.
- Generate release notes by running `script/release_notes.py --since v4.6.0` on the `releases/v4.7.0` branch.
See the section "Writing the release notes" below for more information.
- Next, we will move a curated list of downstream repos to the release candidate.
- This assumes that for each repository either:
* There is already a *reviewed* branch `bump/v4.7.0` containing the required adaptations.
@@ -181,10 +199,11 @@ We'll use `v4.7.0-rc1` as the intended release version in this example.
- We do this for the same list of repositories as for stable releases, see above.
As above, there are dependencies between these, and so the process above is iterative.
It greatly helps if you can merge the `bump/v4.7.0` PRs yourself!
It is essential for Mathlib CI that you then create the next `bump/v4.8.0` branch
- It is essential for Mathlib and Batteries CI that you then create the next `bump/v4.8.0` branch
for the next development cycle.
Set the `lean-toolchain` file on this branch to same `nightly` you used for this release.
- For Batteries/Aesop/Mathlib, which maintain a `nightly-testing` branch, make sure there is a tag
- (Note: we're currently uncertain if we really want to do this step. Check with Kim Morrison if you're unsure.)
For Batteries/Aesop/Mathlib, which maintain a `nightly-testing` branch, make sure there is a tag
`nightly-testing-2024-02-29` with date corresponding to the nightly used for the release
(create it if not), and then on the `nightly-testing` branch `git reset --hard master`, and force push.
- Make an announcement!
@@ -248,15 +267,26 @@ Please read https://leanprover-community.github.io/contribute/tags_and_branches.
# Writing the release notes
We are currently trying a system where release notes are compiled all at once from someone looking through the commit history.
The exact steps are a work in progress.
Here is the general idea:
Release notes are automatically generated from the commit history, using `script/release_notes.py`.
* The work is done right on the `releases/v4.6.0` branch sometime after it is created but before the stable release is made.
The release notes for `v4.6.0` will later be copied to `master` when we begin a new development cycle.
* There can be material for release notes entries in commit messages.
* There can also be pre-written entries in `./releases_drafts`, which should be all incorporated in the release notes and then deleted from the branch.
Run this as `script/release_notes.py --since v4.6.0`, where `v4.6.0` is the *previous* release version.
This script should be run on the `releases/v4.7.0` branch.
This will generate output for all commits since that tag.
Note that there is output on both stderr, which should be manually reviewed,
and on stdout, which should be manually copied to `RELEASES.md`.
The output on stderr should mostly be about commits for which the script could not find an associated PR,
usually because a PR was rebase-merged because it contained an update to stage0.
Some judgement is required here: ignore commits which look minor,
but manually add items to the release notes for significant PRs that were rebase-merged.
There can also be pre-written entries in `./releases_drafts`, which should be all incorporated in the release notes and then deleted from the branch.
See `./releases_drafts/README.md` for more information.
* The release notes should be written from a downstream expert user's point of view.
This section will be updated when the next release notes are written (for `v4.10.0`).
# `release_checklist.py`
The script `script/release_checklist.py` attempts to automate checking the status of the release.
Future improvements:
* We check the release notes have been posted on Github,
but do not check that they are present in `RELEASES.md` on the release branch or on `master`.

417
doc/do.md
View File

@@ -1,417 +0,0 @@
# The `do` notation
Lean is a pure functional programming language, but you can write effectful code using the `do` embedded domain specific language (DSL). The following simple program prints two strings "hello" and "world" in the standard output and terminates with exit code 0. Note that the type of the program is `IO UInt32`. You can read this type as the type of values that perform input-output effects and produce a value of type `UInt32`.
```lean
def main : IO UInt32 := do
IO.println "hello"
IO.println "world"
return 0
```
The type of `IO.println` is `String → IO Unit`. That is, it is a function from `String` to `IO Unit` which indicates it may perform input-output effects and produce a value of type `Unit`. We often say that functions that may perform effects are *methods*.
We also say a method application, such as `IO.println "hello"` is an *action*.
Note that the examples above also demonstrates that braceless `do` blocks are whitespace sensitive.
If you like `;`s and curly braces, you can write the example above as
```lean
def main : IO UInt32 := do {
IO.println "hello";
IO.println "world";
return 0;
}
```
Semicolons can be used even when curly braces are not used. They are particularly useful when you want to "pack" more than one action in a single line.
```lean
def main : IO UInt32 := do
IO.println "hello"; IO.println "world"
return 0
```
Whitespace sensitivity in programming languages is a controversial topic
among programmers. You should use your own style. We, the Lean developers, **love** the
braceless and semicolon-free style.
We believe it is clean and beautiful.
The `do` DSL expands into the core Lean language. Let's inspect the different components using the commands `#print` and `#check`.
```lean
# def main : IO UInt32 := do
# IO.println "hello"
# IO.println "world"
# return 0
#check IO.println "hello"
-- IO Unit
#print main
-- Output contains the infix operator `>>=` and `pure`
-- The following `set_option` disables notation such as `>>=` in the output
set_option pp.notation false in
#print main
-- Output contains `bind` and `pure`
#print bind
-- bind : {m : Type u → Type v} → [self : Bind m] → {α β : Type u} →
-- m α → (α → m β) → m β
#print pure
-- pure : {m : Type u → Type v} → [self : Pure m] → {α : Type u} →
-- α → m α
-- IO implements the type classes `Bind` and `Pure`.
#check (inferInstance : Bind IO)
#check (inferInstance : Pure IO)
```
The types of `bind` and `pure` may look daunting at first sight.
They both have many implicit arguments. Let's focus first on the explicit arguments.
`bind` has two explicit arguments `m α` and `α → m β`. The first one should
be viewed as an action with effects `m` and producing a value of type `α`.
The second is a function that takes a value of type `α` and produces an action
with effects `m` and a value of type `β`. The result is `m β`. The method `bind` is composing
these two actions. We often say `bind` is an abstract semicolon. The method `pure` converts
a value `α` into an action that produces an action `m α`.
Here is the same function being defined using `bind` and `pure` without the `do` DSL.
```lean
def main : IO UInt32 :=
bind (IO.println "hello") fun _ =>
bind (IO.println "world") fun _ =>
pure 0
```
The notations `let x <- action1; action2` and `let x ← action1; action2` are just syntax sugar for `bind action1 fun x => action2`.
Here is a small example using it.
```lean
def isGreaterThan0 (x : Nat) : IO Bool := do
IO.println s!"value: {x}"
return x > 0
def f (x : Nat) : IO Unit := do
let c <- isGreaterThan0 x
if c then
IO.println s!"{x} is greater than 0"
else
pure ()
#eval f 10
-- value: 10
-- 10 is greater than 0
```
## Nested actions
Note that we cannot write `if isGreaterThan0 x then ... else ...` because the condition in a `if-then-else` is a **pure** value without effects, but `isGreaterThan0 x` has type `IO Bool`. You can use the nested action notation to avoid this annoyance. Here is an equivalent definition for `f` using a nested action.
```lean
# def isGreaterThan0 (x : Nat) : IO Bool := do
# IO.println s!"x: {x}"
# return x > 0
def f (x : Nat) : IO Unit := do
if (<- isGreaterThan0 x) then
IO.println s!"{x} is greater than 0"
else
pure ()
#print f
```
Lean "lifts" the nested actions and introduces the `bind` for us.
Here is an example with two nested actions. Note that both actions are executed
even if `x = 0`.
```lean
# def isGreaterThan0 (x : Nat) : IO Bool := do
# IO.println s!"x: {x}"
# return x > 0
def f (x y : Nat) : IO Unit := do
if (<- isGreaterThan0 x) && (<- isGreaterThan0 y) then
IO.println s!"{x} and {y} are greater than 0"
else
pure ()
#eval f 0 10
-- value: 0
-- value: 10
-- The function `f` above is equivalent to
def g (x y : Nat) : IO Unit := do
let c1 <- isGreaterThan0 x
let c2 <- isGreaterThan0 y
if c1 && c2 then
IO.println s!"{x} and {y} are greater than 0"
else
pure ()
theorem fgEqual : f = g :=
rfl -- proof by reflexivity
```
Here are two ways to achieve the short-circuit semantics in the example above
```lean
# def isGreaterThan0 (x : Nat) : IO Bool := do
# IO.println s!"x: {x}"
# return x > 0
def f1 (x y : Nat) : IO Unit := do
if (<- isGreaterThan0 x <&&> isGreaterThan0 y) then
IO.println s!"{x} and {y} are greater than 0"
else
pure ()
-- `<&&>` is the effectful version of `&&`
-- Given `x y : IO Bool`, `x <&&> y` : m Bool`
-- It only executes `y` if `x` returns `true`.
#eval f1 0 10
-- value: 0
#eval f1 1 10
-- value: 1
-- value: 10
-- 1 and 10 are greater than 0
def f2 (x y : Nat) : IO Unit := do
if (<- isGreaterThan0 x) then
if (<- isGreaterThan0 y) then
IO.println s!"{x} and {y} are greater than 0"
else
pure ()
else
pure ()
```
## `if-then` notation
In the `do` DSL, we can write `if c then action` as a shorthand for `if c then action else pure ()`. Here is the method `f2` using this shorthand.
```lean
# def isGreaterThan0 (x : Nat) : IO Bool := do
# IO.println s!"x: {x}"
# return x > 0
def f2 (x y : Nat) : IO Unit := do
if (<- isGreaterThan0 x) then
if (<- isGreaterThan0 y) then
IO.println s!"{x} and {y} are greater than 0"
```
## Reassignments
When writing effectful code, it is natural to think imperatively.
For example, suppose we want to create an empty array `xs`,
add `0` if some condition holds, add `1` if another condition holds,
and then print it. In the following example, we use variable
"shadowing" to simulate this kind of "update".
```lean
def f (b1 b2 : Bool) : IO Unit := do
let xs := #[]
let xs := if b1 then xs.push 0 else xs
let xs := if b2 then xs.push 1 else xs
IO.println xs
#eval f true true
-- #[0, 1]
#eval f false true
-- #[1]
#eval f true false
-- #[0]
#eval f false false
-- #[]
```
We can use tuples to simulate updates on multiple variables.
```lean
def f (b1 b2 : Bool) : IO Unit := do
let xs := #[]
let ys := #[]
let (xs, ys) := if b1 then (xs.push 0, ys) else (xs, ys.push 0)
let (xs, ys) := if b2 then (xs.push 1, ys) else (xs, ys.push 1)
IO.println s!"xs: {xs}, ys: {ys}"
#eval f true false
-- xs: #[0], ys: #[1]
```
We can also simulate the control-flow above using *join-points*.
A join-point is a `let` that is always tail called and fully applied.
The Lean compiler implements them using `goto`s.
Here is the same example using join-points.
```lean
def f (b1 b2 : Bool) : IO Unit := do
let jp1 xs ys := IO.println s!"xs: {xs}, ys: {ys}"
let jp2 xs ys := if b2 then jp1 (xs.push 1) ys else jp1 xs (ys.push 1)
let xs := #[]
let ys := #[]
if b1 then jp2 (xs.push 0) ys else jp2 xs (ys.push 0)
#eval f true false
-- xs: #[0], ys: #[1]
```
You can capture complex control-flow using join-points.
The `do` DSL offers the variable reassignment feature to make this kind of code more comfortable to write. In the following example, the `mut` modifier at `let mut xs := #[]` indicates that variable `xs` can be reassigned. The example contains two reassignments `xs := xs.push 0` and `xs := xs.push 1`. The reassignments are compiled using join-points. There is no hidden state being updated.
```lean
def f (b1 b2 : Bool) : IO Unit := do
let mut xs := #[]
if b1 then xs := xs.push 0
if b2 then xs := xs.push 1
IO.println xs
#eval f true true
-- #[0, 1]
```
The notation `x <- action` reassigns `x` with the value produced by the action. It is equivalent to `x := (<- action)`
## Iteration
The `do` DSL provides a unified notation for iterating over datastructures. Here are a few examples.
```lean
def sum (xs : Array Nat) : IO Nat := do
let mut s := 0
for x in xs do
IO.println s!"x: {x}"
s := s + x
return s
#eval sum #[1, 2, 3]
-- x: 1
-- x: 2
-- x: 3
-- 6
-- We can write pure code using the `Id.run <| do` DSL too.
def sum' (xs : Array Nat) : Nat := Id.run <| do
let mut s := 0
for x in xs do
s := s + x
return s
#eval sum' #[1, 2, 3]
-- 6
def sumEven (xs : Array Nat) : IO Nat := do
let mut s := 0
for x in xs do
if x % 2 == 0 then
IO.println s!"x: {x}"
s := s + x
return s
#eval sumEven #[1, 2, 3, 6]
-- x: 2
-- x: 6
-- 8
def splitEvenOdd (xs : List Nat) : IO Unit := do
let mut evens := #[]
let mut odds := #[]
for x in xs do
if x % 2 == 0 then
evens := evens.push x
else
odds := odds.push x
IO.println s!"evens: {evens}, odds: {odds}"
#eval splitEvenOdd [1, 2, 3, 4]
-- evens: #[2, 4], odds: #[1, 3]
def findNatLessThan (x : Nat) (p : Nat Bool) : IO Nat := do
-- [:x] is notation for the range [0, x)
for i in [:x] do
if p i then
return i -- `return` from the `do` block
throw (IO.userError "value not found")
#eval findNatLessThan 10 (fun x => x > 5 && x % 4 == 0)
-- 8
def sumOddUpTo (xs : List Nat) (threshold : Nat) : IO Nat := do
let mut s := 0
for x in xs do
if x % 2 == 0 then
continue -- it behaves like the `continue` statement in imperative languages
IO.println s!"x: {x}"
s := s + x
if s > threshold then
break -- it behaves like the `break` statement in imperative languages
IO.println s!"result: {s}"
return s
#eval sumOddUpTo [2, 3, 4, 11, 20, 31, 41, 51, 107] 40
-- x: 3
-- x: 11
-- x: 31
-- result: 45
-- 45
```
TODO: describe `forIn`
## Try-catch
TODO
## Returning early from a failed match
Inside a `do` block, the pattern `let _ ← <success> | <fail>` will continue with the rest of the block if the match on the left hand side succeeds, but will execute the right hand side and exit the block on failure:
```lean
def showUserInfo (getUsername getFavoriteColor : IO (Option String)) : IO Unit := do
let some n getUsername | IO.println "no username!"
IO.println s!"username: {n}"
let some c getFavoriteColor | IO.println "user didn't provide a favorite color!"
IO.println s!"favorite color: {c}"
-- username: JohnDoe
-- favorite color: red
#eval showUserInfo (pure <| some "JohnDoe") (pure <| some "red")
-- no username
#eval showUserInfo (pure none) (pure <| some "purple")
-- username: JaneDoe
-- user didn't provide a favorite color
#eval showUserInfo (pure <| some "JaneDoe") (pure none)
```
## If-let
Inside a `do` block, users can employ the `if let` pattern to destructure actions:
```lean
def tryIncrement (getInput : IO (Option Nat)) : IO (Except String Nat) := do
if let some n getInput
then return Except.ok n.succ
else return Except.error "argument was `none`"
-- Except.ok 2
#eval tryIncrement (pure <| some 1)
-- Except.error "argument was `none`"
#eval tryIncrement (pure <| none)
```
## Pattern matching
TODO
## Monads
TODO
## ReaderT
TODO
## StateT
TODO
## StateRefT
TODO
## ExceptT
TODO
## MonadLift and automatic lifting
TODO

View File

@@ -1,8 +0,0 @@
## Elaborators
TODO. See [Lean Together 2021: Metaprogramming in Lean
4](https://youtu.be/hxQ1vvhYN_U) for an overview as well [the
continuation](https://youtu.be/vy4JWIiiXSY) about tactic programming.
For more information on antiquotations, see also §4.1 of [Beyond
Notations: Hygienic Macro Expansion for Theorem Proving
Languages](https://arxiv.org/pdf/2001.10490.pdf#page=11).

View File

@@ -1,190 +0,0 @@
# Enumerated Types
The simplest kind of inductive type is simply a type with a finite, enumerated list of elements.
The following command declares the enumerated type `Weekday`.
```lean
inductive Weekday where
| sunday : Weekday
| monday : Weekday
| tuesday : Weekday
| wednesday : Weekday
| thursday : Weekday
| friday : Weekday
| saturday : Weekday
```
The `Weekday` type has 7 constructors/elements. The constructors live in the `Weekday` namespace
Think of `sunday`, `monday`, …, `saturday` as being distinct elements of `Weekday`,
with no other distinguishing properties.
```lean
# inductive Weekday where
# | sunday : Weekday
# | monday : Weekday
# | tuesday : Weekday
# | wednesday : Weekday
# | thursday : Weekday
# | friday : Weekday
# | saturday : Weekday
#check Weekday.sunday -- Weekday
#check Weekday.monday -- Weekday
```
You can define functions by pattern matching.
The following function converts a `Weekday` into a natural number.
```lean
# inductive Weekday where
# | sunday : Weekday
# | monday : Weekday
# | tuesday : Weekday
# | wednesday : Weekday
# | thursday : Weekday
# | friday : Weekday
# | saturday : Weekday
def natOfWeekday (d : Weekday) : Nat :=
match d with
| Weekday.sunday => 1
| Weekday.monday => 2
| Weekday.tuesday => 3
| Weekday.wednesday => 4
| Weekday.thursday => 5
| Weekday.friday => 6
| Weekday.saturday => 7
#eval natOfWeekday Weekday.tuesday -- 3
```
It is often useful to group definitions related to a type in a namespace with the same name.
For example, we can put the function above into the ``Weekday`` namespace.
We are then allowed to use the shorter name when we open the namespace.
In the following example, we define functions from ``Weekday`` to ``Weekday`` in the namespace `Weekday`.
```lean
# inductive Weekday where
# | sunday : Weekday
# | monday : Weekday
# | tuesday : Weekday
# | wednesday : Weekday
# | thursday : Weekday
# | friday : Weekday
# | saturday : Weekday
namespace Weekday
def next (d : Weekday) : Weekday :=
match d with
| sunday => monday
| monday => tuesday
| tuesday => wednesday
| wednesday => thursday
| thursday => friday
| friday => saturday
| saturday => sunday
end Weekday
```
It is so common to start a definition with a `match` in Lean, that Lean provides a syntax sugar for it.
```lean
# inductive Weekday where
# | sunday : Weekday
# | monday : Weekday
# | tuesday : Weekday
# | wednesday : Weekday
# | thursday : Weekday
# | friday : Weekday
# | saturday : Weekday
# namespace Weekday
def previous : Weekday -> Weekday
| sunday => saturday
| monday => sunday
| tuesday => monday
| wednesday => tuesday
| thursday => wednesday
| friday => thursday
| saturday => friday
# end Weekday
```
We can use the command `#eval` to test our definitions.
```lean
# inductive Weekday where
# | sunday : Weekday
# | monday : Weekday
# | tuesday : Weekday
# | wednesday : Weekday
# | thursday : Weekday
# | friday : Weekday
# | saturday : Weekday
# namespace Weekday
# def next (d : Weekday) : Weekday :=
# match d with
# | sunday => monday
# | monday => tuesday
# | tuesday => wednesday
# | wednesday => thursday
# | thursday => friday
# | friday => saturday
# | saturday => sunday
# def previous : Weekday -> Weekday
# | sunday => saturday
# | monday => sunday
# | tuesday => monday
# | wednesday => tuesday
# | thursday => wednesday
# | friday => thursday
# | saturday => friday
def toString : Weekday -> String
| sunday => "Sunday"
| monday => "Monday"
| tuesday => "Tuesday"
| wednesday => "Wednesday"
| thursday => "Thursday"
| friday => "Friday"
| saturday => "Saturday"
#eval toString (next sunday) -- "Monday"
#eval toString (next tuesday) -- "Wednesday"
#eval toString (previous wednesday) -- "Tuesday"
#eval toString (next (previous sunday)) -- "Sunday"
#eval toString (next (previous monday)) -- "Monday"
-- ..
# end Weekday
```
We can now prove the general theorem that ``next (previous d) = d`` for any weekday ``d``.
The idea is to perform a proof by cases using `match`, and rely on the fact for each constructor both
sides of the equality reduce to the same term.
```lean
# inductive Weekday where
# | sunday : Weekday
# | monday : Weekday
# | tuesday : Weekday
# | wednesday : Weekday
# | thursday : Weekday
# | friday : Weekday
# | saturday : Weekday
# namespace Weekday
# def next (d : Weekday) : Weekday :=
# match d with
# | sunday => monday
# | monday => tuesday
# | tuesday => wednesday
# | wednesday => thursday
# | thursday => friday
# | friday => saturday
# | saturday => sunday
# def previous : Weekday -> Weekday
# | sunday => saturday
# | monday => sunday
# | tuesday => monday
# | wednesday => tuesday
# | thursday => wednesday
# | friday => thursday
# | saturday => friday
theorem nextOfPrevious (d : Weekday) : next (previous d) = d :=
match d with
| sunday => rfl
| monday => rfl
| tuesday => rfl
| wednesday => rfl
| thursday => rfl
| friday => rfl
| saturday => rfl
# end Weekday
```

View File

@@ -29,7 +29,7 @@ def ex3 (declName : Name) : MetaM Unit := do
for x in xs do
trace[Meta.debug] "{x} : {← inferType x}"
def myMin [LT α] [DecidableRel (α := α) (·<·)] (a b : α) : α :=
def myMin [LT α] [DecidableLT α] (a b : α) : α :=
if a < b then
a
else

View File

@@ -179,7 +179,7 @@ local macro "have_eq " lhs:term:max rhs:term:max : tactic =>
`(tactic|
(have h : $lhs = $rhs :=
-- TODO: replace with linarith
by simp_arith at *; apply Nat.le_antisymm <;> assumption
by simp +arith at *; apply Nat.le_antisymm <;> assumption
try subst $lhs))
/-!

View File

@@ -12,17 +12,17 @@ Remark: this example is based on an example found in the Idris manual.
Vectors
--------
A `Vector` is a list of size `n` whose elements belong to a type `α`.
A `Vec` is a list of size `n` whose elements belong to a type `α`.
-/
inductive Vector (α : Type u) : Nat Type u
| nil : Vector α 0
| cons : α Vector α n Vector α (n+1)
inductive Vec (α : Type u) : Nat Type u
| nil : Vec α 0
| cons : α Vec α n Vec α (n+1)
/-!
We can overload the `List.cons` notation `::` and use it to create `Vector`s.
We can overload the `List.cons` notation `::` and use it to create `Vec`s.
-/
infix:67 " :: " => Vector.cons
infix:67 " :: " => Vec.cons
/-!
Now, we define the types of our simple functional language.
@@ -50,11 +50,11 @@ the builtin instance for `Add Int` as the solution.
/-!
Expressions are indexed by the types of the local variables, and the type of the expression itself.
-/
inductive HasType : Fin n Vector Ty n Ty Type where
inductive HasType : Fin n Vec Ty n Ty Type where
| stop : HasType 0 (ty :: ctx) ty
| pop : HasType k ctx ty HasType k.succ (u :: ctx) ty
inductive Expr : Vector Ty n Ty Type where
inductive Expr : Vec Ty n Ty Type where
| var : HasType i ctx ty Expr ctx ty
| val : Int Expr ctx Ty.int
| lam : Expr (a :: ctx) ty Expr ctx (Ty.fn a ty)
@@ -102,8 +102,8 @@ indexed over the types in scope. Since an environment is just another form of li
to the vector of local variable types, we overload again the notation `::` so that we can use the usual list syntax.
Given a proof that a variable is defined in the context, we can then produce a value from the environment.
-/
inductive Env : Vector Ty n Type where
| nil : Env Vector.nil
inductive Env : Vec Ty n Type where
| nil : Env Vec.nil
| cons : Ty.interp a Env ctx Env (a :: ctx)
infix:67 " :: " => Env.cons

View File

@@ -82,9 +82,7 @@ theorem Expr.typeCheck_correct (h₁ : HasType e ty) (h₂ : e.typeCheck ≠ .un
/-!
Now, we prove that if `Expr.typeCheck e` returns `Maybe.unknown`, then forall `ty`, `HasType e ty` does not hold.
The notation `e.typeCheck` is sugar for `Expr.typeCheck e`. Lean can infer this because we explicitly said that `e` has type `Expr`.
The proof is by induction on `e` and case analysis. The tactic `rename_i` is used to rename "inaccessible" variables.
We say a variable is inaccessible if it is introduced by a tactic (e.g., `cases`) or has been shadowed by another variable introduced
by the user. Note that the tactic `simp [typeCheck]` is applied to all goal generated by the `induction` tactic, and closes
The proof is by induction on `e` and case analysis. Note that the tactic `simp [typeCheck]` is applied to all goal generated by the `induction` tactic, and closes
the cases corresponding to the constructors `Expr.nat` and `Expr.bool`.
-/
theorem Expr.typeCheck_complete {e : Expr} : e.typeCheck = .unknown ¬ HasType e ty := by

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
source ../../tests/common.sh
exec_check lean -Dlinter.all=false "$f"
exec_check_raw lean -Dlinter.all=false "$f"

View File

@@ -83,7 +83,6 @@
src = ./.;
roots = [
{ mod = "examples"; glob = "submodules"; }
{ mod = "monads"; glob = "submodules"; }
];
};
inked = renderPackage literate;

View File

@@ -1 +0,0 @@
# Float

View File

@@ -1,153 +0,0 @@
# Functions
Functions are the fundamental unit of program execution in any programming language.
As in other languages, a Lean function has a name, can have parameters and take arguments, and has a body.
Lean also supports functional programming constructs such as treating functions as values,
using unnamed functions in expressions, composition of functions to form new functions,
curried functions, and the implicit definition of functions by way of
the partial application of function arguments.
You define functions by using the `def` keyword followed by its name, a parameter list, return type and its body.
The parameter list consists of successive parameters that are separated by spaces.
You can specify an explicit type for each parameter.
If you do not specify a specific argument type, the compiler tries to infer the type from the function body.
An error is returned when it cannot be inferred.
The expression that makes up the function body is typically a compound expression consisting of a number of expressions
that culminate in a final expression that is the return value.
The return type is a colon followed by a type and is optional.
If you do not specify the type of the return value explicitly,
the compiler tries to determine the return type from the final expression.
```lean
def f x := x + 1
```
In the previous example, the function name is `f`, the argument is `x`, which has type `Nat`,
the function body is `x + 1`, and the return value is of type `Nat`.
The following example defines the factorial recursive function using pattern matching.
```lean
def fact x :=
match x with
| 0 => 1
| n+1 => (n+1) * fact n
#eval fact 100
```
By default, Lean only accepts total functions.
The `partial` keyword may be used to define a recursive function without a termination proof; `partial` functions compute in compiled programs, but are opaque in proofs and during type checking.
```lean
partial def g (x : Nat) (p : Nat -> Bool) : Nat :=
if p x then
x
else
g (x+1) p
#eval g 0 (fun x => x > 10)
```
In the previous example, `g x p` only terminates if there is a `y >= x` such that `p y` returns `true`.
Of course, `g 0 (fun x => false)` never terminates.
However, the use of `partial` is restricted to functions whose return type is not empty so the soundness
of the system is not compromised.
```lean,ignore
partial def loop? : α := -- failed to compile partial definition 'loop?', failed to
loop? -- show that type is inhabited and non empty
partial def loop [Inhabited α] : α := -- compiles
loop
example : True := -- accepted
loop
example : False :=
loop -- failed to synthesize instance Inhabited False
```
If we were able to partially define `loop?`, we could prove `False` with it.
# Lambda expressions
A lambda expression is an unnamed function.
You define lambda expressions by using the `fun` keyword. A lambda expression resembles a function definition, except that instead of the `:=` token,
the `=>` token is used to separate the argument list from the function body. As in a regular function definition,
the argument types can be inferred or specified explicitly, and the return type of the lambda expression is inferred from the type of the
last expression in the body.
```lean
def twice (f : Nat -> Nat) (x : Nat) : Nat :=
f (f x)
#eval twice (fun x => x + 1) 3
#eval twice (fun (x : Nat) => x * 2) 3
#eval List.map (fun x => x + 1) [1, 2, 3]
-- [2, 3, 4]
#eval List.map (fun (x, y) => x + y) [(1, 2), (3, 4)]
-- [3, 7]
```
# Syntax sugar for simple lambda expressions
Simple functions can be defined using parentheses and `·` as a placeholder.
```lean
#check (· + 1)
-- fun a => a + 1
#check (2 - ·)
-- fun a => 2 - a
#eval [1, 2, 3, 4, 5].foldl (· * ·) 1
-- 120
def h (x y z : Nat) :=
x + y + z
#check (h · 1 ·)
-- fun a b => h a 1 b
#eval [(1, 2), (3, 4), (5, 6)].map (·.1)
-- [1, 3, 5]
```
In the previous example, the term `(·.1)` is syntax sugar for `fun x => x.1`.
# Pipelining
Pipelining enables function calls to be chained together as successive operations. Pipelining works as follows:
```lean
def add1 x := x + 1
def times2 x := x * 2
#eval times2 (add1 100)
#eval 100 |> add1 |> times2
#eval times2 <| add1 <| 100
```
The result of the previous `#eval` commands is 202.
The forward pipeline `|>` operator takes a function and an argument and return a value.
In contrast, the backward pipeline `<|` operator takes an argument and a function and returns a value.
These operators are useful for minimizing the number of parentheses.
```lean
def add1Times3FilterEven (xs : List Nat) :=
List.filter (· % 2 == 0) (List.map (· * 3) (List.map (· + 1) xs))
#eval add1Times3FilterEven [1, 2, 3, 4]
-- [6, 12]
-- Define the same function using pipes
def add1Times3FilterEven' (xs : List Nat) :=
xs |> List.map (· + 1) |> List.map (· * 3) |> List.filter (· % 2 == 0)
#eval add1Times3FilterEven' [1, 2, 3, 4]
-- [6, 12]
```
Lean also supports the operator `|>.` which combines forward pipeline `|>` operator with the `.` field notation.
```lean
-- Define the same function using pipes
def add1Times3FilterEven'' (xs : List Nat) :=
xs.map (· + 1) |>.map (· * 3) |>.filter (· % 2 == 0)
#eval add1Times3FilterEven'' [1, 2, 3, 4]
-- [6, 12]
```
For users familiar with the Haskell programming language,
Lean also supports the notation `f $ a` for the backward pipeline `f <| a`.

View File

@@ -1,142 +0,0 @@
## Implicit Arguments
Suppose we define the `compose` function as.
```lean
def compose (α β γ : Type) (g : β γ) (f : α β) (x : α) : γ :=
g (f x)
```
The function `compose` takes three types, ``α``, ``β``, and ``γ``, and two functions, ``g : β → γ`` and ``f : α → β``, a value `x : α`, and
returns ``g (f x)``, the composition of ``g`` and ``f``.
We say `compose` is polymorphic over types ``α``, ``β``, and ``γ``. Now, let's use `compose`:
```lean
# def compose (α β γ : Type) (g : β → γ) (f : α → β) (x : α) : γ :=
# g (f x)
def double (x : Nat) := 2*x
def triple (x : Nat) := 3*x
#check compose Nat Nat Nat double triple 10 -- Nat
#eval compose Nat Nat Nat double triple 10 -- 60
def appendWorld (s : String) := s ++ "world"
#check String.length -- String → Nat
#check compose String String Nat String.length appendWorld "hello" -- Nat
#eval compose String String Nat String.length appendWorld "hello" -- 10
```
Because `compose` is polymorphic over types ``α``, ``β``, and ``γ``, we have to provide them in the examples above.
But this information is redundant: one can infer the types from the arguments ``g`` and ``f``.
This is a central feature of dependent type theory: terms carry a lot of information, and often some of that information can be inferred from the context.
In Lean, one uses an underscore, ``_``, to specify that the system should fill in the information automatically.
```lean
# def compose (α β γ : Type) (g : β → γ) (f : α → β) (x : α) : γ :=
# g (f x)
# def double (x : Nat) := 2*x
# def triple (x : Nat) := 3*x
#check compose _ _ _ double triple 10 -- Nat
#eval compose Nat Nat Nat double triple 10 -- 60
# def appendWorld (s : String) := s ++ "world"
# #check String.length -- String → Nat
#check compose _ _ _ String.length appendWorld "hello" -- Nat
#eval compose _ _ _ String.length appendWorld "hello" -- 10
```
It is still tedious, however, to type all these underscores. When a function takes an argument that can generally be inferred from context,
Lean allows us to specify that this argument should, by default, be left implicit. This is done by putting the arguments in curly braces, as follows:
```lean
def compose {α β γ : Type} (g : β → γ) (f : α → β) (x : α) : γ :=
g (f x)
# def double (x : Nat) := 2*x
# def triple (x : Nat) := 3*x
#check compose double triple 10 -- Nat
#eval compose double triple 10 -- 60
# def appendWorld (s : String) := s ++ "world"
# #check String.length -- String → Nat
#check compose String.length appendWorld "hello" -- Nat
#eval compose String.length appendWorld "hello" -- 10
```
All that has changed are the braces around ``α β γ: Type``.
It makes these three arguments implicit. Notationally, this hides the specification of the type,
making it look as though ``compose`` simply takes 3 arguments.
Variables can also be specified as implicit when they are declared with
the ``variable`` command:
```lean
universe u
section
variable {α : Type u}
variable (x : α)
def ident := x
end
variable (α β : Type u)
variable (a : α) (b : β)
#check ident
#check ident a
#check ident b
```
This definition of ``ident`` here has the same effect as the one above.
Lean has very complex mechanisms for instantiating implicit arguments, and we will see that they can be used to infer function types, predicates, and even proofs.
The process of instantiating these "holes," or "placeholders," in a term is part of a bigger process called *elaboration*.
The presence of implicit arguments means that at times there may be insufficient information to fix the meaning of an expression precisely.
An expression like ``ident`` is said to be *polymorphic*, because it can take on different meanings in different contexts.
One can always specify the type ``T`` of an expression ``e`` by writing ``(e : T)``.
This instructs Lean's elaborator to use the value ``T`` as the type of ``e`` when trying to elaborate it.
In the following example, this mechanism is used to specify the desired types of the expressions ``ident``.
```lean
def ident {α : Type u} (a : α) : α := a
#check (ident : Nat → Nat) -- Nat → Nat
```
Numerals are overloaded in Lean, but when the type of a numeral cannot be inferred, Lean assumes, by default, that it is a natural number.
So the expressions in the first two ``#check`` commands below are elaborated in the same way, whereas the third ``#check`` command interprets ``2`` as an integer.
```lean
#check 2 -- Nat
#check (2 : Nat) -- Nat
#check (2 : Int) -- Int
```
Sometimes, however, we may find ourselves in a situation where we have declared an argument to a function to be implicit,
but now want to provide the argument explicitly. If ``foo`` is such a function, the notation ``@foo`` denotes the same function with all
the arguments made explicit.
```lean
# def ident {α : Type u} (a : α) : α := a
variable (α β : Type)
#check @ident -- {α : Type u} → αα
#check @ident α -- αα
#check @ident β -- β → β
#check @ident Nat -- Nat → Nat
#check @ident Bool true -- Bool
```
Notice that now the first ``#check`` command gives the type of the identifier, ``ident``, without inserting any placeholders.
Moreover, the output indicates that the first argument is implicit.
Named arguments enable you to specify an argument for a parameter by matching the argument with
its name rather than with its position in the parameter list. You can use them to specify explicit *and* implicit arguments.
If you don't remember the order of the parameters but know their names, you can send the arguments in any order.
You may also provide the value for an implicit parameter when
Lean failed to infer it. Named arguments also improve the readability of your code by identifying what
each argument represents.
```lean
# def ident {α : Type u} (a : α) : α := a
#check ident (α := Nat) -- Nat → Nat
#check ident (α := Bool) -- Bool → Bool
```

View File

@@ -1,3 +0,0 @@
# Inductive Types
[Theorem Proving in Lean](https://lean-lang.org/theorem_proving_in_lean4/inductive_types.html) has a chapter about inductive datatypes.

View File

@@ -1,37 +0,0 @@
# Integers
The `Int` type represents the arbitrary-precision integers. There are no overflows.
```lean
#eval (100000000000000000 : Int) * 200000000000000000000 * 1000000000000000000000
```
Recall that nonnegative numerals are considered to be a `Nat` if there are no typing constraints.
```lean
#check 1 -- Nat
#check -1 -- Int
#check (1:Int) -- Int
```
The operator `/` for `Int` implements integer division.
```lean
#eval -10 / 4 -- -3
```
Similar to `Nat`, the internal representation of `Int` is optimized. Small integers are
represented by a single machine word. Big integers are implemented using [GMP](https://gmplib.org/manual/) numbers.
We recommend you use fixed precision numeric types only in performance critical code.
The Lean kernel does not have special support for reducing `Int` during type checking.
However, since `Int` is defined as
```lean
# namespace hidden
inductive Int : Type where
| ofNat : Nat Int
| negSucc : Nat Int
# end hidden
```
the type checker will be able reduce `Int` expressions efficiently by relying on the special support for `Nat`.
```lean
theorem ex : -2000000000 * 1000000000 = -2000000000000000000 :=
rfl
```

View File

@@ -61,7 +61,7 @@ Parts of atomic names can be escaped by enclosing them in pairs of French double
letterlike_symbols: [℀-⅏]
escaped_ident_part: "«" [^«»\r\n\t]* "»"
atomic_ident_rest: atomic_ident_start | [0-9'ⁿ] | subscript
subscript: [₀-₉ₐ-ₜᵢ-ᵪ]
subscript: [₀-₉ₐ-ₜᵢ-ᵪ]
```
String Literals
@@ -128,16 +128,16 @@ Numeric literals can be specified in various bases.
```
numeral : numeral10 | numeral2 | numeral8 | numeral16
numeral10 : [0-9]+
numeral2 : "0" [bB] [0-1]+
numeral8 : "0" [oO] [0-7]+
numeral16 : "0" [xX] hex_char+
numeral10 : [0-9]+ ("_"+ [0-9]+)*
numeral2 : "0" [bB] ("_"* [0-1]+)+
numeral8 : "0" [oO] ("_"* [0-7]+)+
numeral16 : "0" [xX] ("_"* hex_char+)+
```
Floating point literals are also possible with optional exponent:
```
float : [0-9]+ "." [0-9]+ [[eE[+-][0-9]+]
float : numeral10 "." numeral10? [eE[+-]numeral10]
```
For example:
@@ -147,6 +147,7 @@ constant w : Int := 55
constant x : Nat := 26085
constant y : Nat := 0x65E5
constant z : Float := 2.548123e-05
constant b : Bool := 0b_11_01_10_00
```
Note: that negative numbers are created by applying the "-" negation prefix operator to the number, for example:

View File

@@ -1 +0,0 @@
# List

View File

@@ -1,393 +0,0 @@
# Macro Overview
The official paper describing the mechanics behind Lean 4's macro system can be
found in [Beyond Notations: Hygienic Macro Expansion for Theorem Proving
Languages](https://arxiv.org/abs/2001.10490) by Sebastian Ullrich and Leonardo
de Moura, and the accompanying repo with example code can be found in the
paper's code [supplement](https://github.com/Kha/macro-supplement). The
supplement also includes a working implementation of the macro expander, so it's
a good case study for people interested in the details.
## What is a macro in Lean?
A macro is a function that takes in a syntax tree and produces a new syntax
tree. Macros are useful for many reasons, but two of the big ones are a)
allowing users to extend the language with new syntactic constructs without
having to actually expand the core language, and b) allowing users to automate
tasks that would otherwise be extremely repetitive, time-consuming, and/or
error-prone.
A motivating example is set builder notation. We would like to be able to write
the set of natural numbers 0, 1, and 2 as just `{0, 1, 2}`. However, Lean does
not natively support this syntax, and the actual definition of a set in Mathlib
does not let us just declare sets in this manner; naively using the set API
would force us to write `Set.insert 1 (Set.insert 2 (Set.singleton 3))`.
Instead, we can teach Lean's macro system to recognize `{0, 1, 2}` as a
shorthand for a composition of existing methods and let it do the repetitive
work of creating the `Set.insert...` invocation for us. In this way, we can have
our more readable and more convenient syntax without having to extend Lean
itself, and while retaining the simple insert/singleton API.
## How macros are handled
The general procedure is as follows:
1. Lean parses a command, creating a Lean syntax tree which contains any
unexpanded macros.
2. Lean repeats the cycle (elaboration ~> (macro hygiene and expansion) ~>
elaboration...)
The cycle in step 2 repeats until there are no more macros which need to be
expanded, and elaboration can finish normally. This repetition is required since
macros can expand to other macros, and may expand to code that needs information
from the elaborator. As you can see, the process of macro parsing and expansion
is interleaved with the parsing and elaboration of non-macro code.
By default, macros in Lean are hygienic, which means the system avoids
accidental name capture when reusing the same name inside and outside the macro.
Users may occasionally want to disable hygiene, which can be accomplished with
the command `set_option hygiene false`. More in-depth information about hygiene
and how it's implemented in the official paper and supplement linked at the top
of this guide.
## Elements of "a" macro (important types)
In the big picture, a macro has two components that must be implemented by the
user, parsers and syntax transformers, where the latter is a function that says
what the input syntax should expand to. There is a third component, syntax
categories, such as `term`, `tactic`, and `command`, but declaring a new syntax
category is not always necessary. When we say "parser" in the context of a
macro, we refer to the core type `Lean.ParserDescr`, which parses elements of
type `Lean.Syntax`, where `Lean.Syntax` represents elements of a Lean syntax
tree. Syntax transformers are functions of type `Syntax -> MacroM Syntax`. Lean
has a synonym for this type, which is simply `Macro`. `MacroM` is a monad that
carries state needed for macro expansion to work nicely, including the info
needed to implement hygiene.
As an example, we again refer to Mathlib's set builder notation:
```lean
/- Declares a parser -/
syntax (priority := high) "{" term,+ "}" : term
/- Declares two expansions/syntax transformers -/
macro_rules
| `({$x}) => `(Set.singleton $x)
| `({$x, $xs:term,*}) => `(Set.insert $x {$xs,*})
/- Provided `Set` has been imported (from Mathlib4), these are all we need for `{1, 2, 3}` to be valid notation to create a literal set -/
```
This example should also make clear the reason why macros (and pretty much all
of Lean 4's metaprogramming facilities) are functions that take an argument of
type `Syntax` e.g. `Syntax -> MacroM Syntax`; the leading syntax element is the
thing that actually triggers the macro expansion by matching with the declared
parser, and as a user, you will almost always be interested in inspecting and
transforming that initial syntax element (though there are cases in which it can
just be ignored, as in the parameter-less exfalso tactic).
Returning briefly to the API provided by Lean, `Lean.Syntax`, is pretty much
what you would expect a basic syntax tree type to look like. Below is a slightly
simplified representation which omits details in the `atom` and `ident`
constructors; users can create atoms and idents which comport with this
simplified representation using the `mkAtom` and `mkIdent` methods provided in
the `Lean` namespace.
```lean
# open Lean
inductive Syntax where
| missing : Syntax
| node (kind : SyntaxNodeKind) (args : Array Syntax) : Syntax
| atom : String -> Syntax
| ident : Name -> Syntax
```
For those interested, `MacroM` is a `ReaderT`:
```lean
# open Lean
abbrev MacroM := ReaderT Macro.Context (EStateM Macro.Exception Macro.State)
```
The other relevant components are defined as follows:
```lean
# open Lean
structure Context where
methods : MethodsRef
mainModule : Name
currMacroScope : MacroScope
currRecDepth : Nat := 0
maxRecDepth : Nat := defaultMaxRecDepth
ref : Syntax
inductive Exception where
| error : Syntax String Exception
| unsupportedSyntax : Exception
structure State where
macroScope : MacroScope
traceMsgs : List (Prod Name String) := List.nil
deriving Inhabited
```
As a review/checklist, the three (sometimes only two depending on whether you
need a new syntax category) components users need to be concerned with are:
0. You may or may not need to declare a new syntax category using
`declare_syntax_cat`
1. Declare a parser with either `syntax` or `macro`
2. Declare an expansion/syntax transformer with either `macro_rules` or `macro`
Parsers and syntax transformers can be declared manually, but use of the pattern
language and `syntax`, `macro_rules`, and `macro` is recommended.
## syntax categories with declare_syntax_cat
`declare_syntax_cat` declares a new syntax category, like `command`, `tactic`,
or mathlib4's `binderterm`. These are the different categories of things that
can be referred to in a quote/antiquote. `declare_syntax_cat` results in a call
to `registerParserCategory` and produces a new parser descriptor:
```lean
set_option trace.Elab.definition true in
declare_syntax_cat binderterm
/-
Output:
[Elab.definition.body] binderterm.quot : Lean.ParserDescr :=
Lean.ParserDescr.node `Lean.Parser.Term.quot 1024
(Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol "`(binderterm|")
(Lean.ParserDescr.binary `andthen (Lean.ParserDescr.cat `binderterm 0)
(Lean.ParserDescr.symbol ")")))
-/
```
Declaring a new syntax category like this one automatically declares a quotation
operator `` `(binderterm| ...)``. These pipe prefixes `<thing>|` are used in
syntax quotations to say what category a given quotation is expected to be an
element of. The pipe prefixes are *not* used for elements in the `term` and
`command` categories (since they're considered the default), but need to be used
for everything else.
## Parsers and the `syntax` keyword
Internally, elements of type `Lean.ParserDescr` are implemented as parser
combinators. However, Lean offers the ability to write parsers using the
macro/pattern language by way of the `syntax` keyword. This is the recommended
means of writing parsers. As an example, the parser for the `rwa` (rewrite, then
use assumption) tactic is:
```lean
# open Lean.Parser.Tactic
set_option trace.Elab.definition true in
syntax "rwa " rwRuleSeq (location)? : tactic
/-
which expands to:
[Elab.definition.body] tacticRwa__ : Lean.ParserDescr :=
Lean.ParserDescr.node `tacticRwa__ 1022
(Lean.ParserDescr.binary `andthen
(Lean.ParserDescr.binary `andthen (Lean.ParserDescr.nonReservedSymbol "rwa " false) Lean.Parser.Tactic.rwRuleSeq)
(Lean.ParserDescr.unary `optional Lean.Parser.Tactic.location))
-/
```
Literals are written as double-quoted strings (`"rwa "` expects the literal
sequence of characters `rwa`, while the trailing space provides a hint to the
formatter that it should add a space after `rwa` when pretty printing this
syntax); `rwRuleSeq` and `location` are themselves `ParserDescr`s, and we finish
with `: tactic` specifying that the preceding parser is for an element in the
`tactic` syntax category. The parentheses around `(location)?` are necessary
(rather than `location?`) because Lean 4 allows question marks to be used in
identifiers, so `location?` is one single identifier that ends with a question
mark, which is not what we want.
The name `tacticRwa__` is automatically generated. You can name parser
descriptors declared with the `syntax` keyword like so:
```lean
set_option trace.Elab.definition true in
syntax (name := introv) "introv " (colGt ident)* : tactic
/-
[Elab.definition.body] introv : Lean.ParserDescr :=
Lean.ParserDescr.node `introv 1022
(Lean.ParserDescr.binary `andthen (Lean.ParserDescr.nonReservedSymbol "introv " false)
(Lean.ParserDescr.unary `many
(Lean.ParserDescr.binary `andthen (Lean.ParserDescr.const `colGt) (Lean.ParserDescr.const `ident))))
-/
```
## The pattern language
Available quantifiers are `?` (one or zero occurrences, see note below), `*`
(zero or more occurrences), and `+` (one or more occurrences).
Keep in mind that Lean makes `?` available for use in identifiers, so if we want
a parser to look for an optional `location`, we would need to write
`(location)?` with parenthesis acting as a separator, since `location?` would
look for something under the identifier `location?` (where the `?` is part of
the identifier).
Parentheses can be used as delimiters.
Separated lists can be constructed like so: `$ts,*` for a comma separated list.
"extended splices" can be constructed as `$[..]`. See the official paper (p. 12)
for more details.
Literals are written as double-quoted strings. A literal may use trailing
whitespace (see e.g. the `rwa` or `introv` tactics) to tell the pretty-printer
how it should be displayed, but such whitespace will not prevent a literal with
no trailing whitespace from matching. The spaces are relevant, but not
interpreted literally. When the ParserDescr is turned into a Parser, the actual
token matcher [uses the .trim of the provided
string](https://github.com/leanprover/lean4/blob/53ec43ff9b8f55989b12c271e368287b7b997b54/src/Lean/Parser/Basic.lean#L1193),
but the generated formatter [uses the spaces as
specified](https://github.com/leanprover/lean4/blob/8d370f151f7c88a687152a5b161dcb484c446ce2/src/Lean/PrettyPrinter/Formatter.lean#L328),
that is, turning the atom "rwa" in the syntax into the string rwa as part of the
pretty printed output.
## Syntax expansions with `macro_rules`, and how it desugars.
`macro_rules` lets you declare expansions for a given `Syntax` element using a
syntax similar to a `match` statement. The left-hand side of a match arm is a
quotation (with a leading `<cat>|` for categories other than `term` and
`command`) in which users can specify the pattern they'd like to write an
expansion for. The right-hand side returns a syntax quotation which is the
output the user wants to expand to.
A feature of Lean's macro system is that if there are multiple expansions for a
particular match, Lean will try the most recently declared expansion first, and
will retry with other matching expansions if the previous attempt failed. This
is particularly useful for extending existing tactics.
The following example shows both the retry behavior, and the fact that macros
declared using the shorthand `macro` syntax can still have additional expansions
declared with `macro_rules`. This `transitivity` tactic is implemented such that
it will work for either Nat.le or Nat.lt. The Nat.lt version was declared "most
recently", so it will be tried first, but if it fails (for example, if the
actual term in question is Nat.le) the next potential expansion will be tried:
```lean
macro "transitivity" e:(colGt term) : tactic => `(tactic| apply Nat.le_trans (m := $e))
macro_rules
| `(tactic| transitivity $e) => `(tactic| apply Nat.lt_trans (m := $e))
example (a b c : Nat) (h0 : a < b) (h1 : b < c) : a < c := by
transitivity b <;>
assumption
example (a b c : Nat) (h0 : a <= b) (h1 : b <= c) : a <= c := by
transitivity b <;>
assumption
/- This will fail, but is interesting in that it exposes the "most-recent first" behavior, since the
error message complains about being unable to unify mvar1 <= mvar2, rather than mvar1 < mvar2. -/
/-
example (a b c : Nat) (h0 : a <= b) (h1 : b <= c) : False := by
transitivity b <;>
assumption
-/
```
To see the desugared definition of the actual expansion, we can again use
`set_option trace.Elab.definition true in` and observe the output of the humble
`exfalso` tactic defined in Mathlib4:
```lean
set_option trace.Elab.definition true in
macro "exfalso" : tactic => `(tactic| apply False.elim)
/-
Results in the expansion:
[Elab.definition.body] _aux___macroRules_tacticExfalso_1 : Lean.Macro :=
fun x =>
let discr := x;
/- This is where Lean tries to actually identify that it's an invocation of the exfalso tactic -/
if Lean.Syntax.isOfKind discr `tacticExfalso = true then
let discr := Lean.Syntax.getArg discr 0;
let x := discr;
do
/- Lean getting scope/meta info from the macro monad -/
let info ← Lean.MonadRef.mkInfoFromRefPos
let scp ← Lean.getCurrMacroScope
let mainModule ← Lean.getMainModule
pure
(Lean.Syntax.node Lean.SourceInfo.none `Lean.Parser.Tactic.seq1
#[Lean.Syntax.node Lean.SourceInfo.none `null
#[Lean.Syntax.node Lean.SourceInfo.none `Lean.Parser.Tactic.apply
#[Lean.Syntax.atom info "apply",
Lean.Syntax.ident info (String.toSubstring "False.elim")
(Lean.addMacroScope mainModule `False.elim scp) [(`False.elim, [])]]]])
else
/- If this wasn't actually an invocation of the exfalso tactic, throw the "unsupportedSyntax" error -/
let discr := x;
throw Lean.Macro.Exception.unsupportedSyntax
-/
```
We can also create the syntax transformer declaration ourselves instead of using
`macro_rules`. We'll need to name our parser and use the attribute `@[macro
myExFalsoParser]` to associate our declaration with the parser:
```lean
# open Lean
syntax (name := myExfalsoParser) "myExfalso" : tactic
-- remember that `Macro` is a synonym for `Syntax -> TacticM Unit`
@[macro myExfalsoParser] def implMyExfalso : Macro :=
fun stx => `(tactic| apply False.elim)
example (p : Prop) (h : p) (f : p -> False) : 3 = 2 := by
myExfalso
exact f h
```
In the above example, we're still using the sugar Lean provides for creating
quotations, as it feels more intuitive and saves us some work. It is possible to
forego the sugar altogether:
```lean
syntax (name := myExfalsoParser) "myExfalso" : tactic
@[macro myExfalsoParser] def implMyExfalso : Lean.Macro :=
fun stx => pure (Lean.mkNode `Lean.Parser.Tactic.apply
#[Lean.mkAtomFrom stx "apply", Lean.mkCIdentFrom stx ``False.elim])
example (p : Prop) (h : p) (f : p -> False) : 3 = 2 := by
myExfalso
exact f h
```
## The `macro` keyword
`macro` is a shortcut which allows users to declare both a parser and an
expansion at the same time as a matter of convenience. Additional expansions for
the parser generated by the `macro` invocation can be added with a separate
`macro_rules` block (see the example in the `macro_rules` section).
## Unexpanders
TODO; for now, see the unexpander in Mathlib.Set for an example.
## More illustrative examples:
The
[Tactic.Basic](https://github.com/leanprover-community/mathlib4/blob/master/Mathlib/Tactic/Basic.lean)
file in Mathlib4 contains many good examples to learn from.
## Practical tips:
You can observe the output of commands and functions that in some way use the
macro system by setting this option to true : `set_option trace.Elab.definition
true`
Lean also offers the option of limiting the region in which option is set with
the syntax `set_option ... in`):
Hygiene can be disabled with the command option `set_option hygiene false`

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](doc/dev/index.md).
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](doc/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 [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.
Requirements
------------

View File

@@ -15,17 +15,24 @@ Mode](https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-devi
which will allow Lean to create symlinks that e.g. enable go-to-definition in
the stdlib.
## Installing the Windows SDK
Install the Windows SDK from [Microsoft](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/).
The oldest supported version is 10.0.18362.0. If you installed the Windows SDK to the default location,
then there should be a directory with the version number at `C:\Program Files (x86)\Windows Kits\10\Include`.
If there are multiple directories, only the highest version number matters.
## Installing dependencies
[The official webpage of MSYS2][msys2] provides one-click installers.
Once installed, you should run the "MSYS2 MinGW 64-bit shell" from the start menu (the one that runs `mingw64.exe`).
Do not run "MSYS2 MSYS" instead!
MSYS2 has a package management system, [pacman][pacman], which is used in Arch Linux.
Once installed, you should run the "MSYS2 CLANG64" shell from the start menu (the one that runs `clang64.exe`).
Do not run "MSYS2 MSYS" or "MSYS2 MINGW64" instead!
MSYS2 has a package management system, [pacman][pacman].
Here are the commands to install all dependencies needed to compile Lean on your machine.
```bash
pacman -S make python mingw-w64-x86_64-cmake mingw-w64-x86_64-clang mingw-w64-x86_64-ccache mingw-w64-x86_64-libuv mingw-w64-x86_64-gmp git unzip diffutils binutils
pacman -S make python mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-ccache mingw-w64-clang-x86_64-libuv mingw-w64-clang-x86_64-gmp git unzip diffutils binutils
```
You should now be able to run these commands:
@@ -61,8 +68,7 @@ If you want a version that can run independently of your MSYS install
then you need to copy the following dependent DLL's from where ever
they are installed in your MSYS setup:
- libgcc_s_seh-1.dll
- libstdc++-6.dll
- libc++.dll
- libgmp-10.dll
- libuv-1.dll
- libwinpthread-1.dll
@@ -82,6 +88,6 @@ version clang to your path.
**-bash: gcc: command not found**
Make sure `/mingw64/bin` is in your PATH environment. If it is not then
check you launched the MSYS2 MinGW 64-bit shell from the start menu.
(The one that runs `mingw64.exe`).
Make sure `/clang64/bin` is in your PATH environment. If it is not then
check you launched the MSYS2 CLANG64 shell from the start menu.
(The one that runs `clang64.exe`).

View File

@@ -32,12 +32,13 @@ following to use `g++`.
cmake -DCMAKE_CXX_COMPILER=g++ ...
```
## Required Packages: CMake, GMP, libuv
## Required Packages: CMake, GMP, libuv, pkgconf
```bash
brew install cmake
brew install gmp
brew install libuv
brew install pkgconf
```
## Recommended Packages: CCache

View File

@@ -8,5 +8,5 @@ follow the [generic build instructions](index.md).
## Basic packages
```bash
sudo apt-get install git libgmp-dev libuv1-dev cmake ccache clang
sudo apt-get install git libgmp-dev libuv1-dev cmake ccache clang pkgconf
```

View File

@@ -1 +0,0 @@
*.lean.md

View File

@@ -1,334 +0,0 @@
/-!
# Applicative Functors
Building on [Functors](functors.lean.md) is the [Applicative
Functor](https://en.wikipedia.org/wiki/Applicative_functor). For simplicity, you can refer to these
simply as "Applicatives". These are a little tricker than functors, but still simpler than monads.
Let's see how they work!
## What is an Applicative Functor?
An applicative functor defines a default or "base" construction for an object and allows
function application to be chained across multiple instances of the structure. All applicative
functors are functors, meaning they must also support the "map" operation.
## How are Applicatives represented in Lean?
An [applicative functor](https://en.wikipedia.org/wiki/Applicative_functor) is an intermediate
structure between `Functor` and `Monad`. It mainly consists of two operations:
* `pure : α → F α`
* `seq : F (α → β) → F α → F β` (written as `<*>`)
The `pure` operator specifies how you can wrap a normal object `α` into an instance of this structure `F α`.
This is the "default" mechanism mentioned above.
The `seq` operator allows you to chain operations by wrapping a function in a structure. The name
"applicative" comes from the fact that you "apply" functions from within the structure, rather than
simply from outside the structure, as was the case with `Functor.map`.
Applicative in Lean is built on some helper type classes, `Functor`, `Pure` and `Seq`:
-/
namespace hidden -- hidden
class Applicative (f : Type u Type v) extends Functor f, Pure f, Seq f, SeqLeft f, SeqRight f where
map := fun x y => Seq.seq (pure x) fun _ => y
seqLeft := fun a b => Seq.seq (Functor.map (Function.const _) a) b
seqRight := fun a b => Seq.seq (Functor.map (Function.const _ id) a) b
end hidden -- hidden
/-!
Notice that as with `Functor` it is also a type transformer `(f : Type u → Type v)` and notice the
`extends Functor f` is ensuring the base `Functor` also performs that same type transformation.
As stated above, all applicatives are then functors. This means you can assume that `map` already
exists for all these types.
The `Pure` base type class is a very simple type class that supplies the `pure` function.
-/
namespace hidden -- hidden
class Pure (f : Type u Type v) where
pure {α : Type u} : α f α
end hidden -- hidden
/-!
You can think of it as lifting the result of a pure value to some monadic type. The simplest example
of `pure` is the `Option` type:
-/
#eval (pure 10 : Option Nat) -- some 10
/-!
Here we used the `Option` implementation of `pure` to wrap the `Nat 10` value in an `Option Nat`
type resulting in the value `some 10`, and in fact if you look at the Monad instance of `Option` , you
will see that `pure` is indeed implemented using `Option.some`:
-/
instance : Monad Option where
pure := Option.some
/-!
The `Seq` type class is also a simple type class that provides the `seq` operator which can
also be written using the special syntax `<*>`.
-/
namespace hidden -- hidden
class Seq (f : Type u Type v) : Type (max (u+1) v) where
seq : {α β : Type u} f (α β) (Unit f α) f β
end hidden -- hidden
/-!
## Basic Applicative Examples
Many of the basic functors also have instances of `Applicative`.
For example, `Option` is also `Applicative`.
So let's take a look and what the `seq` operator can do. Suppose you want to multiply two `Option Nat`
objects. Your first attempt might be this:
-/
#check_failure (some 4) * (some 5) -- failed to synthesize instance
/-!
You then might wonder how to use the `Functor.map` to solve this since you could do these before:
-/
#eval (some 4).map (fun x => x * 5) -- some 20
#eval (some 4).map (· * 5) -- some 20
#eval (· * 5) <$> (some 4) -- some 20
/-!
Remember that `<$>` is the infix notation for `Functor.map`.
The functor `map` operation can apply a multiplication to the value in the `Option` and then lift the
result back up to become a new `Option` , but this isn't what you need here.
The `Seq.seq` operator `<*>` can help since it can apply a function to the items inside a
container and then lift the result back up to the desired type, namely `Option` .
There are two ways to do this:
-/
#eval pure (.*.) <*> some 4 <*> some 5 -- some 20
#eval (.*.) <$> some 4 <*> some 5 -- some 20
/-!
In the first way, we start off by wrapping the function in an applicative using pure. Then we apply
this to the first `Option` , and again to the second `Option` in a chain of operations. So you can see
how `Seq.seq` can be chained in fact, `Seq.seq` is really all about chaining of operations.
But in this case there is a simpler way. In the second way, you can see that "applying" a single
function to a container is the same as using `Functor.map`. So you use `<$>` to "transform" the first
option into an `Option` containing a function, and then apply this function over the second value.
Now if either side is `none`, the result is `none`, as expected, and in this case the
`seq` operator was able to eliminate the multiplication:
-/
#eval (.*.) <$> none <*> some 5 -- none
#eval (.*.) <$> some 4 <*> none -- none
/-!
For a more interesting example, let's make `List` an applicative by adding the following
definition:
-/
instance : Applicative List where
pure := List.pure
seq f x := List.bind f fun y => Functor.map y (x ())
/-!
Notice you can now sequence a _list_ of functions and a _list_ of items.
The trivial case of sequencing a singleton list is in fact the same as `map`, as you saw
earlier with the `Option` examples:
-/
#eval [ (·+2)] <*> [4, 6] -- [6, 8]
#eval (·+2) <$> [4,6] -- [6, 8]
/-!
But now with list it is easier to show the difference when you do this:
-/
#eval [(·+2), (· *3)] <*> [4, 6] -- [6, 8, 12, 18]
/-!
Why did this produce 4 values? The reason is because `<*>` applies _every_ function to _every_
value in a pairwise manner. This makes sequence really convenient for solving certain problems. For
example, how do you get the pairwise combinations of all values from two lists?
-/
#eval Prod.mk <$> [1, 2, 3] <*> [4, 5, 6]
-- [(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]
/-!
How do you get the sum of these pairwise values?
-/
#eval (·+·) <$> [1, 2, 3] <*> [4, 5, 6]
-- [5, 6, 7, 6, 7, 8, 7, 8, 9]
/-!
Here you can use `<$>` to "transform" each element of the first list into a function, and then apply
these functions over the second list.
If you have 3 lists, and want to find all combinations of 3 values across those lists you
would need helper function that can create a tuple out of 3 values, and Lean provides a
very convenient syntax for that `(·,·,·)`:
-/
#eval (·,·,·) <$> [1, 2] <*> [3, 4] <*> [5, 6]
-- [(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]
/-!
And you could sum these combinations if you first define a sum function that takes three inputs and
then you could chain apply this over the three lists. Again lean can create such a function
with the expression `(·+·+·)`:
-/
#eval (·+·+·) <$> [1, 2] <*> [3, 4] <*> [5, 6]
-- [9, 10, 10, 11, 10, 11, 11, 12]
/-!
And indeed each sum here matches the expected values if you manually sum the triples we
show above.
**Side note:** there is another way to combine lists with a function that does not do the pairwise
combinatorics, it is called `List.zipWith`:
-/
#eval List.zipWith (·+·) [1, 2, 3] [4, 5, 6]
-- [5, 7, 9]
/-!
And there is a helper function named `List.zip` that calls `zipWith` using the function `Prod.mk`
so you get a nice zipped list like this:
-/
#eval List.zip [1, 2, 3] [4, 5, 6]
-- [(1, 4), (2, 5), (3, 6)]
/-!
And of course, as you would expect, there is an `unzip` also:
-/
#eval List.unzip (List.zip [1, 2, 3] [4, 5, 6])
-- ([1, 2, 3], [4, 5, 6])
/-!
## Example: A Functor that is not Applicative
From the chapter on [functors](functors.lean.md) you might remember this example of `LivingSpace`
that had a `Functor` instance:
-/
structure LivingSpace (α : Type) where
totalSize : α
numBedrooms : Nat
masterBedroomSize : α
livingRoomSize : α
kitchenSize : α
deriving Repr, BEq
def LivingSpace.map (f : α β) (s : LivingSpace α) : LivingSpace β :=
{ totalSize := f s.totalSize
numBedrooms := s.numBedrooms
masterBedroomSize := f s.masterBedroomSize
livingRoomSize := f s.livingRoomSize
kitchenSize := f s.kitchenSize }
instance : Functor LivingSpace where
map := LivingSpace.map
/-!
It wouldn't really make sense to make an `Applicative` instance here. How would you write `pure` in
the `Applicative` instance? By taking a single value and plugging it in for total size _and_ the
master bedroom size _and_ the living room size? That wouldn't really make sense. And what would the
numBedrooms value be for the default? What would it mean to "chain" two of these objects together?
If you can't answer these questions very well, then it suggests this type isn't really an
Applicative functor.
## SeqLeft and SeqRight
You may remember seeing the `SeqLeft` and `SeqRight` base types on `class Applicative` earlier.
These provide the `seqLeft` and `seqRight` operations which also have some handy notation
shorthands `<*` and `*>` respectively. Where: `x <* y` evaluates `x`, then `y`, and returns the
result of `x` and `x *> y` evaluates `x`, then `y`, and returns the result of `y`.
To make it easier to remember, notice that it returns that value that the `<*` or `*>` notation is
pointing at. For example:
-/
#eval (some 1) *> (some 2) -- Some 2
#eval (some 1) <* (some 2) -- Some 1
/-!
So these are a kind of "discard" operation. Run all the actions, but only return the values that you
care about. It will be easier to see these in action when you get to full Monads, but they are used
heavily in the Lean `Parsec` parser combinator library where you will find parsing functions like
this one which parses the XML declaration `<?xml version="1.0" encoding='utf-8' standalone="yes">`:
```lean
def XMLdecl : Parsec Unit := do
skipString "<?xml"
VersionInfo
optional EncodingDecl *> optional SDDecl *> optional S *> skipString "?>"
```
But you will need to understand full Monads before this will make sense.
## Lazy Evaluation
Diving a bit deeper, (you can skip this and jump to the [Applicative
Laws](laws.lean.md#what-are-the-applicative-laws) if don't want to dive into this implementation detail right
now). But, if you write a simple `Option` example `(.*.) <$> some 4 <*> some 5` that produces `some 20`
using `Seq.seq` you will see something interesting:
-/
#eval Seq.seq ((.*.) <$> some 4) (fun (_ : Unit) => some 5) -- some 20
/-!
This may look a bit cumbersome, specifically, why did we need to invent this funny looking function
`fun (_ : Unit) => (some 5)`?
Well if you take a close look at the type class definition:
```lean
class Seq (f : Type u → Type v) where
seq : {α β : Type u} → f (α → β) → (Unit → f α) → f β
```
You will see this function defined here: `(Unit → f α)`, this is a function that takes `Unit` as input
and produces the output of type `f α` where `f` is the container type `Type u -> Type v`, in this example `Option`
and `α` is the element type `Nat`, so `fun (_ : Unit) => some 5` matches this definition because
it is taking an input of type Unit and producing `some 5` which is type `Option Nat`.
The that `seq` is defined this way is because Lean is an eagerly evaluated language
(call-by-value), you have to use this kind of Unit function whenever you want to explicitly delay
evaluation and `seq` wants that so it can eliminate unnecessary function evaluations whenever
possible.
Fortunately the `<*>` infix notation hides this from you by creating this wrapper function for you.
If you look up the notation using F12 in VS Code you will find it contains `(fun _ : Unit => b)`.
Now to complete this picture you will find the default implementation of `seq` on the Lean `Monad`
type class:
```lean
class Monad (m : Type u → Type v) extends Applicative m, Bind m where
seq f x := bind f fun y => Functor.map y (x ())
```
Notice here that `x` is the `(Unit → f α)` function, and it is calling that function by passing the
Unit value `()`, which is the Unit value (Unit.unit). All this just to ensure delayed evaluation.
## How do Applicatives help with Monads?
Applicatives are helpful for the same reasons as functors. They're a relatively simple abstract
structure that has practical applications in your code. Now that you understand how chaining
operations can fit into a structure definition, you're in a good position to start learning about
[Monads](monads.lean.md)!
-/

View File

@@ -1,178 +0,0 @@
/-!
# Except
The `Except` Monad adds exception handling behavior to your functions. Exception handling
in other languages like Python or Java is done with a built in `throw` method that you
can use anywhere. In `Lean` you can only `throw` an exception when your function is
executing in the context of an `Except` monad.
-/
def divide (x y: Float): Except String Float :=
if y == 0 then
throw "can't divide by zero"
else
pure (x / y)
#eval divide 5 2 -- Except.ok 2.500000
#eval divide 5 0 -- Except.error "can't divide by zero"
/-!
Just as the `read` operation was available from the `ReaderM` monad and the `get` and `set`
operations came with the `StateM` monad, here you can see a `throw` operation is provided by the
`Except` monad.
So in Lean, `throw` is not available everywhere like it is in most imperative programming languages.
You have to declare your function can throw by changing the type signature to `Except String Float`.
This creates a function that might return an error of type `String` or it might return a value of
type `Float` in the non-error case.
Once your function is monadic you also need to use the `pure` constructor of the `Except` monad to
convert the pure non-monadic value `x / y` into the required `Except` object. See
[Applicatives](applicatives.lean.md) for details on `pure`.
Now this return typing would get tedious if you had to include it everywhere that you call this
function, however, Lean type inference can clean this up. For example, you can define a test
function that calls the `divide` function and you don't need to say anything here about the fact that
it might throw an error, because that is inferred:
-/
def test := divide 5 0
#check test -- Except String Float
/-!
Notice the Lean compiler infers the required `Except String Float` type information for you.
And now you can run this test and get the expected exception:
-/
#eval test -- Except.error "can't divide by zero"
/-!
## Chaining
Now as before you can build a chain of monadic actions that can be composed together using `bind (>>=)`:
-/
def square (x : Float) : Except String Float :=
if x >= 100 then
throw "it's absolutely huge"
else
pure (x * x)
#eval divide 6 2 >>= square -- Except.ok 9.000000
#eval divide 6 0 >>= square -- Except.error "can't divide by zero"
#eval divide 100 1 >>= square -- Except.error "it's absolutely huge"
def chainUsingDoNotation := do
let r divide 6 0
square r
#eval chainUsingDoNotation -- Except.error "can't divide by zero"
/-!
Notice in the second `divide 6 0` the exception from that division was nicely propagated along
to the final result and the square function was ignored in that case. You can see why the
`square` function was ignored if you look at the implementation of `Except.bind`:
-/
def bind (ma : Except ε α) (f : α Except ε β) : Except ε β :=
match ma with
| Except.error err => Except.error err
| Except.ok v => f v
/-!
Specifically notice that it only calls the next function `f v` in the `Except.ok`, and
in the error case it simply passes the same error along.
Remember also that you can chain the actions with implicit binding by using the `do` notation
as you see in the `chainUsingDoNotation` function above.
## Try/Catch
Now with all good exception handling you also want to be able to catch exceptions so your program
can continue on or do some error recovery task, which you can do like this:
-/
def testCatch :=
try
let r divide 8 0 -- 'r' is type Float
pure (toString r)
catch e =>
pure s!"Caught exception: {e}"
#check testCatch -- Except String String
/-!
Note that the type inferred by Lean for this function is `Except String String` so unlike the
`test` function earlier, this time Lean type inference has figured out that since the pure
value `(toString r)` is of type `String`, then this function must have type `Except String String`
so you don't have to explicitly state this. You can always hover your mouse over `testCatch`
or use `#check testCatch` to query Lean interactively to figure out what type inference
has decided. Lean type inference makes life easy for you, so it's good to use it
when you can.
You can now see the try/catch working in this eval:
-/
#eval testCatch -- Except.ok "Caught exception: can't divide by zero"
/-!
Notice the `Caught exception:` wrapped message is returned, and that it is returned as an
`Except.ok` value, meaning `testCatch` eliminated the error result as expected.
So you've interleaved a new concept into your functions (exception handling) and the compiler is still
able to type check everything just as well as it does for pure functions and it's been able to infer
some things along the way to make it even easier to manage.
Now you might be wondering why `testCatch` doesn't infer the return type `String`? Lean does this as a
convenience since you could have a rethrow in or after the catch block. If you really want to stop
the `Except` type from bubbling up you can unwrap it like this:
-/
def testUnwrap : String := Id.run do
let r divide 8 0 -- r is type Except String Float
match r with
| .ok a => toString a -- 'a' is type Float
| .error e => s!"Caught exception: {e}"
#check testUnwrap -- String
#eval testUnwrap -- "Caught exception: can't divide by zero"
/-!
The `Id.run` function is a helper function that executes the `do` block and returns the result where
`Id` is the _identity monad_. So `Id.run do` is a pattern you can use to execute monads in a
function that is not itself monadic. This works for all monads except `IO` which, as stated earlier,
you cannot invent out of thin air, you must use the `IO` monad given to your `main` function.
## Monadic functions
You can also write functions that are designed to operate in the context of a monad.
These functions typically end in upper case M like `List.forM` used below:
-/
def validateList (x : List Nat) (max : Nat): Except String Unit := do
x.forM fun a => do
if a > max then throw "illegal value found in list"
#eval validateList [1, 2, 5, 3, 8] 10 -- Except.ok ()
#eval validateList [1, 2, 5, 3, 8] 5 -- Except.error "illegal value found in list"
/-!
Notice here that the `List.forM` function passes the monadic context through to the inner function
so it can use the `throw` function from the `Except` monad.
The `List.forM` function is defined like this where `[Monad m]` means "in the context of a monad `m`":
-/
def forM [Monad m] (as : List α) (f : α m PUnit) : m PUnit :=
match as with
| [] => pure
| a :: as => do f a; List.forM as f
/-!
## Summary
Now that you know all these different monad constructs, you might be wondering how you can combine
them. What if there was some part of your state that you wanted to be able to modify (using the
State monad), but you also needed exception handling. How can you get multiple monadic capabilities
in the same function. To learn the answer, head to [Monad Transformers](transformers.lean.md).
-/

View File

@@ -1,227 +0,0 @@
/-!
# Functor
A `Functor` is any type that can act as a generic container that allows you to transform the
underlying values inside the container using a function, so that the values are all updated, but the
structure of the container is the same. This is called "mapping".
A List is one of the most basic examples of a `Functor`.
A list contains zero or more elements of the same, underlying type. When you `map` a function over
a list, you create a new list with the same number of elements, where each has been transformed by
the function:
-/
#eval List.map (λ x => toString x) [1,2,3] -- ["1", "2", "3"]
-- you can also write this using dot notation on the List object
#eval [1,2,3].map (λ x => toString x) -- ["1", "2", "3"]
/-!
Here we converted a list of natural numbers (Nat) to a list of strings where the lambda function
here used `toString` to do the transformation of each element. Notice that when you apply `map` the
"structure" of the object remains the same, in this case the result is always a `List` of the same
size.
Note that in Lean a lambda function can be written using `fun` keyword or the unicode
symbol `λ` which you can type in VS code using `\la `.
List has a specialized version of `map` defined as follows:
-/
def map (f : α β) : List α List β
| [] => []
| a::as => f a :: map f as
/-!
This is a very generic `map` function that can take any function that converts `(α → β)` and use it
to convert `List α → List β`. Notice the function call `f a` above, this application of `f` is
producing the converted items for the new list.
Let's look at some more examples:
-/
-- List String → List Nat
#eval ["elephant", "tiger", "giraffe"].map (fun s => s.length)
-- [8, 5, 7]
-- List Nat → List Float
#eval [1,2,3,4,5].map (fun s => (s.toFloat) ^ 3.0)
-- [1.000000, 8.000000, 27.000000, 64.000000, 125.000000]
--- List String → List String
#eval ["chris", "david", "mark"].map (fun s => s.capitalize)
-- ["Chris", "David", "Mark"]
/-!
Another example of a functor is the `Option` type. Option contains a value or nothing and is handy
for code that has to deal with optional values, like optional command line arguments.
Remember you can construct an Option using the type constructors `some` or `none`:
-/
#check some 5 -- Option Nat
#eval some 5 -- some 5
#eval (some 5).map (fun x => x + 1) -- some 6
#eval (some 5).map (fun x => toString x) -- some "5"
/-!
Lean also provides a convenient short hand syntax for `(fun x => x + 1)`, namely `(· + 1)`
using the middle dot unicode character which you can type in VS code using `\. `.
-/
#eval (some 4).map (· * 5) -- some 20
/-!
The `map` function preserves the `none` state of the Option, so again
map preserves the structure of the object.
-/
def x : Option Nat := none
#eval x.map (fun x => toString x) -- none
#check x.map (fun x => toString x) -- Option String
/-!
Notice that even in the `none` case it has transformed `Option Nat` into `Option String` as
you see in the `#check` command.
## How to make a Functor Instance?
The `List` type is made an official `Functor` by the following type class instance:
-/
instance : Functor List where
map := List.map
/-!
Notice all you need to do is provide the `map` function implementation. For a quick
example, let's supposed you create a new type describing the measurements of a home
or apartment:
-/
structure LivingSpace (α : Type) where
totalSize : α
numBedrooms : Nat
masterBedroomSize : α
livingRoomSize : α
kitchenSize : α
deriving Repr, BEq
/-!
Now you can construct a `LivingSpace` in square feet using floating point values:
-/
abbrev SquareFeet := Float
def mySpace : LivingSpace SquareFeet :=
{ totalSize := 1800, numBedrooms := 4, masterBedroomSize := 500,
livingRoomSize := 900, kitchenSize := 400 }
/-!
Now, suppose you want anyone to be able to map a `LivingSpace` from one type of measurement unit to
another. Then you would provide a `Functor` instance as follows:
-/
def LivingSpace.map (f : α β) (s : LivingSpace α) : LivingSpace β :=
{ totalSize := f s.totalSize
numBedrooms := s.numBedrooms
masterBedroomSize := f s.masterBedroomSize
livingRoomSize := f s.livingRoomSize
kitchenSize := f s.kitchenSize }
instance : Functor LivingSpace where
map := LivingSpace.map
/-!
Notice this functor instance takes `LivingSpace` and not the fully qualified type `LivingSpace SquareFeet`.
Notice below that `LivingSpace` is a function from Type to Type. For example, if you give it type `SquareFeet`
it gives you back the fully qualified type `LivingSpace SquareFeet`.
-/
#check LivingSpace -- Type → Type
/-!
So the `instance : Functor` then is operating on the more abstract, or generic `LivingSpace` saying
for the whole family of types `LivingSpace α` you can map to `LivingSpace β` using the generic
`LivingSpace.map` map function by simply providing a function that does the more primitive mapping
from `(f : α → β)`. So `LivingSpace.map` is a sort of function applicator.
This is called a "higher order function" because it takes a function as input
`(α → β)` and returns another function as output `F α → F β`.
Notice that `LivingSpace.map` applies a function `f` to convert the units of all the LivingSpace
fields, except for `numBedrooms` which is a count (and therefore is not a measurement that needs
converting).
So now you can define a simple conversion function, let's say you want square meters instead:
-/
abbrev SquareMeters := Float
def squareFeetToMeters (ft : SquareFeet ) : SquareMeters := (ft / 10.7639104)
/-!
and now bringing it all together you can use the simple function `squareFeetToMeters` to map
`mySpace` to square meters:
-/
#eval mySpace.map squareFeetToMeters
/-
{ totalSize := 167.225472,
numBedrooms := 4,
masterBedroomSize := 46.451520,
livingRoomSize := 83.612736,
kitchenSize := 37.161216 }
-/
/-!
Lean also defines custom infix operator `<$>` for `Functor.map` which allows you to write this:
-/
#eval (fun s => s.length) <$> ["elephant", "tiger", "giraffe"] -- [8, 5, 7]
#eval (fun x => x + 1) <$> (some 5) -- some 6
/-!
Note that the infix operator is left associative which means it binds more tightly to the
function on the left than to the expression on the right, this means you can often drop the
parentheses on the right like this:
-/
#eval (fun x => x + 1) <$> some 5 -- some 6
/-!
Note that Lean lets you define your own syntax, so `<$>` is nothing special.
You can define your own infix operator like this:
-/
infixr:100 " doodle " => Functor.map
#eval (· * 5) doodle [1, 2, 3] -- [5, 10, 15]
/-!
Wow, this is pretty powerful. By providing a functor instance on `LivingSpace` with an
implementation of the `map` function it is now super easy for anyone to come along and
transform the units of a `LivingSpace` using very simple functions like `squareFeetToMeters`. Notice
that squareFeetToMeters knows nothing about `LivingSpace`.
## How do Functors help with Monads ?
Functors are an abstract mathematical structure that is represented in Lean with a type class. The
Lean functor defines both `map` and a special case for working on constants more efficiently called
`mapConst`:
```lean
class Functor (f : Type u → Type v) : Type (max (u+1) v) where
map : {α β : Type u} → (α → β) → f α → f β
mapConst : {α β : Type u} → α → f β → f α
```
Note that `mapConst` has a default implementation, namely:
`mapConst : {α β : Type u} → α → f β → f α := Function.comp map (Function.const _)` in the `Functor`
type class. So you can use this default implementation and you only need to replace it if
your functor has a more specialized variant than this (usually the custom version is more performant).
In general then, a functor is a function on types `F : Type u → Type v` equipped with an operator
called `map` such that if you have a function `f` of type `α → β` then `map f` will convert your
container type from `F α → F β`. This corresponds to the category-theory notion of
[functor](https://en.wikipedia.org/wiki/Functor) in the special case where the category is the
category of types and functions between them.
Understanding abstract mathematical structures is a little tricky for most people. So it helps to
start with a simpler idea like functors before you try to understand monads. Building on
functors is the next abstraction called [Applicatives](applicatives.lean.md).
-/

View File

@@ -1,63 +0,0 @@
# Monads
Monads are used heavily in Lean, as they are also in Haskell. Monads come from the wonderful world
of [Category Theory](https://en.wikipedia.org/wiki/Monad_%28category_theory%29).
Monads in Lean are so similar to Haskell that this introduction to monads is heavily based on the
similar chapter of the [Monday Morning Haskell](https://mmhaskell.com/monads/). Many thanks to
the authors of that material for allowing us to reuse it here.
Monads build on the following fundamental type classes which you will need to understand
first before fully understanding monads. Shown in light blue are some concrete functors
and monads that will also be covered in this chapter:
![image](../images/monads.svg)
This chapter is organized to give you a bottom up introduction to monads, starting with functors and
applicative functors, you'll get an intuition for how these abstract structures work in Lean. Then
you'll dive into monads and learn how to use some of the most useful built-in ones.
## [Functor](functors.lean.md)
A functor is a type class that provides a map function and the map function is something many
people are already familiar with so this should be easy to follow. Here you will see some
concrete examples in action with `List` and `Option`.
## [Applicative Functors](applicatives.lean.md)
Applicatives are a little more difficult to understand than functors, but their functionality can
still be summed up in a couple simple functions. Here you will learn how to create an
`Applicative List` and a completely custom `Applicative` type.
## [Monads Tutorial](monads.lean.md)
Now that you have an intuition for how abstract structures work, you'll examine some of the problems
that functors and applicative functors don't help you solve. Then you'll learn the specifics of how
to actually use monads with some examples using the `Option` monad and the all important `IO` monad.
## [Reader Monad](readers.lean.md)
Now that you understand the details of what makes a monadic structure work, in this section, you'll
learn about one of the most useful built in monads `ReaderM`, which gives your programs a
global read-only context.
## [State Monad](states.lean.md)
This section introduces the `StateM` monad. This monad allows you to access a particular type that you can
both read from and write to. It opens the door to fully stateful programming, allowing you to do many
of the things a function programming language supposedly "can't" do.
## [Except Monad](except.lean.md)
Similar to the `Option` monad the `Except` monad allows you to change the signature of a function so
that it can return an `ok` value or an `error` and it provides the classic exception handling
operations `throw/try/catch` so that your programs can do monad-based exception handling.
## [Monad Transformers](transformers.lean.md)
Now that you are familiar with all the above monads it is time to answer the question - how you can
make them work together? After all, there are definitely times when you need multiple kinds of
monadic behavior. This section introduces the concept of monad transformers, which allow you to
combine multiple monads into one.
## [Monad Laws](laws.lean.md)
This section examines what makes a monad a legal monad. You could just implement your monadic type
classes any way you want and write "monad" instances, but starting back with functors and
applicative functors, you'll learn that all these structures have "laws" that they are expected to
obey with respect to their behavior. You can make instances that don't follow these laws. But you do
so at your peril, as other programmers will be very confused when they try to use them.

View File

@@ -1,322 +0,0 @@
/-!
# Monad Laws
In the previous sections you learned how to use [Functors](functors.lean.md),
[Applicatives](applicatives.lean.md), and [Monads](monads.lean.md), and you played with some useful
instances including [Option](monads.lean.md), [IO](monads.lean.md), [Reader](readers.lean.md),
[State](states.lean.md) and [Except](except.lean.md) and you learned about composition using [Monad
Transformers](transformers.lean.md).
So far, you've learned the concrete details you need in order to _use_ monads in your Lean programs.
But there's still one more important concept you need if you want to _create_ new functors,
applicatives and monads. Namely, the notion of _structural "laws"_ -- rules that these type
classes should follow in order to meet other programmers' expectations about your code.
## Life without Laws
Remember Lean represents each of these abstract structures by a type class. Each of these type classes
has one or two main functions. So, as long as you implement those functions and it type checks, you
have a new functor, applicative, or monad, right?
Well not quite. Yes, your program will compile and you'll be able to use the instances. But this
doesn't mean your instances follow the mathematical constructs. If they don't, your instances won't
fulfill other programmers' expectations. Each type class has its own "laws". For instance, suppose
you have the following Point Functor:
-/
structure Point (α : Type) where
x : α
y : α
deriving Repr, BEq
def Point.map (f : α β) (s : Point α) : Point β :=
{ x := f s.y, -- an example of something weird
y := f s.x }
instance : Functor Point where
map := Point.map
#eval (·+2) <$> (Point.mk 1 2) -- { x := 4, y := 3 }
/-!
This Point does something weird, when you `map` it because it transposes the `x` and `y` coordinates
which is not what other people would expect from a `map` function. In fact, it breaks the rules
as you will see below.
## What are the Functor laws?
Functors have two laws: the _identity_ law, and the _composition_ law. These laws express behaviors that
your functor instances should follow. If they don't, other programmers will be very confused at the
effect your instances have on their program.
The identity law says that if you "map" the identity function (`id`) over your functor, the
resulting functor should be the same. A succinct way of showing this on a `List` functor is:
-/
def list1 := [1,2,3]
#eval id <$> list1 == list1 -- true
/-!
Now let's try the same test on the `Point` functor:
-/
def p1 : Point Nat := (Point.mk 1 2)
#eval id <$> p1 == p1 -- false
/-!
Oh, and look while the `List` is behaving well, the `Point` functor fails this identity test.
The _composition_ law says that if you "map" two functions in succession over a functor, this
should be the same as "composing" the functions and simply mapping that one super-function over the
functor. In Lean you can compose two functions using `Function.comp f g` (or the syntax `f ∘ g`,
which you can type in VS code using `\o `) and you will get the same results from both of these
showing that the composition law holds for `List Nat`:
-/
def double (x : Nat) := x + x
def square (x : Nat) := x * x
#eval double <$> (square <$> list1) -- [2, 8, 18]
#eval (double <$> (square <$> list1)) == ((double square) <$> list1) -- true
-- ok, what about the Point class?
#eval double <$> (square <$> p1) -- { x := 2, y := 8 }
#eval (double square) <$> p1 -- { x := 8, y := 2 }
#eval double <$> (square <$> p1) == (double square) <$> p1 -- false
/-!
Note that composition also fails on the bad `Point` because the x/y transpose.
As you can see this bad `Point` implementation violates both of the functor laws. In this case it
would not be a true functor. Its behavior would confuse any other programmers trying to use it. You
should take care to make sure that your instances make sense. Once you get a feel for these type
classes, the likelihood is that the instances you'll create will follow the laws.
You can also write a bad functor that passes one law but not the other like this:
-/
def bad_option_map {α β : Type u} : (α β) Option α Option β
| _, _ => none
instance : Functor Option where
map := bad_option_map
def t1 : Option Nat := some 10
#eval id <$> t1 == t1 -- false
#eval double <$> (square <$> t1) == (double square) <$> t1 -- true
/-!
This fails the id law but obeys the composition law. Hopefully this explains the value of these
laws, and you don't need to see any more bad examples!
## What are the Applicative Laws?
While functors have two laws, applicatives have four laws:
- Identity
- Homomorphism
- Interchange
- Composition
### Identity
`pure id <*> v = v`
Applying the identity function through an applicative structure should not change the underlying
values or structure. For example:
-/
instance : Applicative List where
pure := List.pure
seq f x := List.bind f fun y => Functor.map y (x ())
#eval pure id <*> [1, 2, 3] -- [1, 2, 3]
/-!
The `pure id` statement here is wrapping the identity function in an applicative structure
so that you can apply that over the container `[1, 2, 3]` using the Applicative `seq` operation
which has the notation `<*>`.
To prove this for all values `v` and any applicative `m` you can write this theorem:
-/
example [Applicative m] [LawfulApplicative m] (v : m α) :
pure id <*> v = v :=
by simp -- Goals accomplished 🎉
/-!
### Homomorphism
`pure f <*> pure x = pure (f x)`
Suppose you wrap a function and an object in `pure`. You can then apply the wrapped function over the
wrapped object. Of course, you could also apply the normal function over the normal object, and then
wrap it in `pure`. The homomorphism law states these results should be the same.
For example:
-/
def x := 1
def f := (· + 2)
#eval pure f <*> pure x = (pure (f x) : List Nat) -- true
/-!
You should see a distinct pattern here. The overriding theme of almost all these laws is that these
`Applicative` types should behave like normal containers. The `Applicative` functions should not
have any side effects. All they should do is facilitate the wrapping, unwrapping, and transformation
of data contained in the container resulting in a new container that has the same structure.
### Interchange
`u <*> pure y = pure (. y) <*> u`.
This law is a little more complicated, so don't sweat it too much. It states that the order that
you wrap things shouldn't matter. One the left, you apply any applicative `u` over a pure wrapped
object. On the right, you first wrap a function applying the object as an argument. Note that `(·
y)` is short hand for: `fun f => f y`. Then you apply this to the first applicative `u`. These
should be the same.
For example:
-/
def y := 4
def g : List (Nat Nat) := [(· + 2)]
#eval g <*> pure y = pure (· y) <*> g -- true
/-!
You can prove this with the following theorem:
-/
example [Applicative m] [LawfulApplicative m] (u : m (α β)) (y : α) :
u <*> pure y = pure (· y) <*> u :=
by simp [pure_seq] -- Goals accomplished 🎉
/-!
### Composition:
`u <*> v <*> w = u <*> (v <*> w)`
This final applicative law mimics the second functor law. It is a composition law. It states that
function composition holds across applications within the applicative:
For example:
-/
def u := [1, 2]
def v := [3, 4]
def w := [5, 6]
#eval pure (·+·+·) <*> u <*> v <*> w
-- [9, 10, 10, 11, 10, 11, 11, 12]
#eval let grouping := pure (·+·) <*> v <*> w
pure (·+·) <*> u <*> grouping
-- [9, 10, 10, 11, 10, 11, 11, 12]
/-!
To test composition you see the separate grouping `(v <*> w)` then that can be used in the outer
sequence `u <*> grouping` to get the same final result `[9, 10, 10, 11, 10, 11, 11, 12]`.
## What are the Monad Laws?
Monads have three laws:
- Left Identity
- Right Identity
- Associativity
### Left Identity
Identity laws for monads specify that `pure` by itself shouldn't really change anything about the
structure or its values.
Left identity is `x >>= pure = x` and is demonstrated by the following examples on a monadic `List`:
-/
instance : Monad List where
pure := List.pure
bind := List.bind
def a := ["apple", "orange"]
#eval a >>= pure -- ["apple", "orange"]
#eval a >>= pure = a -- true
/-!
### Right Identity
Right identity is `pure x >>= f = f x` and is demonstrated by the following example:
-/
def h (x : Nat) : Option Nat := some (x + 1)
def z := 5
#eval pure z >>= h -- some 6
#eval h z -- some 6
#eval pure z >>= h = h z -- true
/-!
So in this example, with this specific `z` and `h`, you see that the rule holds true.
### Associativity
The associativity law is written as:
```lean,ignore
x >>= f >>= g = x >>= (λ x => f x >>= g)
```
where `(x : m α)` and `(f : α → m β)` and `(g : β → m γ)`.
The associativity law is difficult to parse like some of the applicative laws, but what it is saying
is that if you change the grouping of `bind` operations, you should still get the same result.
This law has a parallel structure to the other composition laws.
You can see this in action in the following rewrite of `runOptionFuncsBind` from [monads](monads.lean.md):
-/
def optionFunc1 : String -> Option Nat
| "" => none
| str => some str.length
def optionFunc2 (i : Nat) : Option Float :=
if i % 2 == 0 then none else some (i.toFloat * 3.14159)
def optionFunc3 (f : Float) : Option (List Nat) :=
if f > 15.0 then none else some [f.floor.toUInt32.toNat, f.ceil.toUInt32.toNat]
def runOptionFuncsBind (input : String) : Option (List Nat) :=
optionFunc1 input >>= optionFunc2 >>= optionFunc3
def runOptionFuncsBindGrouped (input : String) : Option (List Nat) :=
optionFunc1 input >>= (λ x => optionFunc2 x >>= optionFunc3)
#eval runOptionFuncsBind "big" -- some [9, 10]
#eval runOptionFuncsBindGrouped "big" -- some [9, 10]
/-!
Notice here we had to insert a `λ` function just like the definition says: `(λ x => f x >>= g)`.
This is because unlike applicatives, you can't resolve the structure of later operations without the
results of earlier operations quite as well because of the extra context monads provide. But you can
still group their later operations into composite functions taking their inputs from earlier on, and
the result should be the same.
## Summary
While these laws may be a bit difficult to understand just by looking at them, the good news is that
most of the instances you'll make will naturally follow the laws so long as you keep it simple, so
you shouldn't have to worry about them too much.
There are two main ideas from all the laws:
1. Applying the identity or pure function should not change the underlying values or structure.
1. It should not matter what order you group operations in. Another way to state this is function
composition should hold across your structures.
Following these laws will ensure other programmers are not confused by the behavior of your
new functors, applicatives and monads.
-/

View File

@@ -1,300 +0,0 @@
/-!
# Monads
Building on [Functors](functors.lean.md) and [Applicatives](applicatives.lean.md) we can now
introduce [monads](https://en.wikipedia.org/wiki/Monad_%28category_theory%29).
A monad is another type of abstract, functional structure. Let's explore what makes it different
from the first two structures.
## What is a Monad?
A monad is a computational context. It provides a structure that allows you to chain together
operations that have some kind of shared state or similar effect. Whereas pure functional code can
only operate on explicit input parameters and affect the program through explicit return values,
operations in a monad can affect other computations in the chain implicitly through side effects,
especially modification of an implicitly shared value.
## How are monads represented in Lean?
Like functors and applicatives, monads are represented with a type class in Lean:
```lean,ignore
class Monad (m : Type u → Type v) extends Applicative m, Bind m where
```
Just as every applicative is a functor, every monad is also an applicative and there's one more new
base type class used here that you need to understand, namely, `Bind`.
```lean,ignore
class Bind (f : Type u → Type v) where
bind : {α β : Type u} → f α → (α → f β) → f β
```
The `bind` operator also has infix notation `>>=` where `x >>= g` represents the result of executing
`x` to get a value of type `f α` then unwrapping the value `α` from that and passing it to function
`g` of type `α → f β` returning the result of type `f β` where `f` is the target structure type
(like `Option` or List)
This `bind` operation looks similar to the other ones you've seen so far, if you put them all
together `Monad` has the following operations:
```lean,ignore
class Monad (f : Type u → Type v) extends Applicative f, Bind f where
pure {α : Type u} : α → f α
map : {α β : Type u} → (α → β) → f α → f β
seq : {α β : Type u} → f (α → β) → (Unit → f α) → f β
bind : {α β : Type u} → f α → (α → f β) → f β
...
```
Notice `Monad` also contains `pure` it must also have a "default" way to wrap a value in the
structure.
The `bind` operator is similar to the applicative `seq` operator in that it chains two operations,
with one of them being function related. Notice that `bind`, `seq` and `map` all take a function of
some kind. Let's examine those function types:
- map: `(α → β)`
- seq: `f (α → β)`
- bind: `(α → f β)`
So `map` is a pure function, `seq` is a pure function wrapped in the structure, and `bind` takes a
pure input but produces an output wrapped in the structure.
Note: we are ignoring the `(Unit → f α)` function used by `seq` here since that has a special
purpose explained in [Applicatives Lazy Evaluation](applicatives.lean.md#lazy-evaluation).
## Basic Monad Example
Just as `Option` is a functor and an applicative functor, it is also a monad! Let's start with how
`Option` implements the Monad type class.
-/
instance : Monad Option where
pure := Option.some
bind := Option.bind
/-!
where:
```lean,ignore
def Option.bind : Option α → (α → Option β) → Option β
| none, _ => none
| some a, f => f a
```
> **Side note**: this function definition is using a special shorthand syntax in Lean where the `:=
match a, b with` code can be collapsed away. To make this more clear consider the following simpler
example, where `Option.bind` is using the second form like `bar`:
-/
def foo (x : Option Nat) (y : Nat) : Option Nat :=
match x, y with
| none, _ => none
| some x, y => some (x + y)
def bar : Option Nat Nat Option Nat
| none, _ => none
| some x, y => some (x + y)
#eval foo (some 1) 2 -- some 3
#eval bar (some 1) 2 -- some 3
/-!
What is important is that `Option.bind` is using a `match` statement to unwrap the input value
`Option α`, if it is `none` then it does nothing and returns `none`, if it has a value of type `α`
then it applies the function in the second argument `(α → Option β)` to this value, which is
the expression `f a` that you see in the line ` | some a, f => f a` above. The function
returns a result of type `Option β` which then becomes the return value for `bind`. So there
is no structure wrapping required on the return value since the input function already did that.
But let's bring in the definition of a monad. What does it mean to describe `Option` as a
computational context?
The `Option` monad encapsulates the context of failure. Essentially, the `Option` monad lets us
abort a series of operations whenever one of them fails. This allows future operations to assume
that all previous operations have succeeded. Here's some code to motivate this idea:
-/
def optionFunc1 : String -> Option Nat
| "" => none
| str => some str.length
def optionFunc2 (i : Nat) : Option Float :=
if i % 2 == 0 then none else some (i.toFloat * 3.14159)
def optionFunc3 (f : Float) : Option (List Nat) :=
if f > 15.0 then none else some [f.floor.toUInt32.toNat, f.ceil.toUInt32.toNat]
def runOptionFuncs (input : String) : Option (List Nat) :=
match optionFunc1 input with
| none => none
| some i => match optionFunc2 i with
| none => none
| some f => optionFunc3 f
#eval runOptionFuncs "big" -- some [9, 10]
/-!
Here you see three different functions that could fail. These are then combined in `runOptionFuncs`.
But then you have to use nested `match` expressions to check if the previous result succeeded. It
would be very tedious to continue this pattern much longer.
The `Option` monad helps you fix this. Here's what this function looks like using the `bind`
operator.
-/
def runOptionFuncsBind (input : String) : Option (List Nat) :=
optionFunc1 input >>= optionFunc2 >>= optionFunc3
#eval runOptionFuncsBind "big" -- some [9, 10]
/-!
It's much cleaner now! You take the first result and pass it into the second and third functions
using the `bind` operation. The monad instance handles all the failure cases so you don't have to!
Let's see why the types work out. The result of `optionFunc1` input is simply `Option Nat`. Then the
bind operator allows you to take this `Option Nat` value and combine it with `optionFunc2`, whose type
is `Nat → Option Float` The **bind operator resolves** these to an `Option Float`. Then you pass this
similarly through the bind operator to `optionFunc3`, resulting in the final type, `Option (List Nat)`.
Your functions will not always combine so cleanly though. This is where `do` notation comes into play.
This notation allows you to write monadic operations one after another, line-by-line. It almost makes
your code look like imperative programming. You can rewrite the above as:
-/
def runOptionFuncsDo (input : String) : Option (List Nat) := do
let i optionFunc1 input
let f optionFunc2 i
optionFunc3 f
#eval runOptionFuncsDo "big" -- some [9, 10]
/-!
The `←` operator used here is special. It effectively unwraps the value on the right-hand side from
the monad. This means the value `i` has type `Nat`, _even though_ the result of `optionFunc1` is
`Option Nat`. This is done using a `bind` operation under the hood.
> Note you can use `<-` or the nice unicode symbol `←` which you can type into VS code by typing
these characters `\l `. When you type the final space, `\l` is replaced with `←`.
Observe that we do not unwrap the final line of the computation. The function result is `Option
(List Nat)` which matches what `optionFunc3` returns. At first glance, this may look more complicated
than the `bind` example. However, it gives you a lot more flexibility, like mixing monadic and
non-monadic statements, using if then/else structures with their own local do blocks and so on. It
is particularly helpful when one monadic function depends on multiple previous functions.
## Example using List
You can easily make `List` into a monad with the following, since List already provides an
implementation of `pure` and `bind`.
-/
instance : Monad List where
pure := List.pure
bind := List.bind
/-!
Like you saw with the applicative `seq` operator, the `bind` operator applies the given function
to every element of the list. It is useful to look at the bind implementation for List:
-/
open List
def bind (a : List α) (b : α List β) : List β := join (map b a)
/-!
So `Functor.map` is used to apply the function `b` to every element of `a` but this would
return a whole bunch of little lists, so `join` is used to turn those back into a single list.
Here's an example where you use `bind` to convert a list of strings into a combined list of chars:
-/
#eval "apple".toList -- ['a', 'p', 'p', 'l', 'e']
#eval ["apple", "orange"] >>= String.toList
-- ['a', 'p', 'p', 'l', 'e', 'o', 'r', 'a', 'n', 'g', 'e']
/-!
## The IO Monad
The `IO Monad` is perhaps the most important monad in Lean. It is also one of the hardest monads to
understand starting out. Its actual implementation is too intricate to discuss when first learning
monads. So it is best to learn by example.
What is the **computational context** that describes the IO monad? IO operations can read
information from or write information to the terminal, file system, operating system, and/or
network. They interact with systems outside of your program. If you want to get user input, print a
message to the user, read information from a file, or make a network call, you'll need to do so
within the IO Monad.
The state of the world outside your program can change at virtually any moment, and so this IO
context is particularly special. So these IO operations are "side effects" which means you cannot
perform them from "pure" Lean functions.
Now, the most important job of pretty much any computer program is precisely to perform this
interaction with the outside world. For this reason, the root of all executable Lean code is a
function called main, with the type `IO Unit`. So every program starts in the IO monad!
When your function is `IO` monadic, you can get any input you need, call into "pure" code with the
inputs, and then output the result in some way. The reverse does not work. You cannot call into IO
code from pure code like you can call into a function that takes `Option` as input. Another way to
say this is you cannot invent an `IO` context out of thin air, it has to be given to you in your
`main` function.
Let's look at a simple program showing a few of the basic IO functions. It also uses `do` notation
to make the code read nicely:
-/
def main : IO Unit := do
IO.println "enter a line of text:"
let stdin IO.getStdin -- IO IO.FS.Stream (monadic)
let input stdin.getLine -- IO.FS.Stream → IO String (monadic)
let uppercased := input.toUpper -- String → String (pure)
IO.println uppercased -- IO Unit (monadic)
/-!
So, once again you can see that the `do` notation lets you chain a series of monadic actions.
`IO.getStdin` is of type `IO IO.FS.Stream` and `stdin.getLine` is of type `IO String`
and `IO.println` is of type `IO Unit`.
In between you see a non-monadic expression `let uppercased := input.toUpper` which is fine too.
A let statement can occur in any monad. Just as you could unwrap `i` from `Option Nat` to get the
inner Nat, you can use `←` to unwrap the result of `getLine` to get a String. You can then manipulate
this value using normal pure string functions like `toUpper`, and then you can pass the result to the
`IO.println` function.
This is a simple echo program. It reads a line from the terminal, and then prints the line back out
capitalized to the terminal. Hopefully it gives you a basic understanding of how IO works.
You can test this program using `lean --run` as follows:
```
> lean --run Main.lean
enter a line of text:
the quick brown fox
THE QUICK BROWN FOX
```
Here the user entered the string `the quick brown fox` and got back the uppercase result.
## What separates Monads from Applicatives?
The key that separates these is **context**. You cannot really determine the structure of
"future" operations without knowing the results of "past" operations, because the past can alter the
context in which the future operations work. With applicatives, you can't get the final function
result without evaluating everything, but you can determine the structure of how the operation will
take place. This allows some degree of parallelism with applicatives that is not generally possible
with monads.
## Conclusion
Hopefully you now have a basic level understanding of what a monad is. But perhaps some more
examples of what a "computational context" means would be useful to you. The Reader, State and
Except monads each provide a concrete and easily understood context that can be compared easily to
function parameters. You can learn more about those in [Reader monads](readers.lean.md),
[State monads](states.lean.md), and the [Except monad](except.lean.md).
-/

View File

@@ -1,199 +0,0 @@
/-!
# Readers
In the [previous section](monads.lean.md) you learned about the conceptual idea of monads. You learned
what they are, and saw how some common types like `IO` and `Option` work as monads. Now in this
section, you will be looking at some other useful monads. In particular, the `ReaderM` monad.
## How to do Global Variables in Lean?
In Lean, your code is generally "pure", meaning functions can only interact with the arguments
passed to them. This effectively means you cannot have global variables. You can have global
definitions, but these are fixed at compile time. If some user behavior might change them, you would have
to wrap them in the `IO` monad, which means they can't be used from pure code.
Consider this example. Here, you want to have an `Environment` containing different parameters as a
global variable. However, you want to load these parameters from the process environment variables,
which requires the `IO` monad.
-/
structure Environment where
path : String
home : String
user : String
deriving Repr
def getEnvDefault (name : String): IO String := do
let val? IO.getEnv name
pure <| match val? with
| none => ""
| some s => s
def loadEnv : IO Environment := do
let path getEnvDefault "PATH"
let home getEnvDefault "HOME"
let user getEnvDefault "USER"
pure { path, home, user }
def func1 (e : Environment) : Float :=
let l1 := e.path.length
let l2 := e.home.length * 2
let l3 := e.user.length * 3
(l1 + l2 + l3).toFloat * 2.1
def func2 (env : Environment) : Nat :=
2 + (func1 env).floor.toUInt32.toNat
def func3 (env : Environment) : String :=
"Result: " ++ (toString (func2 env))
def main : IO Unit := do
let env loadEnv
let str := func3 env
IO.println str
#eval main -- Result: 7538
/-!
The only function actually using the environment is func1. However func1 is a pure function. This
means it cannot directly call loadEnv, an impure function in the IO monad. This means the
environment has to be passed through as a variable to the other functions, just so they can
ultimately pass it to func1. In a language with global variables, you could save env as a global
value in main. Then func1 could access it directly. There would be no need to have it as a parameter
to func1, func2 and func3. In larger programs, these "pass-through" variables can cause a lot of
headaches.
## The Reader Solution
The `ReaderM` monad solves this problem. It effectively creates a global read-only value of a
specified type. All functions within the monad can "read" the type. Let's look at how the `ReaderM`
monad changes the shape of this code. Now the functions **no longer need** to be given the
`Environment` as an explicit parameter, as they can access it through the monad.
-/
def readerFunc1 : ReaderM Environment Float := do
let env read
let l1 := env.path.length
let l2 := env.home.length * 2
let l3 := env.user.length * 3
return (l1 + l2 + l3).toFloat * 2.1
def readerFunc2 : ReaderM Environment Nat :=
readerFunc1 >>= (fun x => return 2 + (x.floor.toUInt32.toNat))
def readerFunc3 : ReaderM Environment String := do
let x readerFunc2
return "Result: " ++ toString x
def main2 : IO Unit := do
let env loadEnv
let str := readerFunc3.run env
IO.println str
#eval main2 -- Result: 7538
/-!
The `ReaderM` monad provides a `run` method and it is the `ReaderM` run method that takes the initial
`Environment` context. So here you see `main2` loads the environment as before, and establishes
the `ReaderM` context by passing `env` to the `run` method.
> **Side note 1**: The `return` statement used above also needs some explanation. The `return`
statement in Lean is closely related to `pure`, but a little different. First the similarity is that
`return` and `pure` both lift a pure value up to the Monad type. But `return` is a keyword so you do
not need to parenthesize the expression like you do when using `pure`. (Note: you can avoid
parentheses when using `pure` by using the `<|` operator like we did above in the initial
`getEnvDefault` function). Furthermore, `return` can also cause an early `return` in a monadic
function similar to how it can in an imperative language while `pure` cannot.
> So technically if `return` is the last statement in a function it could be replaced with `pure <|`,
but one could argue that `return` is still a little easier for most folks to read, just so long as
you understand that `return` is doing more than other languages, it is also wrapping pure values in
the monadic container type.
> **Side note 2**: If the function `readerFunc3` also took some explicit arguments then you would have
to write `(readerFunc3 args).run env` and this is a bit ugly, so Lean provides an infix operator
`|>` that eliminates those parentheses so you can write `readerFunc3 args |>.run env` and then you can
chain multiple monadic actions like this `m1 args1 |>.run args2 |>.run args3` and this is the
recommended style. You will see this pattern used heavily in Lean code.
The `let env ← read` expression in `readerFunc1` unwraps the environment from the `ReaderM` so we
can use it. Each type of monad might provide one or more extra functions like this, functions that
become available only when you are in the context of that monad.
Here the `readerFunc2` function uses the `bind` operator `>>=` just to show you that there are bind
operations happening here. The `readerFunc3` function uses the `do` notation you learned about in
[Monads](monads.lean.md) which hides that bind operation and can make the code look cleaner.
So the expression `let x ← readerFunc2` is also calling the `bind` function under the covers,
so that you can access the unwrapped value `x` needed for the `toString x` conversion.
The important difference here to the earlier code is that `readerFunc3` and `readerFunc2` no longer
have an **explicit** Environment input parameter that needs to be passed along all the way to
`readerFunc1`. Instead, the `ReaderM` monad is taking care of that for you, which gives you the
illusion of something like global context where the context is now available to all functions that use
the `ReaderM` monad.
The above code also introduces an important idea. Whenever you learn about a monad "X", there's
often (but not always) a `run` function to execute that monad, and sometimes some additional
functions like `read` that interact with the monad context.
You might be wondering, how does the context actually move through the `ReaderM` monad? How can you
add an input argument to a function by modifying its return type? There is a special command in
Lean that will show you the reduced types:
-/
#reduce ReaderM Environment String -- Environment → String
/-!
And you can see here that this type is actually a function! It's a function that takes an
`Environment` as input and returns a `String`.
Now, remember in Lean that a function that takes an argument of type `Nat` and returns a `String`
like `def f (a : Nat) : String` is the same as this function `def f : Nat → String`. These are
exactly equal as types. Well this is being used by the `ReaderM` Monad to add an input argument to
all the functions that use the `ReaderM` monad and this is why `main` is able to start things off by
simply passing that new input argument in `readerFunc3.run env`. So now that you know the implementation
details of the `ReaderM` monad you can see that what it is doing looks very much like the original
code we wrote at the beginning of this section, only it's taking a lot of the tedious work off your
plate and it is creating a nice clean separation between what your pure functions are doing, and the
global context idea that the `ReaderM` adds.
## withReader
One `ReaderM` function can call another with a modified version of the `ReaderM` context. You can
use the `withReader` function from the `MonadWithReader` type class to do this:
-/
def readerFunc3WithReader : ReaderM Environment String := do
let x withReader (λ env => { env with user := "new user" }) readerFunc2
return "Result: " ++ toString x
/-!
Here we changed the `user` in the `Environment` context to "new user" and then we passed that
modified context to `readerFunc2`.
So `withReader f m` executes monad `m` in the `ReaderM` context modified by `f`.
## Handy shortcut with (← e)
If you use the operator `←` in a let expression and the variable is only used once you can
eliminate the let expression and place the `←` operator in parentheses like this
call to loadEnv:
-/
def main3 : IO Unit := do
let str := readerFunc3 ( loadEnv)
IO.println str
/-!
## Conclusion
It might not seem like much has been accomplished with this `ReaderM Environment` monad, but you will
find that in larger code bases, with many different types of monads all composed together this
greatly cleans up the code. Monads provide a beautiful functional way of managing cross-cutting
concerns that would otherwise make your code very messy.
Having this control over the inherited `ReaderM` context via `withReader` is actually very useful
and something that is quite messy if you try and do this sort of thing with global variables, saving
the old value, setting the new one, calling the function, then restoring the old value, making sure
you do that in a try/finally block and so on. The `ReaderM` design pattern avoids that mess
entirely.
Now it's time to move on to [StateM Monad](states.lean.md) which is like a `ReaderM` that is
also updatable.
-/

View File

@@ -1,265 +0,0 @@
import Lean.Data.HashMap
/-!
# State
In the [previous section](readers.lean.md), you learned about the `ReaderM` monad. Hopefully this gave you
a new perspective on Lean. It showed that, in fact, you _can_ have global variables of some sort;
you just need to encode them in the type signature somehow, and this is what monads are for! In this
part, you will explore the `StateM` monad, which is like a `ReaderM` only the state can also be updated.
## Motivating example: Tic Tac Toe
For this section, let's build a simple model for a Tic Tace Toe game. The main object is the `GameState`
data type containing several important pieces of information. First and foremost, it has the
"board", a map from 2D tile indices to the "Tile State" (X, O or empty). Then it also knows the
current player, and it has a random generator.
-/
open Batteries (HashMap)
abbrev TileIndex := Nat × Nat -- a 2D index
inductive TileState where
| TileEmpty | TileX | TileO
deriving Repr, BEq
inductive Player where
| XPlayer | OPlayer
deriving Repr, BEq
abbrev Board := HashMap TileIndex TileState
structure GameState where
board : Board
currentPlayer : Player
generator : StdGen
/-!
Let's think at a high level about how some of the game functions would work. You could, for
instance, have a function for selecting a random move. This would output a `TileIndex` to play and
alter the game's number generator. You would then make a move based on the selected move and the
current player. This would change the board state as well as swap the current player. In other
words, you have operations that depend on the current state of the game, but also need to **update
that state**.
## The StateM Monad to the Rescue
This is exactly the situation the `StateM` monad deals with. The `StateM` monad wraps computations in
the context of reading and modifying a global state object.
It is parameterized by a single type parameter `s`, the state type in use. So just like the `ReaderM`
has a single type you read from, the `StateM` has a single type you can both **read from and write
to**. There are three primary actions you can take within the `StateM`monad:
- **get** - retrieves the state, like Reader.read
- **set** - updates the state
- **modifyGet** - retrieves the state, then updates it
There is also a `run` function, similar to `run` on `ReaderM`. Like the `ReaderM` monad, you must
provide an initial state, in addition to the computation to run. `StateM` then produces two outputs:
the result of the computation combined with the final updated state.
If you wish to discard the final state and just get the computation's result, you can use
`run'` method instead. Yes in Lean, the apostrophe can be part of a name, you read this "run
prime", and the general naming convention is that the prime method discards something.
So for your Tic Tac Toe game, many of your functions will have a signature like `State GameState a`.
## Stateful Functions
Now you can examine some of the different functions mentioned above and determine their types.
You can, for instance, pick a random move:
-/
open TileState
def findOpen : StateM GameState (List TileIndex) := do
let game get
return game.board.toList.filterMap fun (i, x) => guard (x == TileEmpty) *> pure i
def chooseRandomMove : StateM GameState TileIndex := do
let game get
let openSpots findOpen
let gen := game.generator
let (i, gen') := randNat gen 0 (openSpots.length - 1)
set { game with generator := gen' }
return openSpots[i]!
/-!
This returns a `TileIndex` and modifies the random number generator stored in the `GameState`!
Notice you have a fun little use of the `Applicative.seqRight` operator `*>` in `findOpen`
as described in [Applicatives](applicatives.lean.md).
Now you can create the function that can make a move:
-/
open Player
def tileStateForPlayer : Player TileState
| XPlayer => TileX
| OPlayer => TileO
def nextPlayer : Player Player
| XPlayer => OPlayer
| OPlayer => XPlayer
def applyMove (i : TileIndex): StateM GameState Unit := do
let game get
let p := game.currentPlayer
let newBoard := game.board.insert i (tileStateForPlayer p)
set { game with currentPlayer := nextPlayer p, board := newBoard }
/-!
This updates the board in the `GameState` with the new tile, and then changes the current player,
providing no output (`Unit` return type).
So finally, you can combine these functions together with `do` notation, and it actually looks quite
clean! You don't need to worry about the side effects. The different monadic functions handle them.
Here's a sample of what your function might look like to play one turn of the game. At the end, it
returns a boolean determining if all the spaces have been filled.
Notice in `isGameDone` and `nextTurn` we have stopped providing the full return type
`StateM GameState Unit`. This is because Lean is able to infer the correct monadic return type
from the context and as a result the code is now looking really clean.
-/
def isGameDone := do
return ( findOpen).isEmpty
def nextTurn := do
let i chooseRandomMove
applyMove i
isGameDone
/-!
To give you a quick test harness that runs all moves for both players you can run this:
-/
def initBoard : Board := Id.run do
let mut board := HashMap.empty
for i in [0:3] do
for j in [0:3] do
let t : TileIndex := (i, j)
board := board.insert t TileEmpty
board
def printBoard (board : Board) : IO Unit := do
let mut row : List String := []
for i in board.toList do
let s := match i.2 with
| TileEmpty => " "
| TileX => "X"
| TileO => "O"
row := row.append [s]
if row.length == 3 then
IO.println row
row := []
def playGame := do
while true do
let finished nextTurn
if finished then return
def main : IO Unit := do
let gen IO.stdGenRef.get
let (x, gen') := randNat gen 0 1
let gs := {
board := initBoard,
currentPlayer := if x = 0 then XPlayer else OPlayer,
generator := gen' }
let (_, g) := playGame |>.run gs
printBoard g.board
#eval main
-- [X, X, O]
-- [X, O, O]
-- [O, O, X]
/-!
Note that when you run the above code interactively the random number generator always starts in the
same place. But if you run `lean --run states.lean` then you will see randomness in the result.
## Implementation
It may be helpful to see how the `StateM` monad adds the input state and output state. If you look
at the reduced Type for `nextTurn`:
-/
#reduce StateM GameState Bool
-- GameState → Bool × GameState
/-!
So a function like `nextTurn` that might have just returned a `Bool` has been modified by the
`StateM` monad such that the initial `GameState` is passed in as a new input argument, and the output
value has been changed to the pair `Bool × GameState` so that it can return the pure `Bool` and the
updated `GameState`. So `playGame` then is automatically saving that updated game state so that each
time around the `while` loop it is acting on the new state, otherwise that would be an infinite loop!
It is also interesting to see how much work the `do` and `←` notation are doing for you. To
implement the `nextTurn` function without these you would have to write this, manually plumbing
the state all the way through:
-/
def nextTurnManually : StateM GameState Bool
| state =>
let (i, gs) := chooseRandomMove |>.run state
let (_, gs') := applyMove i |>.run gs
let (result, gs'') := isGameDone |>.run gs'
(result, gs'')
/-!
This expression `let (i, gs)` conveniently breaks a returned pair up into 2 variables.
In the expression `let (_, gs')` we didn't care what the first value was so we used underscore.
Notice that nextTurn is capturing the updated game state from `chooseRandomMove` in the variable
`gs`, which it is then passing to `applyMove` which returns `gs'` which is passed to `isGameDone`
and that function returns `gs''` which we then return from `nextTurnManually`. Phew, what a lot
of work you don't have to do when you use `do` notation!
## StateM vs ReaderM
While `ReaderM` functions can use `withReader` to modify the context before calling another function,
`StateM` functions are a little more powerful, let's look at this function again:
```
def nextTurn : StateM GameState Bool := do
let i ← chooseRandomMove
applyMove i
isGameDone
```
In this function `chooseRandomMove` is modifying the state that `applyMove` is getting
and `chooseRandomMove` knows nothing about `applyMove`. So `StateM` functions can have this
kind of downstream effect outside their own scope, whereas, `withReader` cannot do that.
So there is no equivalent to `withReader` for `StateM`, besides you can always use the `StateM`
`set` function to modify the state before calling the next function anyway. You could however,
manually call a `StateM` function like you see in `nextTurnManually` and completely override
the state at any point that way.
## State, IO and other languages
When thinking about Lean, it is often seen as a restriction that you can't have global variables or
`static` variables like you can with other languages like Python or C++. However, hopefully you see
now this isn't true. You can have a data type with exactly the same functionality as a Python class.
You would simply have many functions that can modify some global state using the `StateM` monad.
The difference is in Lean you simply put a label on these types of functions. You don't allow it to
happen for free anywhere in an uncontrolled fashion because that results in too many sleepless
nights debugging nasty code. You want to know when side effects can potentially happen, because
knowing when they can happen makes your code easier to reason about. In a Python class, many of the
methods won't actually need to modify the global state. But they could, which makes it harder to
debug them. In Lean you can simply make these pure functions, and the compiler will ensure they stay
pure and cannot modify any global state.
IO is the same way. It's not like you can't perform IO in Lean. Instead, you want to label the areas
where you can, to increase your certainty about the areas where you don't need to. When you know part of
your code cannot communicate with the outside world, you can be far more certain of its behavior.
The `StateM` monad is also a more disciplined way of managing side effects. Top level code could
call a `StateM` function multiple times with different independent initial states, even doing that
across multiple tasks in parallel and each of these cannot clobber the state belonging to other
tasks. Monadic code is more predictable and reusable than code that uses global variables.
## Summary
That wraps it up for the `StateM` monad! There is one more very useful monad that can be used to do
exception handling which will be covered in the [next section](except.lean.md).
-/

View File

@@ -1,316 +0,0 @@
/-!
# Monad Transformers
In the previous sections you learned about some handy monads [Option](monads.lean.md),
[IO](monads.lean.md), [Reader](readers.lean.md), [State](states.lean.md) and
[Except](except.lean.md), and you now know how to make your function use one of these, but what you
do not yet know is how to make your function use multiple monads at once.
For example, suppose you need a function that wants to access some Reader context and optionally throw
an exception? This would require composition of two monads `ReaderM` and `Except` and this is what
monad transformers are for.
A monad transformer is fundamentally a wrapper type. It is generally parameterized by another
monadic type. You can then run actions from the inner monad, while adding your own customized
behavior for combining actions in this new monad. The common transformers add `T` to the end of an
existing monad name. You will find `OptionT`, `ExceptT`, `ReaderT`, `StateT` but there is no transformer
for `IO`. So generally if you need `IO` it becomes the innermost wrapped monad.
In the following example we use `ReaderT` to provide some read only context to a function
and this `ReaderT` transformer will wrap an `Except` monad. If all goes well the
`requiredArgument` returns the value of a required argument and `optionalSwitch`
returns true if the optional argument is present.
-/
abbrev Arguments := List String
def indexOf? [BEq α] (xs : List α) (s : α) (start := 0): Option Nat :=
match xs with
| [] => none
| a :: tail => if a == s then some start else indexOf? tail s (start+1)
def requiredArgument (name : String) : ReaderT Arguments (Except String) String := do
let args read
let value := match indexOf? args name with
| some i => if i + 1 < args.length then args[i+1]! else ""
| none => ""
if value == "" then throw s!"Command line argument {name} missing"
return value
def optionalSwitch (name : String) : ReaderT Arguments (Except String) Bool := do
let args read
return match (indexOf? args name) with
| some _ => true
| none => false
#eval requiredArgument "--input" |>.run ["--input", "foo"]
-- Except.ok "foo"
#eval requiredArgument "--input" |>.run ["foo", "bar"]
-- Except.error "Command line argument --input missing"
#eval optionalSwitch "--help" |>.run ["--help"]
-- Except.ok true
#eval optionalSwitch "--help" |>.run []
-- Except.ok false
/-!
Notice that `throw` was available from the inner `Except` monad. The cool thing is you can switch
this around and get the exact same result using `ExceptT` as the outer monad transformer and
`ReaderM` as the wrapped monad. Try changing requiredArgument to `ExceptT String (ReaderM Arguments) Bool`.
Note: the `|>.` notation is described in [Readers](readers.lean.md#the-reader-solution).
## Adding more layers
Here's the best part about monad transformers. Since the result of a monad transformer is itself a
monad, you can wrap it inside another transformer! Suppose you need to pass in some read only context
like the command line arguments, update some read-write state (like program Config) and optionally
throw an exception, then you could write this:
-/
structure Config where
help : Bool := false
verbose : Bool := false
input : String := ""
deriving Repr
abbrev CliConfigM := StateT Config (ReaderT Arguments (Except String))
def parseArguments : CliConfigM Bool := do
let mut config get
if ( optionalSwitch "--help") then
throw "Usage: example [--help] [--verbose] [--input <input file>]"
config := { config with
verbose := ( optionalSwitch "--verbose"),
input := ( requiredArgument "--input") }
set config
return true
def main (args : List String) : IO Unit := do
let config : Config := { input := "default"}
match parseArguments |>.run config |>.run args with
| Except.ok (_, c) => do
IO.println s!"Processing input '{c.input}' with verbose={c.verbose}"
| Except.error s => IO.println s
#eval main ["--help"]
-- Usage: example [--help] [--verbose] [--input <input file>]
#eval main ["--input", "foo"]
-- Processing input file 'foo' with verbose=false
#eval main ["--verbose", "--input", "bar"]
-- Processing input 'bar' with verbose=true
/-!
In this example `parseArguments` is actually three stacked monads, `StateM`, `ReaderM`, `Except`. Notice
the convention of abbreviating long monadic types with an alias like `CliConfigM`.
## Monad Lifting
Lean makes it easy to compose functions that use different monads using a concept of automatic monad
lifting. You already used lifting in the above code, because you were able to compose
`optionalSwitch` which has type `ReaderT Arguments (Except String) Bool` and call it from
`parseArguments` which has a bigger type `StateT Config (ReaderT Arguments (Except String))`.
This "just worked" because Lean did some magic with monad lifting.
To give you a simpler example of this, suppose you have the following function:
-/
def divide (x : Float ) (y : Float): ExceptT String Id Float :=
if y == 0 then
throw "can't divide by zero"
else
pure (x / y)
#eval divide 6 3 -- Except.ok 2.000000
#eval divide 1 0 -- Except.error "can't divide by zero"
/-!
Notice here we used the `ExceptT` transformer, but we composed it with the `Id` identity monad.
This is then the same as writing `Except String Float` since the identity monad does nothing.
Now suppose you want to count the number of times divide is called and store the result in some
global state:
-/
def divideCounter (x : Float) (y : Float) : StateT Nat (ExceptT String Id) Float := do
modify fun s => s + 1
divide x y
#eval divideCounter 6 3 |>.run 0 -- Except.ok (2.000000, 1)
#eval divideCounter 1 0 |>.run 0 -- Except.error "can't divide by zero"
/-!
The `modify` function is a helper which makes it easier to use `modifyGet` from the `StateM` monad.
But something interesting is happening here, `divideCounter` is returning the value of
`divide`, but the types don't match, yet it works? This is monad lifting in action.
You can see this more clearly with the following test:
-/
def liftTest (x : Except String Float) :
StateT Nat (Except String) Float := x
#eval liftTest (divide 5 1) |>.run 3 -- Except.ok (5.000000, 3)
/-!
Notice that `liftTest` returned `x` without doing anything to it, yet that matched the return type
`StateT Nat (Except String) Float`. Monad lifting is provided by monad transformers. if you
`#print liftTest` you will see that Lean is implementing this using a call to a function named
`monadLift` from the `MonadLift` type class:
```lean,ignore
class MonadLift (m : Type u → Type v) (n : Type u → Type w) where
monadLift : {α : Type u} → m α → n α
```
So `monadLift` is a function for lifting a computation from an inner `Monad m α ` to an outer `Monad n α`.
You could replace `x` in `liftTest` with `monadLift x` if you want to be explicit about it.
The StateT monad transformer defines an instance of `MonadLift` like this:
```lean
@[inline] protected def lift {α : Type u} (t : m α) : StateT σ m α :=
fun s => do let a ← t; pure (a, s)
instance : MonadLift m (StateT σ m) := ⟨StateT.lift⟩
```
This means that any monad `m` can be wrapped in a `StateT` monad by using the function
`fun s => do let a ← t; pure (a, s)` that takes state `s`, runs the inner monad action `t`, and
returns the result and the new state in a pair `(a, s)` without making any changes to `s`.
Because `MonadLift` is a type class, Lean can automatically find the required `monadLift`
instances in order to make your code compile and in this way it was able to find the `StateT.lift`
function and use it to wrap the result of `divide` so that the correct type is returned from
`divideCounter`.
If you have an instance `MonadLift m n` that means there is a way to turn a computation that happens
inside of `m` into one that happens inside of `n` and (this is the key part) usually *without* the
instance itself creating any additional data that feeds into the computation. This means you can in
principle declare lifting instances from any monad to any other monad, it does not, however, mean
that you should do this in all cases. You can get a very nice report on how all this was done by
adding the line `set_option trace.Meta.synthInstance true in` before `divideCounter` and moving you
cursor to the end of the first line after `do`.
This was a lot of detail, but it is very important to understand how monad lifting works because it
is used heavily in Lean programs.
## Transitive lifting
There is also a transitive version of `MonadLift` called `MonadLiftT` which can lift multiple
monad layers at once. In the following example we added another monad layer with
`ReaderT String ...` and notice that `x` is also automatically lifted to match.
-/
def liftTest2 (x : Except String Float) :
ReaderT String (StateT Nat (Except String)) Float := x
#eval liftTest2 (divide 5 1) |>.run "" |>.run 3
-- Except.ok (5.000000, 3)
/-!
The ReaderT monadLift is even simpler than the one for StateT:
```lean,ignore
instance : MonadLift m (ReaderT ρ m) where
monadLift x := fun _ => x
```
This lift operation creates a function that defines the required `ReaderT` input
argument, but the inner monad doesn't know or care about `ReaderT` so the
monadLift function throws it away with the `_` then calls the inner monad action `x`.
This is a perfectly legal implementation of the `ReaderM` monad.
## Add your own Custom MonadLift
This does not compile:
-/
def main2 : IO Unit := do
try
let ret divideCounter 5 2 |>.run 0
IO.println (toString ret)
catch e =>
IO.println e
/-!
saying:
```
typeclass instance problem is stuck, it is often due to metavariables
ToString ?m.4786
```
The reason is `divideCounter` returns the big `StateT Nat (ExceptT String Id) Float` and that type
cannot be automatically lifted into the `main` return type of `IO Unit` unless you give it some
help.
The following custom `MonadLift` solves this problem:
-/
def liftIO (t : ExceptT String Id α) : IO α := do
match t with
| .ok r => EStateM.Result.ok r
| .error s => EStateM.Result.error s
instance : MonadLift (ExceptT String Id) IO where
monadLift := liftIO
def main3 : IO Unit := do
try
let ret divideCounter 5 2 |>.run 0
IO.println (toString ret)
catch e =>
IO.println e
#eval main3 -- (2.500000, 1)
/-!
It turns out that the `IO` monad you see in your `main` function is based on the `EStateM.Result` type
which is similar to the `Except` type but it has an additional return value. The `liftIO` function
converts any `Except String α` into `IO α` by simply mapping the ok case of the `Except` to the
`Result.ok` and the error case to the `Result.error`.
## Lifting ExceptT
In the previous [Except](except.lean.md) section you saw functions that `throw` Except
values. When you get all the way back up to your `main` function which has type `IO Unit` you have
the same problem you had above, because `Except String Float` doesn't match even if you use a
`try/catch`.
-/
def main4 : IO Unit := do
try
let ret divide 5 0
IO.println (toString ret) -- lifting happens here.
catch e =>
IO.println s!"Unhandled exception: {e}"
#eval main4 -- Unhandled exception: can't divide by zero
/-!
Without the `liftIO` the `(toString ret)` expression would not compile with a similar error:
```
typeclass instance problem is stuck, it is often due to metavariables
ToString ?m.6007
```
So the general lesson is that if you see an error like this when using monads, check for
a missing `MonadLift`.
## Summary
Now that you know how to combine your monads together, you're almost done with understanding the key
concepts of monads! You could probably go out now and start writing some pretty nice code! But to
truly master monads, you should know how to make your own, and there's one final concept that you
should understand for that. This is the idea of type "laws". Each of the structures you've learned
so far has a series of laws associated with it. And for your instances of these classes to make
sense, they should follow the laws! Check out [Monad Laws](laws.lean.md).
-/

View File

@@ -1,108 +0,0 @@
# Namespaces
Lean provides us with the ability to group definitions into nested, hierarchical *namespaces*:
```lean
namespace Foo
def a : Nat := 5
def f (x : Nat) : Nat := x + 7
def fa : Nat := f a
def ffa : Nat := f (f a)
#check a
#check f
#check fa
#check ffa
#check Foo.fa
end Foo
-- #check a -- error
-- #check f -- error
#check Foo.a
#check Foo.f
#check Foo.fa
#check Foo.ffa
open Foo
#check a
#check f
#check fa
#check Foo.fa
```
When we declare that we are working in the namespace ``Foo``, every identifier we declare has
a full name with prefix "``Foo.``" Within the namespace, we can refer to identifiers
by their shorter names, but once we end the namespace, we have to use the longer names.
The ``open`` command brings the shorter names into the current context. Often, when we import a
module, we will want to open one or more of the namespaces it contains, to have access to the short identifiers.
But sometimes we will want to leave this information hidden, for example, when they conflict with
identifiers in another namespace we want to use. Thus namespaces give us a way to manage our working environment.
For example, Lean groups definitions and theorems involving lists into a namespace ``List``.
```lean
#check List.nil
#check List.cons
#check List.map
```
We will discuss their types, below. The command ``open List`` allows us to use the shorter names:
```lean
open List
#check nil
#check cons
#check map
```
Like sections, namespaces can be nested:
```lean
namespace Foo
def a : Nat := 5
def f (x : Nat) : Nat := x + 7
def fa : Nat := f a
namespace Bar
def ffa : Nat := f (f a)
#check fa
#check ffa
end Bar
#check fa
#check Bar.ffa
end Foo
#check Foo.fa
#check Foo.Bar.ffa
open Foo
#check fa
#check Bar.ffa
```
Namespaces that have been closed can later be reopened, even in another file:
```lean
namespace Foo
def a : Nat := 5
def f (x : Nat) : Nat := x + 7
def fa : Nat := f a
end Foo
#check Foo.a
#check Foo.f
namespace Foo
def ffa : Nat := f (f a)
end Foo
```
Like sections, nested namespaces have to be closed in the order they are opened.
Namespaces and sections serve different purposes: namespaces organize data and sections declare variables for insertion in definitions.
Sections are also useful for delimiting the scope of commands such as ``set_option`` and ``open``.
In many respects, however, a ``namespace ... end`` block behaves the same as a ``section ... end`` block.
In particular, if you use the ``variable`` command within a namespace, its scope is limited to the namespace.
Similarly, if you use an ``open`` command within a namespace, its effects disappear when the namespace is closed.

View File

@@ -1,68 +0,0 @@
# Natural numbers
The `Nat` type represents the natural numbers, i.e., arbitrary-precision unsigned integers.
There are no overflows.
```lean
#eval 100000000000000000 * 200000000000000000000 * 1000000000000000000000
```
A numeral is considered to be a `Nat` if there are no typing constraints.
```lean
#check 10 -- Nat
#check id 10 -- Nat
def f (x : Int) : Int :=
x - 1
#eval f (3 - 5) -- 3 and 5 are `Int` since `f` expects an `Int`.
-- -3
```
The operator `-` for `Nat` implements truncated subtraction.
```lean
#eval 10 - 5 -- 5
#eval 5 - 10 -- 0
theorem ex : 5 - 10 = 0 :=
rfl
#eval (5:Int) - 10 -- -5
```
The operator `/` for `Nat` implements Euclidean division.
```lean
#eval 10 / 4 -- 2
#check 10.0 / 4.0 -- Float
#eval 10.0 / 4.0 -- 2.5
```
As we described in the previous sections, we define the `Nat` type as an `inductive` datatype.
```lean
# namespace hidden
inductive Nat where
| zero : Nat
| succ : Nat Nat
# end hidden
```
However, the internal representation of `Nat` is optimized. Small natural numbers (i.e., < `2^63` in a 64-bit machine) are
represented by a single machine word. Big numbers are implemented using [GMP](https://gmplib.org/manual/) numbers.
We recommend you use fixed precision numeric types only in performance critical code.
The Lean kernel has builtin support for the `Nat` type too, and can efficiently reduce `Nat` expressions during type checking.
```lean
#reduce 100000000000000000 * 200000000000000000000 * 1000000000000000000000
theorem ex
: 1000000000000000 * 2000000000000000000 = 2000000000000000000000000000000000 :=
rfl
```
The sharp-eyed reader will notice that GMP is part of the Lean kernel trusted code base.
We believe this is not a problem because you can use external type checkers to double-check your developments,
and we consider GMP very trustworthy.
Existing external type checkers for Lean 3 (e.g., [Trepplein](https://github.com/gebner/trepplein) and [TC](https://github.com/leanprover/tc))
can be easily adapted to Lean 4.
If you are still concerned after checking your development with multiple different external checkers because
they may all rely on buggy arbitrary-precision libraries,
you can develop your own certified arbitrary-precision library and use it to implement your own type checker for Lean.

View File

@@ -1,78 +0,0 @@
# Notations and Precedence
The most basic syntax extension commands allow introducing new (or
overloading existing) prefix, infix, and postfix operators.
```lean
infixl:65 " + " => HAdd.hAdd -- left-associative
infix:50 " = " => Eq -- non-associative
infixr:80 " ^ " => HPow.hPow -- right-associative
prefix:75 "-" => Neg.neg
# set_option quotPrecheck false
postfix:max "⁻¹" => Inv.inv
```
After the initial command name describing the operator kind (its
"fixity"), we give the *parsing precedence* of the operator preceded
by a colon `:`, then a new or existing token surrounded by double
quotes (the whitespace is used for pretty printing), then the function
this operator should be translated to after the arrow `=>`.
The precedence is a natural number describing how "tightly" an
operator binds to its arguments, encoding the order of operations. We
can make this more precise by looking at what the commands above unfold to:
```lean
notation:65 lhs:65 " + " rhs:66 => HAdd.hAdd lhs rhs
notation:50 lhs:51 " = " rhs:51 => Eq lhs rhs
notation:80 lhs:81 " ^ " rhs:80 => HPow.hPow lhs rhs
notation:75 "-" arg:75 => Neg.neg arg
# set_option quotPrecheck false
notation:1024 arg:1024 "⁻¹" => Inv.inv arg -- `max` is a shorthand for precedence 1024
```
It turns out that all commands from the first code block are in fact
command *macros* translating to the more general `notation` command.
We will learn about writing such macros below. Instead of a single
token, the `notation` command accepts a mixed sequence of tokens and
named term placeholders with precedences, which can be referenced on
the right-hand side of `=>` and will be replaced by the respective
term parsed at that position. A placeholder with precedence `p`
accepts only notations with precedence at least `p` in that place.
Thus the string `a + b + c` cannot be parsed as the equivalent of `a +
(b + c)` because the right-hand side operand of an `infixl` notation
has precedence one greater than the notation itself. In contrast,
`infixr` reuses the notation's precedence for the right-hand side
operand, so `a ^ b ^ c` *can* be parsed as `a ^ (b ^ c)`. Note that if
we used `notation` directly to introduce an infix notation like
```lean
# set_option quotPrecheck false
notation:65 lhs:65 " ~ " rhs:65 => wobble lhs rhs
```
where the precedences do not sufficiently determine associativity,
Lean's parser will default to right associativity. More precisely,
Lean's parser follows a local *longest parse* rule in the presence of
ambiguous grammars: when parsing the right-hand side of `a ~` in `a ~
b ~ c`, it will continue parsing as long as possible (as the current
precedence allows), not stopping after `b` but parsing `~ c` as well.
Thus the term is equivalent to `a ~ (b ~ c)`.
As mentioned above, the `notation` command allows us to define
arbitrary *mixfix* syntax freely mixing tokens and placeholders.
```lean
# set_option quotPrecheck false
notation:max "(" e ")" => e
notation:10 Γ "" e " : " τ => Typing Γ e τ
```
Placeholders without precedence default to `0`, i.e. they accept
notations of any precedence in their place. If two notations overlap,
we again apply the longest parse rule:
```lean
notation:65 a " + " b:66 " + " c:66 => a + b - c
#eval 1 + 2 + 3 -- 0
```
The new notation is preferred to the binary notation since the latter,
before chaining, would stop parsing after `1 + 2`. If there are
multiple notations accepting the same longest parse, the choice will
be delayed until elaboration, which will fail unless exactly one
overload is type correct.

View File

@@ -1 +0,0 @@
# Option

View File

@@ -1,4 +0,0 @@
# Organizational features
In this section we introduce some organizational features of Lean that are not a part of its kernel per se,
but make it possible to work in the framework more efficiently.

3
doc/reference.md Normal file
View File

@@ -0,0 +1,3 @@
# The Lean Reference Manual
The latest version of the Lean reference manual is available [here](https://lean-lang.org/doc/reference/latest).

View File

@@ -1,70 +0,0 @@
# Variables and Sections
Consider the following three function definitions:
```lean
def compose (α β γ : Type) (g : β γ) (f : α β) (x : α) : γ :=
g (f x)
def doTwice (α : Type) (h : α α) (x : α) : α :=
h (h x)
def doThrice (α : Type) (h : α α) (x : α) : α :=
h (h (h x))
```
Lean provides us with the ``variable`` command to make such declarations look more compact:
```lean
variable (α β γ : Type)
def compose (g : β → γ) (f : α → β) (x : α) : γ :=
g (f x)
def doTwice (h : αα) (x : α) : α :=
h (h x)
def doThrice (h : αα) (x : α) : α :=
h (h (h x))
```
We can declare variables of any type, not just ``Type`` itself:
```lean
variable (α β γ : Type)
variable (g : β → γ) (f : α → β) (h : αα)
variable (x : α)
def compose := g (f x)
def doTwice := h (h x)
def doThrice := h (h (h x))
#print compose
#print doTwice
#print doThrice
```
Printing them out shows that all three groups of definitions have exactly the same effect.
The ``variable`` command instructs Lean to insert the declared variables as bound variables in definitions that refer to them.
Lean is smart enough to figure out which variables are used explicitly or implicitly in a definition. We can therefore proceed as
though ``α``, ``β``, ``γ``, ``g``, ``f``, ``h``, and ``x`` are fixed objects when we write our definitions, and let Lean abstract
the definitions for us automatically.
When declared in this way, a variable stays in scope until the end of the file we are working on.
Sometimes, however, it is useful to limit the scope of a variable. For that purpose, Lean provides the notion of a ``section``:
```lean
section useful
variable (α β γ : Type)
variable (g : β → γ) (f : α → β) (h : αα)
variable (x : α)
def compose := g (f x)
def doTwice := h (h x)
def doThrice := h (h (h x))
end useful
```
When the section is closed, the variables go out of scope, and become nothing more than a distant memory.
You do not have to indent the lines within a section. Nor do you have to name a section, which is to say,
you can use an anonymous ``section`` / ``end`` pair.
If you do name a section, however, you have to close it using the same name.
Sections can also be nested, which allows you to declare new variables incrementally.

View File

@@ -4,10 +4,10 @@
Platforms built & tested by our CI, available as binary releases via elan (see below)
* x86-64 Linux with glibc 2.27+
* x86-64 Linux with glibc 2.26+
* x86-64 macOS 10.15+
* aarch64 (Apple Silicon) macOS 10.15+
* x86-64 Windows 10+
* x86-64 Windows 11 (any version), Windows 10 (version 1903 or higher), Windows Server 2022
### Tier 2

9
doc/std/README.md Normal file
View File

@@ -0,0 +1,9 @@
# The Lean standard library
This directory contains development information about the Lean standard library. The user-facing documentation of the standard library
is part of the [Lean Language Reference](https://lean-lang.org/doc/reference/latest/).
Here you will find
* the [standard library vision document](./vision.md), including the call for contributions,
* the [standard library style guide](./style.md), and
* the [standard library naming conventions](./naming.md).

3
doc/std/naming-tree.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 68 KiB

260
doc/std/naming.md Normal file
View File

@@ -0,0 +1,260 @@
# Standard library naming conventions
The easiest way to access a result in the standard library is to correctly guess the name of the declaration (possibly with the help of identifier autocompletion). This is faster and has lower friction than more sophisticated search tools, so easily guessable names (which are still reasonably short) make Lean users more productive.
The guide that follows contains very few hard rules, many heuristics and a selection of examples. It cannot and does not present a deterministic algorithm for choosing good names in all situations. It is intended as a living document that gets clarified and expanded as situations arise during code reviews for the standard library. If applying one of the suggestions in this guide leads to nonsensical results in a certain situation, it is
probably safe to ignore the suggestion (or even better, suggest a way to improve the suggestion).
## Prelude
Identifiers use a mix of `UpperCamelCase`, `lowerCamelCase` and `snake_case`, used for types, data, and theorems, respectively.
Structure fields should be named such that the projections have the correct names.
## Naming convention for types
When defining a type, i.e., a (possibly 0-ary) function whose codomain is Sort u for some u, it should be named in UpperCamelCase. Examples include `List`, and `List.IsPrefix`.
When defining a predicate, prefix the name by `Is`, like in `List.IsPrefix`. The `Is` prefix may be omitted if
* the resulting name would be ungrammatical, or
* the predicate depends on additional data in a way where the `Is` prefix would be confusing (like `List.Pairwise`), or
* the name is an adjective (like `Std.Time.Month.Ordinal.Valid`)
## Namespaces and generalized projection notation
Almost always, definitions and theorems relating to a type should be placed in a namespace with the same name as the type. For example, operations and theorems about lists should be placed in the `List` namespace, and operations and theorems about `Std.Time.PlainDate` should be placed in the `Std.Time.PlainDate` namespace.
Declarations in the root namespace will be relatively rare. The most common type of declaration in the root namespace are declarations about data and properties exported by notation type classes, as long as they are not about a specific type implementing that type class. For example, we have
```lean
theorem beq_iff_eq [BEq α] [LawfulBEq α] {a b : α} : a == b a = b := sorry
```
in the root namespace, but
```lean
theorem List.cons_beq_cons [BEq α] {a b : α} {l₁ l₂ : List α} :
(a :: l₁ == b :: l₂) = (a == b && l₁ == l₂) := rfl
```
belongs in the `List` namespace.
Subtleties arise when multiple namespaces are in play. Generally, place your theorem in the most specific namespace that appears in one of the hypotheses of the theorem. The following names are both correct according to this convention:
```lean
theorem List.Sublist.reverse : l₁ <+ l₂ l₁.reverse <+ l₂.reverse := sorry
theorem List.reverse_sublist : l₁.reverse <+ l₂.reverse l₁ <+ l₂ := sorry
```
Notice that the second theorem does not have a hypothesis of type `List.Sublist l` for some `l`, so the name `List.Sublist.reverse_iff` would be incorrect.
The advantage of placing results in a namespace like `List.Sublist` is that it enables generalized projection notation, i.e., given `h : l₁ <+ l₂`,
one can write `h.reverse` to obtain a proof of `l₁.reverse <+ l₂.reverse`. Thinking about which dot notations are convenient can act as a guideline
for deciding where to place a theorem, and is, on occasion, a good reason to duplicate a theorem into multiple namespaces.
### The `Std` namespace
New types that are added will usually be placed in the `Std` namespace and in the `Std/` source directory, unless there are good reasons to place
them elsewhere.
Inside the `Std` namespace, all internal declarations should be `private` or else have a name component that clearly marks them as internal, preferably
`Internal`.
## Naming convention for data
When defining data, i.e., a (possibly 0-ary) function whose codomain is not Sort u, but has type Type u for some u, it should be named in lowerCamelCase. Examples include `List.append` and `List.isPrefixOf`.
If your data is morally fully specified by its type, then use the naming procedure for theorems described below and convert the result to lower camel case.
If your function returns an `Option`, consider adding `?` as a suffix. If your function may panic, consider adding `!` as a suffix. In many cases, there will be multiple variants of a function; one returning an option, one that may panic and possibly one that takes a proof argument.
## Naming algorithm for theorems and some definitions
There is, in principle, a general algorithm for naming a theorem. The problem with this algorithm is that it produces very long and unwieldy names which need to be shortened. So choosing a name for a declaration can be thought of as consisting of a mechanical part and a creative part.
Usually the first part is to decide which namespace the result should live in, according to the guidelines described above.
Next, consider the type of your declaration as a tree. Inner nodes of this tree are function types or function applications. Leaves of the tree are 0-ary functions or bound variables.
As an example, consider the following result from the standard library:
```lean
example {α : Type u} {β : Type v} [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α]
[Inhabited β] {m : Std.HashMap α β} {a : α} {h' : a m} : m[a]? = some (m[a]'h') :=
sorry
```
The correct namespace is clearly `Std.HashMap`. The corresponding tree looks like this:
![](naming-tree.svg)
The preferred spelling of a notation can be looked up by hovering over the notation.
Now traverse the tree and build a name according to the following rules:
* When encountering a function type, first turn the result type into a name, then all of the argument types from left to right, and join the names using `_of_`.
* When encountering a function that is neither an infix notation nor a structure projection, first put the function name and then the arguments, joined by an underscore.
* When encountering an infix notation, join the arguments using the name of the notation, separated by underscores.
* When encountering a structure projection, proceed as for normal functions, but put the name of the projection last.
* When encountering a name, put it in lower camel case.
* Skip bound variables and proofs.
* Type class arguments are also generally skipped.
When encountering namespaces names, concatenate them in lower camel case.
Applying this algorithm to our example yields the name `Std.HashMap.getElem?_eq_optionSome_getElem_of_mem`.
From there, the name should be shortened, using the following heuristics:
* The namespace of functions can be omitted if it is clear from context or if the namespace is the current one. This is almost always the case.
* For infix operators, it is possible to leave out the RHS or the name of the notation and the RHS if they are clear from context.
* Hypotheses can be left out if it is clear that they are required or if they appear in the conclusion.
Based on this, here are some possible names for our example:
1. `Std.HashMap.getElem?_eq`
2. `Std.HashMap.getElem?_eq_of_mem`
3. `Std.HashMap.getElem?_eq_some`
4. `Std.HashMap.getElem?_eq_some_of_mem`
5. `Std.HashMap.getElem?_eq_some_getElem`
6. `Std.Hashmap.getElem?_eq_some_getElem_of_mem`
Choosing a good name among these then requires considering the context of the lemma. In this case it turns out that the first four options are underspecified as there is also a lemma relating `m[a]?` and `m[a]!` which could have the same name. This leaves the last two options, the first of which is shorter, and this is how the lemma is called in the Lean standard library.
Here are some additional examples:
```lean
example {x y : List α} (h : x <+: y) (hx : x []) :
x.head hx = y.head (h.ne_nil hx) := sorry
```
Since we have an `IsPrefix` parameter, this should live in the `List.IsPrefix` namespace, and the algorithm suggests `List.IsPrefix.head_eq_head_of_ne_nil`, which is shortened to `List.IsPrefix.head`. Note here the difference between the namespace name (`IsPrefix`) and the recommended spelling of the corresponding notation (`prefix`).
```lean
example : l₁ <+: l₂ reverse l₁ <:+ reverse l₂ := sorry
```
Again, this result should be in the `List.IsPrefix` namespace; the algorithm suggests `List.IsPrefix.reverse_prefix_reverse`, which becomes `List.IsPrefix.reverse`.
The following examples show how the traversal order often matters.
```lean
theorem Nat.mul_zero (n : Nat) : n * 0 = 0 := sorry
theorem Nat.zero_mul (n : Nat) : 0 * n = 0 := sorry
```
Here we see that one name may be a prefix of another name:
```lean
theorem Int.mul_ne_zero {a b : Int} (a0 : a 0) (b0 : b 0) : a * b 0 := sorry
theorem Int.mul_ne_zero_iff {a b : Int} : a * b 0 a 0 b 0 := sorry
```
It is usually a good idea to include the `iff` in a theorem name even if the name would still be unique without the name. For example,
```lean
theorem List.head?_eq_none_iff : l.head? = none l = [] := sorry
```
is a good name: if the lemma was simply called `List.head?_eq_none`, users might try to `apply` it when the goal is `l.head? = none`, leading
to confusion.
The more common you expect (or want) a theorem to be, the shorter you should try to make the name. For example, we have both
```lean
theorem Std.HashMap.getElem?_eq_none_of_contains_eq_false {a : α} : m.contains a = false m[a]? = none := sorry
theorem Std.HashMap.getElem?_eq_none {a : α} : ¬a m m[a]? = none := sorry
```
As users of the hash map are encouraged to use ∈ rather than contains, the second lemma gets the shorter name.
## Special cases
There are certain special “keywords” that may appear in identifiers.
| Keyword | Meaning | Example |
| :---- | :---- | :---- |
| `def` | Unfold a definition. Avoid this for public APIs. | `Nat.max_def` |
| `refl` | Theorems of the form `a R a`, where R is a reflexive relation and `a` is an explicit parameter | `Nat.le_refl` |
| `rfl` | Like `refl`, but with `a` implicit | `Nat.le_rfl` |
| `irrefl` | Theorems of the form `¬a R a`, where R is an irreflexive relation | `Nat.lt_irrefl` |
| `symm` | Theorems of the form `a R b → b R a`, where R is a symmetric relation (compare `comm` below) | `Eq.symm` |
| `trans` | Theorems of the form `a R b → b R c → a R c`, where R is a transitive relation (R may carry data) | `Eq.trans` |
| `antisymmm` | Theorems of the form `a R b → b R a → a = b`, where R is an antisymmetric relation | `Nat.le_antisymm` |
| `congr` | Theorems of the form `a R b → f a S f b`, where R and S are usually equivalence relations | `Std.HashMap.mem_congr` |
| `comm` | Theorems of the form `f a b = f b a` (compare `symm` above) | `Eq.comm`, `Nat.add_comm` |
| `assoc` | Theorems of the form `g (f a b) c = f a (g b c)` (note the order! In most cases, we have f = g) | `Nat.add_sub_assoc` |
| `distrib` | Theorems of the form `f (g a b) = g (f a) (f b)` | `Nat.add_left_distrib` |
| `self` | May be used if a variable appears multiple times in the conclusion | `List.mem_cons_self` |
| `inj` | Theorems of the form `f a = f b ↔ a = b`. | `Int.neg_inj`, `Nat.add_left_inj` |
| `cancel` | Theorems which have one of the forms `f a = f b → a = b` or `g (f a) = a`, where `f` and `g` usually involve a binary operator | `Nat.add_sub_cancel` |
| `cancel_iff` | Same as `inj`, but with different conventions for left and right (see below) | `Nat.add_right_cancel_iff` |
| `ext` | Theorems of the form `f a = f b → a = b`, where `f` usually involves some kind of projection | `List.ext_getElem`
| `mono` | Theorems of the form `a R b → f a R f b`, where `R` is a transitive relation | `List.countP_mono_left`
### Left and right
The keywords left and right are useful to disambiguate symmetric variants of theorems.
```lean
theorem imp_congr_left (h : a b) : (a c) (b c) := sorry
theorem imp_congr_right (h : a (b c)) : (a b) (a c) := sorry
```
It is not always obvious which version of a theorem should be “left” and which should be “right”.
Heuristically, the theorem should name the side which is “more variable”, but there are exceptions. For some of the special keywords discussed in this section, there are conventions which should be followed, as laid out in the following examples:
```lean
theorem Nat.left_distrib (n m k : Nat) : n * (m + k) = n * m + n * k := sorry
theorem Nat.right_distrib (n m k : Nat) : (n + m) * k = n * k + m * k := sorry
theorem Nat.add_left_cancel {n m k : Nat} : n + m = n + k m = k := sorry
theorem Nat.add_right_cancel {n m k : Nat} : n + m = k + m n = k := sorry
theorem Nat.add_left_cancel_iff {m k n : Nat} : n + m = n + k m = k := sorry
theorem Nat.add_right_cancel_iff {m k n : Nat} : m + n = k + n m = k := sorry
theorem Nat.add_left_inj {m k n : Nat} : m + n = k + n m = k := sorry
theorem Nat.add_right_inj {m k n : Nat} : n + m = n + k m = k := sorry
```
Note in particular that the convention is opposite for `cancel_iff` and `inj`.
```lean
theorem Nat.add_sub_self_left (a b : Nat) : (a + b) - a = b := sorry
theorem Nat.add_sub_self_right (a b : Nat) : (a + b) - b = a := sorry
theorem Nat.add_sub_cancel (n m : Nat) : (n + m) - m = n := sorry
```
## Primed names
Avoid disambiguating variants of a concept by appending the `'` character (e.g., introducing both `BitVec.sshiftRight` and `BitVec.sshiftRight'`), as it is impossible to tell the difference without looking at the type signature, the documentation or even the code, and even if you know what the two variants are there is no way to tell which is which. Prefer descriptive pairs `BitVec.sshiftRightNat`/`BitVec.sshiftRight`.
## Acronyms
For acronyms which are three letters or shorter, all letters should use the same case as dictated by the convention. For example, `IO` is a correct name for a type and the name `IO.Ref` may become `IORef` when used as part of a definition name and `ioRef` when used as part of a theorem name.
For acronyms which are at least four letters long, switch to lower case starting from the second letter. For example, `Json` is a correct name for a type, as is `JsonRPC`.
If an acronym is typically spelled using mixed case, this mixed spelling may be used in identifiers (for example `Std.Net.IPv4Addr`).
## Simp sets
Simp sets centered around a conversion function should be called `source_to_target`. For example, a simp set for the `BitVec.toNat` function, which goes from `BitVec` to
`Nat`, should be called `bitvec_to_nat`.
## Variable names
We make the following recommendations for variable names, but without insisting on them:
* Simple hypotheses should be named `h`, `h'`, or using a numerical sequence `h₁`, `h₂`, etc.
* Another common name for a simple hypothesis is `w` (for "witness").
* `List`s should be named `l`, `l'`, `l₁`, etc, or `as`, `bs`, etc.
(Use of `as`, `bs` is encouraged when the lists are of different types, e.g. `as : List α` and `bs : List β`.)
`xs`, `ys`, `zs` are allowed, but it is better if these are reserved for `Array` and `Vector`.
A list of lists may be named `L`.
* `Array`s should be named `xs`, `ys`, `zs`, although `as`, `bs` are encouraged when the arrays are of different types, e.g. `as : Array α` and `bs : Array β`.
An array of arrays may be named `xss`.
* `Vector`s should be named `xs`, `ys`, `zs`, although `as`, `bs` are encouraged when the vectors are of different types, e.g. `as : Vector α n` and `bs : Vector β n`.
A vector of vectors may be named `xss`.
* A common exception for `List` / `Array` / `Vector` is to use `acc` for an accumulator in a recursive function.
* `i`, `j`, `k` are preferred for numerical indices.
Descriptive names such as `start`, `stop`, `lo`, and `hi` are encouraged when they increase readability.
* `n`, `m` are preferred for sizes, e.g. in `Vector α n` or `xs.size = n`.
* `w` is preferred for the width of a `BitVec`.

522
doc/std/style.md Normal file
View File

@@ -0,0 +1,522 @@
# Standard library style
Please take some time to familiarize yourself with the stylistic conventions of
the project and the specific part of the library you are planning to contribute
to. While the Lean compiler may not enforce strict formatting rules,
consistently formatted code is much easier for others to read and maintain.
Attention to formatting is more than a cosmetic concern—it reflects the same
level of precision and care required to meet the deeper standards of the Lean 4
standard library.
Below we will give specific formatting prescriptions for various language constructs. Note that this style guide only applies to the Lean standard library, even though some examples in the guide are taken from other parts of the Lean code base.
## Basic whitespace rules
Syntactic elements (like `:`, `:=`, `|`, `::`) are surrounded by single spaces, with the exception of `,` and `;`, which are followed by a space but not preceded by one. Delimiters (like `()`, `{}`) do not have spaces on the inside, with the exceptions of subtype notation and structure instance notation.
Examples of correctly formatted function parameters:
* `{α : Type u}`
* `[BEq α]`
* `(cmp : αα → Ordering)`
* `(hab : a = b)`
* `{d : { l : List ((n : Nat) × Vector Nat n) // l.length % 2 = 0 }}`
Examples of correctly formatted terms:
* `1 :: [2, 3]`
* `letI : Ord α := ⟨cmp⟩; True`
* `(⟨2, 3⟩ : Nat × Nat)`
* `((2, 3) : Nat × Nat)`
* `{ x with fst := f (4 + f 0), snd := 4, .. }`
* `match 1 with | 0 => 0 | _ => 0`
* `fun ⟨a, b⟩ _ _ => by cases hab <;> apply id; rw [hbc]`
Configure your editor to remove trailing whitespace. If you have set up Visual Studio Code for Lean development in the recommended way then the correct setting is applied automatically.
## Splitting terms across multiple lines
When splitting a term across multiple lines, increase indentation by two spaces starting from the second line. When splitting a function application, try to split at argument boundaries. If an argument itself needs to be split, increase indentation further as appropriate.
When splitting at an infix operator, the operator goes at the end of the first line, not at the beginning of the second line. When splitting at an infix operator, you may or may not increase indentation depth, depending on what is more readable.
When splitting an `if`-`then`-`else` expression, the `then` keyword wants to stay with the condition and the `else` keyword wants to stay with the alternative term. Otherwise, indent as if the `if` and `else` keywords were arguments to the same function.
When splitting a comma-separated bracketed sequence (i.e., anonymous constructor application, list/array/vector literal, tuple) it is allowed to indent subsequent lines for alignment, but indenting by two spaces is also allowed.
Do not orphan parentheses.
Correct:
```lean
def MacroScopesView.isPrefixOf (v₁ v₂ : MacroScopesView) : Bool :=
v₁.name.isPrefixOf v₂.name &&
v₁.scopes == v₂.scopes &&
v₁.mainModule == v₂.mainModule &&
v₁.imported == v₂.imported
```
Correct:
```lean
theorem eraseP_eq_iff {p} {l : List α} :
l.eraseP p = l'
(( a l, ¬ p a) l = l')
a l₁ l₂, ( b l₁, ¬ p b) p a
l = l₁ ++ a :: l₂ l' = l₁ ++ l₂ :=
sorry
```
Correct:
```lean
example : Nat :=
functionWithAVeryLongNameSoThatSomeArgumentsWillNotFit firstArgument secondArgument
(firstArgumentWithAnEquallyLongNameAndThatFunctionDoesHaveMoreArguments firstArgument
secondArgument)
secondArgument
```
Correct:
```lean
theorem size_alter [LawfulBEq α] {k : α} {f : Option (β k) Option (β k)} (h : m.WF) :
(m.alter k f).size =
if m.contains k && (f (m.get? k)).isNone then
m.size - 1
else if !m.contains k && (f (m.get? k)).isSome then
m.size + 1
else
m.size := by
simp_to_raw using Raw₀.size_alter
```
Correct:
```lean
theorem get?_alter [LawfulBEq α] {k k' : α} {f : Option (β k) Option (β k)} (h : m.WF) :
(m.alter k f).get? k' =
if h : k == k' then
cast (congrArg (Option β) (eq_of_beq h)) (f (m.get? k))
else m.get? k' := by
simp_to_raw using Raw₀.get?_alter
```
Correct:
```lean
example : Nat × Nat :=
imagineThisWasALongTerm,
imagineThisWasAnotherLongTerm
```
Correct:
```lean
example : Nat × Nat :=
imagineThisWasALongTerm,
imagineThisWasAnotherLongTerm
```
Correct:
```lean
example : Vector Nat :=
#v[imagineThisWasALongTerm,
imagineThisWasAnotherLongTerm]
```
## Basic file structure
Every file should start with a copyright header, imports (in the standard library, this always includes a `prelude` declaration) and a module documentation string. There should not be a blank line between the copyright header and the imports. There should be a blank line between the imports and the module documentation string.
If you explicitly declare universe variables, do so at the top of the file, after the module documentation.
Correct:
```lean
/-
Copyright (c) 2014 Parikshit Khanna. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro,
Yury Kudryashov
-/
prelude
import Init.Data.List.Pairwise
import Init.Data.List.Find
/-!
**# Lemmas about `List.eraseP` and `List.erase`.**
-/
universe u u'
```
Syntax that is not supposed to be user-facing must be scoped. New public syntax must always be discussed explicitly in an RFC.
## Top-level commands and declarations
All top-level commands are unindented. Sectioning commands like `section` and `namespace` do not increase the indentation level.
Attributes may be placed on the same line as the rest of the command or on a separate line.
Multi-line declaration headers are indented by four spaces starting from the second line. The colon that indicates the type of a declaration may not be placed at the start of a line or on its own line.
Declaration bodies are indented by two spaces. Short declaration bodies may be placed on the same line as the declaration type.
Correct:
```lean
theorem eraseP_eq_iff {p} {l : List α} :
l.eraseP p = l'
(( a l, ¬ p a) l = l')
a l₁ l₂, ( b l₁, ¬ p b) p a
l = l₁ ++ a :: l₂ l' = l₁ ++ l₂ :=
sorry
```
Correct:
```lean
@[simp] theorem eraseP_nil : [].eraseP p = [] := rfl
```
Correct:
```lean
@[simp]
theorem eraseP_nil : [].eraseP p = [] := rfl
```
### Documentation comments
Note to external contributors: this is a section where the Lean style and the mathlib style are different.
Declarations should be documented as required by the `docBlame` linter, which may be activated in a file using
`set_option linter.missingDocs true` (we allow these to stay in the file).
Single-line documentation comments should go on the same line as `/--`/`-/`, while multi-line documentation strings
should have these delimiters on their own line, with the documentation comment itself unindented.
Documentation comments must be written in the indicative mood. Use American orthography.
Correct:
```lean
/-- Carries out a monadic action on each mapping in the hash map in some order. -/
@[inline] def forM (f : (a : α) β a m PUnit) (b : Raw α β) : m PUnit :=
b.buckets.forM (AssocList.forM f)
```
Correct:
```lean
/--
Monadically computes a value by folding the given function over the mappings in the hash
map in some order.
-/
@[inline] def foldM (f : δ (a : α) β a m δ) (init : δ) (b : Raw α β) : m δ :=
b.buckets.foldlM (fun acc l => l.foldlM f acc) init
```
### Where clauses
The `where` keyword should be unindented, and all declarations bound by it should be indented with two spaces.
Blank lines before and after `where` and between declarations bound by `where` are optional and should be chosen
to maximize readability.
Correct:
```lean
@[simp] theorem partition_eq_filter_filter (p : α Bool) (l : List α) :
partition p l = (filter p l, filter (not p) l) := by
simp [partition, aux]
where
aux (l) {as bs} : partition.loop p l (as, bs) =
(as.reverse ++ filter p l, bs.reverse ++ filter (not p) l) :=
match l with
| [] => by simp [partition.loop, filter]
| a :: l => by cases pa : p a <;> simp [partition.loop, pa, aux, filter, append_assoc]
```
### Termination arguments
The `termination_by`, `decreasing_by`, `partial_fixpoint` keywords should be unindented. The associated terms should be indented like declaration bodies.
Correct:
```lean
@[inline] def multiShortOption (handle : Char m PUnit) (opt : String) : m PUnit := do
let rec loop (p : String.Pos) := do
if h : opt.atEnd p then
return
else
handle (opt.get' p h)
loop (opt.next' p h)
termination_by opt.utf8ByteSize - p.byteIdx
decreasing_by
simp [String.atEnd] at h
apply Nat.sub_lt_sub_left h
simp [String.lt_next opt p]
loop 1
```
Correct:
```lean
def substrEq (s1 : String) (off1 : String.Pos) (s2 : String) (off2 : String.Pos) (sz : Nat) : Bool :=
off1.byteIdx + sz s1.endPos.byteIdx && off2.byteIdx + sz s2.endPos.byteIdx && loop off1 off2 { byteIdx := off1.byteIdx + sz }
where
loop (off1 off2 stop1 : Pos) :=
if _h : off1.byteIdx < stop1.byteIdx then
let c₁ := s1.get off1
let c₂ := s2.get off2
c₁ == c₂ && loop (off1 + c₁) (off2 + c₂) stop1
else true
termination_by stop1.1 - off1.1
decreasing_by
have := Nat.sub_lt_sub_left _h (Nat.add_lt_add_left c₁.utf8Size_pos off1.1)
decreasing_tactic
```
Correct:
```lean
theorem div_add_mod (m n : Nat) : n * (m / n) + m % n = m := by
rw [div_eq, mod_eq]
have h : Decidable (0 < n n m) := inferInstance
cases h with
| isFalse h => simp [h]
| isTrue h =>
simp [h]
have ih := div_add_mod (m - n) n
rw [Nat.left_distrib, Nat.mul_one, Nat.add_assoc, Nat.add_left_comm, ih, Nat.add_comm, Nat.sub_add_cancel h.2]
decreasing_by apply div_rec_lemma; assumption
```
### Deriving
The `deriving` clause should be unindented.
Correct:
```lean
structure Iterator where
array : ByteArray
idx : Nat
deriving Inhabited
```
## Notation and Unicode
We generally prefer to use notation as available. We usually prefer the Unicode versions of notations over non-Unicode alternatives.
There are some rules and exceptions regarding specific notations which are listed below:
* Sigma types: use `(a : α) × β a` instead of `Σ a, β a` or `Sigma β`.
* Function arrows: use `fun a => f x` instead of `fun x ↦ f x` or `λ x => f x` or any other variant.
## Language constructs
### Pattern matching, induction etc.
Match arms are indented at the indentation level that the match statement would have if it was on its own line. If the match is implicit, then the arms should be indented as if the match was explicitly given. The content of match arms is indented two spaces, so that it appears on the same level as the match pattern.
Correct:
```lean
def alter [BEq α] {β : Type v} (a : α) (f : Option β Option β) :
AssocList α (fun _ => β) AssocList α (fun _ => β)
| nil => match f none with
| none => nil
| some b => AssocList.cons a b nil
| cons k v l =>
if k == a then
match f v with
| none => l
| some b => cons a b l
else
cons k v (alter a f l)
```
Correct:
```lean
theorem eq_append_cons_of_mem {a : α} {xs : List α} (h : a xs) :
as bs, xs = as ++ a :: bs a as := by
induction xs with
| nil => cases h
| cons x xs ih =>
simp at h
cases h with
| inl h => exact [], xs, by simp_all
| inr h =>
by_cases h' : a = x
· subst h'
exact [], xs, by simp
· obtain as, bs, rfl, h := ih h
exact x :: as, bs, rfl, by simp_all
```
Aligning match arms is allowed, but not required.
Correct:
```lean
def mkEqTrans? (h₁? h₂? : Option Expr) : MetaM (Option Expr) :=
match h₁?, h₂? with
| none, none => return none
| none, some h => return h
| some h, none => return h
| some h₁, some h₂ => mkEqTrans h₁ h₂
```
Correct:
```lean
def mkEqTrans? (h₁? h₂? : Option Expr) : MetaM (Option Expr) :=
match h₁?, h₂? with
| none, none => return none
| none, some h => return h
| some h, none => return h
| some h₁, some h₂ => mkEqTrans h₁ h₂
```
Correct:
```lean
def mkEqTrans? (h₁? h₂? : Option Expr) : MetaM (Option Expr) :=
match h₁?, h₂? with
| none, none => return none
| none, some h => return h
| some h, none => return h
| some h₁, some h₂ => mkEqTrans h₁ h₂
```
### Structures
Note to external contributors: this is a section where the Lean style and the mathlib style are different.
When using structure instance syntax over multiple lines, the opening brace should go on the preceding line, while the closing brace should go on its own line. The rest of the syntax should be indented by one level. During structure updates, the `with` clause goes on the same line as the opening brace. Aligning at the assignment symbol is allowed but not required.
Correct:
```lean
def addConstAsync (env : Environment) (constName : Name) (kind : ConstantKind) (reportExts := true) :
IO AddConstAsyncResult := do
let sigPromise IO.Promise.new
let infoPromise IO.Promise.new
let extensionsPromise IO.Promise.new
let checkedEnvPromise IO.Promise.new
let asyncConst := {
constInfo := {
name := constName
kind
sig := sigPromise.result
constInfo := infoPromise.result
}
exts? := guard reportExts *> some extensionsPromise.result
}
return {
constName, kind
mainEnv := { env with
asyncConsts := env.asyncConsts.add asyncConst
checked := checkedEnvPromise.result }
asyncEnv := { env with
asyncCtx? := some { declPrefix := privateToUserName constName.eraseMacroScopes }
}
sigPromise, infoPromise, extensionsPromise, checkedEnvPromise
}
```
Correct:
```lean
instance [Inhabited α] : Inhabited (Descr α β σ) where
default := {
name := default
mkInitial := default
ofOLeanEntry := default
toOLeanEntry := default
addEntry := fun s _ => s
}
```
### Declaring structures
When defining structure types, do not parenthesize structure fields.
When declaring a structure type with a custom constructor name, put the custom name on its own line, indented like the
structure fields, and add a documentation comment.
Correct:
```lean
/--
A bitvector of the specified width.
This is represented as the underlying `Nat` number in both the runtime
and the kernel, inheriting all the special support for `Nat`.
-/
structure BitVec (w : Nat) where
/--
Constructs a `BitVec w` from a number less than `2^w`.
O(1), because we use `Fin` as the internal representation of a bitvector.
-/
ofFin ::
/--
Interprets a bitvector as a number less than `2^w`.
O(1), because we use `Fin` as the internal representation of a bitvector.
-/
toFin : Fin (2 ^ w)
```
## Tactic proofs
Tactic proofs are the most common thing to break during any kind of upgrade, so it is important to write them in a way that minimizes the likelihood of proofs breaking and that makes it easy to debug breakages if they do occur.
If there are multiple goals, either use a tactic combinator (like `all_goals`) to operate on all of them or a clearly specified subset, or use focus dots to work on goals one at a time. Using structured proofs (e.g., `induction … with`) is encouraged but not mandatory.
Squeeze non-terminal `simp`s (i.e., calls to `simp` which do not close the goal). Squeezing terminal `simp`s is generally discouraged, although there are exceptions (for example if squeezing yields a noticeable performance improvement).
Do not over-golf proofs in ways that are likely to lead to hard-to-debug breakage. Examples of things to avoid include complex multi-goal manipulation using lots of tactic combinators, complex uses of the substitution operator (`▸`) and clever point-free expressions (possibly involving anonymous function notation for multiple arguments).
Do not under-golf proofs: for routine tasks, use the most powerful tactics available.
Do not use `erw`. Avoid using `rfl` after `simp` or `rw`, as this usually indicates a missing lemma that should be used instead of `rfl`.
Use `(d)simp` or `rw` instead of `delta` or `unfold`. Use `refine` instead of `refine`. Use `haveI` and `letI` only if they are actually required.
Prefer highly automated tactics (like `grind` and `omega`) over low-level proofs, unless the automated tactic requires unacceptable additional imports or has bad performance. If you decide against using a highly automated tactic, leave a comment explaining the decision.
## `do` notation
The `do` keyword goes on the same line as the corresponding `:=` (or `=>`, or similar). `Id.run do` should be treated as if it was a bare `do`.
Use early `return` statements to reduce nesting depth and make the non-exceptional control flow of a function easier to see.
Alternatives for `let` matches may be placed in the same line or in the next line, indented by two spaces. If the term that is
being matched on is itself more than one line and there is an alternative present, consider breaking immediately after `←` and indent
as far as necessary to ensure readability.
Correct:
```lean
def getFunDecl (fvarId : FVarId) : CompilerM FunDecl := do
let some decl findFunDecl? fvarId | throwError "unknown local function {fvarId.name}"
return decl
```
Correct:
```lean
def getFunDecl (fvarId : FVarId) : CompilerM FunDecl := do
let some decl
findFunDecl? fvarId
| throwError "unknown local function {fvarId.name}"
return decl
```
Correct:
```lean
def getFunDecl (fvarId : FVarId) : CompilerM FunDecl := do
let some decl findFunDecl?
fvarId
| throwError "unknown local function {fvarId.name}"
return decl
```
Correct:
```lean
def tagUntaggedGoals (parentTag : Name) (newSuffix : Name) (newGoals : List MVarId) : TacticM Unit := do
let mctx getMCtx
let mut numAnonymous := 0
for g in newGoals do
if mctx.isAnonymousMVar g then
numAnonymous := numAnonymous + 1
modifyMCtx fun mctx => Id.run do
let mut mctx := mctx
let mut idx := 1
for g in newGoals do
if mctx.isAnonymousMVar g then
if numAnonymous == 1 then
mctx := mctx.setMVarUserName g parentTag
else
mctx := mctx.setMVarUserName g (parentTag ++ newSuffix.appendIndexAfter idx)
idx := idx + 1
pure mctx
```

98
doc/std/vision.md Normal file
View File

@@ -0,0 +1,98 @@
# The Lean 4 standard library
Maintainer team (in alphabetical order): Henrik Böving, Markus Himmel
(community contact & external contribution coordinator), Kim Morrison, Paul
Reichert, Sofia Rodrigues.
The Lean 4 standard library is a core part of the Lean distribution, providing
essential building blocks for functional programming, verified software
development, and software verification. Unlike the standard libraries of most
other languages, many of its components are formally verified and can be used
as part of verified applications.
The standard library is a public API that contains the components listed in the
standard library outline below. Not all public APIs in the Lean distribution
are part of the standard library, and the standard library does not correspond
to a certain directory within the Lean source repository (like `Std`). For
example, the metaprogramming framework is not part of the standard library, but
basic types like `True` and `Nat` are.
The standard library is under active development. Our guiding principles are:
* Provide comprehensive, verified building blocks for real-world software.
* Build a public API of the highest quality with excellent internal consistency.
* Carefully optimize components that may be used in performance-critical software.
* Ensure smooth adoption and maintenance for users.
* Offer excellent documentation, example projects, and guides.
* Provide a reliable and extensible basis that libraries for software
development, software verification and mathematics can build on.
The standard library is principally developed by the Lean FRO. Community
contributions are welcome. If you would like to contribute, please refer to the
call for contributions below.
### Standard library outline
1. Core types and operations
1. Basic types
2. Numeric types, including floating point numbers
3. Containers
4. Strings and formatting
2. Language constructs
1. Ranges and iterators
2. Comparison, ordering, hashing and related type classes
3. Basic monad infrastructure
3. Libraries
1. Random numbers
2. Dates and times
4. Operating system abstractions
1. Concurrency and parallelism primitives
2. Asynchronous I/O
3. FFI helpers
4. Environment, file system, processes
5. Locales
The material covered in the first three sections (core types and operations,
language constructs and libraries) will be verified, with the exception of
floating point numbers and the parts of the libraries that interface with the
operating system (e.g., sources of operating system randomness or time zone
database access).
### Call for contributions
Thank you for taking interest in contributing to the Lean standard library\!
There are two main ways for community members to contribute to the Lean
standard library: by contributing experience reports or by contributing code
and lemmas.
**If you are using Lean for software verification or verified software
development:** hearing about your experiences using Lean and its standard
library for software verification is extremely valuable to us. We are committed
to building a standard library suitable for real-world applications and your
input will directly influence the continued evolution of the Lean standard
library. Please reach out to the standard library maintainer team via Zulip
(either in a public thread in the \#lean4 channel or via direct message). Even
just a link to your code helps. Thanks\!
**If you have code that you believe could enhance the Lean 4 standard
library:** we encourage you to initiate a discussion in the \#lean4 channel on
Zulip. This is the most effective way to receive preliminary feedback on your
contribution. The Lean standard library has a very precise scope and it has
very high quality standards, so at the moment we are mostly interested in
contributions that expand upon existing material rather than introducing novel
concepts.
**If you would like to contribute code to the standard library but dont know
what to work on:** we are always excited to meet motivated community members
who would like to contribute, and there is always impactful work that is
suitable for new contributors. Please reach out to Markus Himmel on Zulip to
discuss possible contributions.
As laid out in the [project-wide External Contribution
Guidelines](../../CONTRIBUTING.md),
PRs are much more likely to be merged if they are preceded by an RFC or if you
discussed your planned contribution with a member of the standard library
maintainer team. When in doubt, introducing yourself is always a good idea.
All code in the standard library is expected to strictly adhere to the
[standard library coding conventions](./style.md).

View File

@@ -1 +0,0 @@
# Strings

View File

@@ -1,58 +0,0 @@
# String interpolation
The `s!` prefix identifies a string literal as an interpolated string.
An interpolated string is a string literal that might contain interpolation expressions.
When an interpolated string is resolved to a result string, items with interpolation expressions are
replaced by the string representations of the expression results. The polymorphic method `toString` is used
to convert the value into a string.
String interpolation provides a more readable and convenient syntax to create formatted strings than
a string composite formatting feature. The following example uses both features to produce the same output:
```lean
def name := "John"
def age := 28
#eval IO.println s!"Hello, {name}! Are you {age} years old?"
#eval IO.println ("Hello, " ++ name ++ "! Are you " ++ toString age ++ " years old?")
-- `println! <interpolated-string>` is a macro for `IO.println s!<interpolated-string>`
#eval println! "Hello, {name}! Are you {age} years old?"
```
# Structure of an interpolated string
To identify a string literal as an interpolated string, prepend it with `s!`.
Terms inside braces `{}` are ordinary expressions whose type implements the type class `ToString`.
To include a curly brace `{` in your interpolated string, you must escape it using `\{`.
You can nest interpolated strings inside interpolated strings.
```lean
def vals := [1, 2, 3]
#eval IO.println s!"\{ vals := {vals} }"
#eval IO.println s!"variables: {vals.map (fun i => s!"x_{i}")}"
```
# `ToString` instances
You can define a `ToString` instance for your own datatypes.
```lean
structure Person where
name : String
age : Nat
instance : ToString Person where
toString : Person -> String
| { name := n, age := v } => s!"\{ name := {n}, age := {v} }"
def person1 : Person := {
name := "John"
age := 28
}
#eval println! "person1: {person1}"
```

View File

@@ -1,227 +0,0 @@
# Structures
Structure is a special case of inductive datatype. It has only one constructor and is not recursive.
Similar to the `inductive` command, the `structure` command introduces a namespace with the same name.
The general form is as follows:
```
structure <name> <parameters> <parent-structures> where
<constructor-name> :: <fields>
```
Most parts are optional. Here is our first example.
```lean
structure Point (α : Type u) where
x : α
y : α
```
In the example above, the constructor name is not provided. So, the constructor is named `mk` by Lean.
Values of type ``Point`` are created using `Point.mk a b` or `{ x := a, y := b : Point α }`. The latter can be
written as `{ x := a, y := b }` when the expected type is known.
The fields of a point ``p`` are accessed using ``Point.x p`` and ``Point.y p``. You can also the more compact notation `p.x` and `p.y` as a shorthand
for `Point.x p` and `Point.y p`.
```lean
# structure Point (α : Type u) where
# x : α
# y : α
#check Point
#check Point -- Type u -> Type u
#check @Point.mk -- {α : Type u} → αα → Point α
#check @Point.x -- {α : Type u} → Point αα
#check @Point.y -- {α : Type u} → Point αα
#check Point.mk 10 20 -- Point Nat
#check { x := 10, y := 20 : Point Nat } -- Point Nat
def mkPoint (a : Nat) : Point Nat :=
{ x := a, y := a }
#eval (Point.mk 10 20).x -- 10
#eval (Point.mk 10 20).y -- 20
#eval { x := 10, y := 20 : Point Nat }.x -- 10
#eval { x := 10, y := 20 : Point Nat }.y -- 20
def addXY (p : Point Nat) : Nat :=
p.x + p.y
#eval addXY { x := 10, y := 20 } -- 30
```
In the notation `{ ... }`, if the fields are in different lines, the `,` is optional.
```lean
# structure Point (α : Type u) where
# x : α
# y : α
def mkPoint (a : Nat) : Point Nat := {
x := a
y := a
}
```
You can also use `where` instead of `:= { ... }`.
```lean
# structure Point (α : Type u) where
# x : α
# y : α
def mkPoint (a : Nat) : Point Nat where
x := a
y := a
```
Here are some simple theorems about our `Point` type.
```lean
# structure Point (α : Type u) where
# x : α
# y : α
theorem ex1 (a b : α) : (Point.mk a b).x = a :=
rfl
theorem ex2 (a b : α) : (Point.mk a b).y = b :=
rfl
theorem ex3 (a b : α) : Point.mk a b = { x := a, y := b } :=
rfl
```
The dot notation is convenient not just for accessing the projections of a structure,
but also for applying functions defined in a namespace with the same name.
If ``p`` has type ``Point``, the expression ``p.foo`` is interpreted as ``Point.foo p``,
assuming that the first argument to ``foo`` has type ``Point``.
The expression ``p.add q`` is therefore shorthand for ``Point.add p q`` in the example below.
```lean
structure Point (α : Type u) where
x : α
y : α
def Point.add (p q : Point Nat) : Point Nat :=
{ x := p.x + q.x, y := p.y + q.y }
def p : Point Nat := Point.mk 1 2
def q : Point Nat := Point.mk 3 4
#eval (p.add q).x -- 4
#eval (p.add q).y -- 6
```
After we introduce type classes, we show how to define a function like ``add`` so that
it works generically for elements of ``Point α`` rather than just ``Point Nat``,
assuming ``α`` has an associated addition operation.
More generally, given an expression ``p.foo x y z``, Lean will insert ``p`` at the first argument to ``foo`` of type ``Point``.
For example, with the definition of scalar multiplication below, ``p.smul 3`` is interpreted as ``Point.smul 3 p``.
```lean
structure Point (α : Type u) where
x : α
y : α
def Point.smul (n : Nat) (p : Point Nat) :=
Point.mk (n * p.x) (n * p.y)
def p : Point Nat :=
Point.mk 1 2
#eval (p.smul 3).x -- 3
#eval (p.smul 3).y -- 6
```
## Inheritance
We can *extend* existing structures by adding new fields. This feature allows us to simulate a form of *inheritance*.
```lean
structure Point (α : Type u) where
x : α
y : α
inductive Color where
| red
| green
| blue
structure ColorPoint (α : Type u) extends Point α where
color : Color
#check { x := 10, y := 20, color := Color.red : ColorPoint Nat }
-- { toPoint := { x := 10, y := 20 }, color := Color.red }
```
The output for the `check` command above suggests how Lean encoded inheritance and multiple inheritance.
Lean uses fields to each parent structure.
```lean
structure Foo where
x : Nat
y : Nat
structure Boo where
w : Nat
z : Nat
structure Bla extends Foo, Boo where
bit : Bool
#check Bla.mk -- Foo → Boo → Bool → Bla
#check Bla.mk { x := 10, y := 20 } { w := 30, z := 40 } true
#check { x := 10, y := 20, w := 30, z := 40, bit := true : Bla }
#check { toFoo := { x := 10, y := 20 },
toBoo := { w := 30, z := 40 },
bit := true : Bla }
theorem ex :
Bla.mk { x := x, y := y } { w := w, z := z } b
=
{ x := x, y := y, w := w, z := z, bit := b } :=
rfl
```
## Default field values
You can assign default value to fields when declaring a new structure.
```lean
inductive MessageSeverity
| error | warning
structure Message where
fileName : String
pos : Option Nat := none
severity : MessageSeverity := MessageSeverity.error
caption : String := ""
data : String
def msg1 : Message :=
{ fileName := "foo.lean", data := "failed to import file" }
#eval msg1.pos -- none
#eval msg1.fileName -- "foo.lean"
#eval msg1.caption -- ""
```
When extending a structure, you can not only add new fields, but provide new default values for existing fields.
```lean
# inductive MessageSeverity
# | error | warning
# structure Message where
# fileName : String
# pos : Option Nat := none
# severity : MessageSeverity := MessageSeverity.error
# caption : String := ""
# data : String
structure MessageExt extends Message where
timestamp : Nat
caption := "extended" -- new default value for field `caption`
def msg2 : MessageExt where
fileName := "bar.lean"
data := "error at initialization"
timestamp := 10
#eval msg2.fileName -- "bar.lean"
#eval msg2.timestamp -- 10
#eval msg2.caption -- "extended"
```
## Updating structure fields
Structure fields can be updated using `{ <struct-val> with <field> := <new-value>, ... }`:
```lean
# structure Point (α : Type u) where
# x : α
# y : α
def incrementX (p : Point Nat) : Point Nat := { p with x := p.x + 1 }
```

View File

@@ -1,20 +0,0 @@
# Syntax Extensions
Lean's syntax can be extended and customized
by users at every level, ranging from [basic "mixfix" notations](./notation.md)
over [macro transformers](./macro_overview.md) to
[type-aware elaborators](./elaborators.md). In fact, all builtin syntax is parsed and
processed using the same mechanisms and APIs open to users. In this
section, we will describe and explain the various extension points.
Significant syntax extensions already builtin into Lean such as the
[`do` notation](./do.md) are described in subsections.
While introducing new syntax is a relatively rare feature in
programming languages and sometimes even frowned upon because of its
potential to obscure code, it is an invaluable tool in formalization
for expressing established conventions and notations of the respective
field succinctly in code. Going beyond basic notations, Lean's ability
to factor out common boilerplate code into (well-behaved) macros and
to embed entire custom domain specific languages (DSLs) to textually
encode subproblems efficiently and readably can be of great benefit to
both programmers and proof engineers alike.

View File

@@ -1 +0,0 @@
# Task

View File

@@ -1,104 +0,0 @@
# Thunks, Tasks, and Threads
A `Thunk` is defined as
```lean
# namespace Ex
# universe u
structure Thunk (α : Type u) : Type u where
fn : Unit α
# end Ex
```
A `Thunk` encapsulates a computation without evaluation.
That is, a `Thunk` stores the way of how the value would be computed.
The Lean runtime has special support for `Thunk`s. It caches their values
after they are computed for the first time. This feature is useful for implementing
data structures such as lazy lists.
Here is a small example using a `Thunk`.
```lean
def fib : Nat Nat
| 0 => 0
| 1 => 1
| x+2 => fib (x+1) + fib x
def f (c : Bool) (x : Thunk Nat) : Nat :=
if c then
x.get
else
0
def g (c : Bool) (x : Nat) : Nat :=
f c (Thunk.mk (fun _ => fib x))
#eval g false 1000
```
The function `f` above uses `x.get` to evaluate the `Thunk` `x`.
The expression `Thunk.mk (fun _ => fib x)` creates a `Thunk` for computing `fib x`.
Note that `fib` is a very naive function for computing the Fibonacci numbers,
and it would an unreasonable amount of time to compute `fib 1000`. However, our
test terminates instantaneously because the `Thunk` is not evaluated when `c` is `false`.
Lean has a builtin coercion from any type `a` to `Thunk a`. You write the function `g` above as
```lean
# def fib : Nat Nat
# | 0 => 0
# | 1 => 1
# | x+2 => fib (x+1) + fib x
# def f (c : Bool) (x : Thunk Nat) : Nat :=
# if c then
# x.get
# else
# 0
def g (c : Bool) (x : Nat) : Nat :=
f c (fib x)
#eval g false 1000
```
In the following example, we use the macro `dbg_trace` to demonstrate
that the Lean runtime caches the value computed by a `Thunk`.
We remark that the macro `dbg_trace` should be used for debugging purposes
only.
```lean
def add1 (x : Nat) : Nat :=
dbg_trace "add1: {x}"
x + 1
def double (x : Thunk Nat) : Nat :=
x.get + x.get
def triple (x : Thunk Nat) : Nat :=
double x + x.get
def test (x : Nat) : Nat :=
triple (add1 x)
#eval test 2
-- add1: 2
-- 9
```
Note that the message `add1: 2` is printed only once.
Now, consider the same example using `Unit -> Nat` instead of `Thunk Nat`.
```lean
def add1 (x : Nat) : Nat :=
dbg_trace "add1: {x}"
x + 1
def double (x : Unit -> Nat) : Nat :=
x () + x ()
def triple (x : Unit -> Nat) : Nat :=
double x + x ()
def test (x : Nat) : Nat :=
triple (fun _ => add1 x)
#eval test 2
-- add1: 2
-- add1: 2
-- 9
```
Now, the message `add1: 2` is printed twice.
It may come as a surprise that it was printed twice instead of three times.
As we pointed out, `dbg_trace` is a macro used for debugging purposes only,
and `add1` is still considered to be a pure function.
The Lean compiler performs common subexpression elimination when compiling `double`,
and the produced code for `double` executes `x ()` only once instead of twice.
This transformation is safe because `x : Unit -> Nat` is pure.

View File

@@ -1,457 +0,0 @@
# Type classes
Typeclasses were introduced as a principled way of enabling
ad-hoc polymorphism in functional programming languages. We first observe that it
would be easy to implement an ad-hoc polymorphic function (such as addition) if the
function simply took the type-specific implementation of addition as an argument
and then called that implementation on the remaining arguments. For example,
suppose we declare a structure in Lean to hold implementations of addition
```lean
# namespace Ex
structure Add (a : Type) where
add : a -> a -> a
#check @Add.add
-- Add.add : {a : Type} → Add a → a → a → a
# end Ex
```
In the above Lean code, the field `add` has type
`Add.add : {α : Type} → Add αααα`
where the curly braces around the type `a` mean that it is an implicit argument.
We could implement `double` by
```lean
# namespace Ex
# structure Add (a : Type) where
# add : a -> a -> a
def double (s : Add a) (x : a) : a :=
s.add x x
#eval double { add := Nat.add } 10
-- 20
#eval double { add := Nat.mul } 10
-- 100
#eval double { add := Int.add } 10
-- 20
# end Ex
```
Note that you can double a natural number `n` by `double { add := Nat.add } n`.
Of course, it would be highly cumbersome for users to manually pass the
implementations around in this way.
Indeed, it would defeat most of the potential benefits of ad-hoc
polymorphism.
The main idea behind typeclasses is to make arguments such as `Add a` implicit,
and to use a database of user-defined instances to synthesize the desired instances
automatically through a process known as typeclass resolution. In Lean, by changing
`structure` to `class` in the example above, the type of `Add.add` becomes
```lean
# namespace Ex
class Add (a : Type) where
add : a -> a -> a
#check @Add.add
-- Add.add : {a : Type} → [self : Add a] → a → a → a
# end Ex
```
where the square brackets indicate that the argument of type `Add a` is *instance implicit*,
i.e. that it should be synthesized using typeclass resolution. This version of
`add` is the Lean analogue of the Haskell term `add :: Add a => a -> a -> a`.
Similarly, we can register an instance by
```lean
# namespace Ex
# class Add (a : Type) where
# add : a -> a -> a
instance : Add Nat where
add := Nat.add
# end Ex
```
Then for `n : Nat` and `m : Nat`, the term `Add.add n m` triggers typeclass resolution with the goal
of `Add Nat`, and typeclass resolution will synthesize the instance above. In
general, instances may depend on other instances in complicated ways. For example,
you can declare an (anonymous) instance stating that if `a` has addition, then `Array a`
has addition:
```lean
instance [Add a] : Add (Array a) where
add x y := Array.zipWith x y (· + ·)
#eval Add.add #[1, 2] #[3, 4]
-- #[4, 6]
#eval #[1, 2] + #[3, 4]
-- #[4, 6]
```
Note that `x + y` is notation for `Add.add x y` in Lean.
The example above demonstrates how type classes are used to overload notation.
Now, we explore another application. We often need an arbitrary element of a given type.
Recall that types may not have any elements in Lean.
It often happens that we would like a definition to return an arbitrary element in a "corner case."
For example, we may like the expression ``head xs`` to be of type ``a`` when ``xs`` is of type ``List a``.
Similarly, many theorems hold under the additional assumption that a type is not empty.
For example, if ``a`` is a type, ``exists x : a, x = x`` is true only if ``a`` is not empty.
The standard library defines a type class ``Inhabited`` to enable type class inference to infer a
"default" or "arbitrary" element of an inhabited type.
Let us start with the first step of the program above, declaring an appropriate class:
```lean
# namespace Ex
class Inhabited (a : Sort u) where
default : a
#check @Inhabited.default
-- Inhabited.default : {a : Sort u} → [self : Inhabited a] → a
# end Ex
```
Note `Inhabited.default` doesn't have any explicit argument.
An element of the class ``Inhabited a`` is simply an expression of the form ``Inhabited.mk x``, for some element ``x : a``.
The projection ``Inhabited.default`` will allow us to "extract" such an element of ``a`` from an element of ``Inhabited a``.
Now we populate the class with some instances:
```lean
# namespace Ex
# class Inhabited (a : Sort _) where
# default : a
instance : Inhabited Bool where
default := true
instance : Inhabited Nat where
default := 0
instance : Inhabited Unit where
default := ()
instance : Inhabited Prop where
default := True
#eval (Inhabited.default : Nat)
-- 0
#eval (Inhabited.default : Bool)
-- true
# end Ex
```
You can use the command `export` to create the alias `default` for `Inhabited.default`
```lean
# namespace Ex
# class Inhabited (a : Sort _) where
# default : a
# instance : Inhabited Bool where
# default := true
# instance : Inhabited Nat where
# default := 0
# instance : Inhabited Unit where
# default := ()
# instance : Inhabited Prop where
# default := True
export Inhabited (default)
#eval (default : Nat)
-- 0
#eval (default : Bool)
-- true
# end Ex
```
## Chaining Instances
If that were the extent of type class inference, it would not be all that impressive;
it would be simply a mechanism of storing a list of instances for the elaborator to find in a lookup table.
What makes type class inference powerful is that one can *chain* instances. That is,
an instance declaration can in turn depend on an implicit instance of a type class.
This causes class inference to chain through instances recursively, backtracking when necessary, in a Prolog-like search.
For example, the following definition shows that if two types ``a`` and ``b`` are inhabited, then so is their product:
```lean
instance [Inhabited a] [Inhabited b] : Inhabited (a × b) where
default := (default, default)
```
With this added to the earlier instance declarations, type class instance can infer, for example, a default element of ``Nat × Bool``:
```lean
# namespace Ex
# class Inhabited (a : Sort u) where
# default : a
# instance : Inhabited Bool where
# default := true
# instance : Inhabited Nat where
# default := 0
# opaque default [Inhabited a] : a :=
# Inhabited.default
instance [Inhabited a] [Inhabited b] : Inhabited (a × b) where
default := (default, default)
#eval (default : Nat × Bool)
-- (0, true)
# end Ex
```
Similarly, we can inhabit type function with suitable constant functions:
```lean
# namespace Ex
# class Inhabited (a : Sort u) where
# default : a
# opaque default [Inhabited a] : a :=
# Inhabited.default
instance [Inhabited b] : Inhabited (a -> b) where
default := fun _ => default
# end Ex
```
As an exercise, try defining default instances for other types, such as `List` and `Sum` types.
The Lean standard library contains the definition `inferInstance`. It has type `{α : Sort u} → [i : α] → α`,
and is useful for triggering the type class resolution procedure when the expected type is an instance.
```lean
#check (inferInstance : Inhabited Nat) -- Inhabited Nat
def foo : Inhabited (Nat × Nat) :=
inferInstance
theorem ex : foo.default = (default, default) :=
rfl
```
You can use the command `#print` to inspect how simple `inferInstance` is.
```lean
#print inferInstance
```
## ToString
The polymorphic method `toString` has type `{α : Type u} → [ToString α] → α → String`. You implement the instance
for your own types and use chaining to convert complex values into strings. Lean comes with `ToString` instances
for most builtin types.
```lean
structure Person where
name : String
age : Nat
instance : ToString Person where
toString p := p.name ++ "@" ++ toString p.age
#eval toString { name := "Leo", age := 542 : Person }
#eval toString ({ name := "Daniel", age := 18 : Person }, "hello")
```
## Numerals
Numerals are polymorphic in Lean. You can use a numeral (e.g., `2`) to denote an element of any type that implements
the type class `OfNat`.
```lean
structure Rational where
num : Int
den : Nat
inv : den ≠ 0
instance : OfNat Rational n where
ofNat := { num := n, den := 1, inv := by decide }
instance : ToString Rational where
toString r := s!"{r.num}/{r.den}"
#eval (2 : Rational) -- 2/1
#check (2 : Rational) -- Rational
#check (2 : Nat) -- Nat
```
Lean elaborate the terms `(2 : Nat)` and `(2 : Rational)` as
`OfNat.ofNat Nat 2 (instOfNatNat 2)` and
`OfNat.ofNat Rational 2 (instOfNatRational 2)` respectively.
We say the numerals `2` occurring in the elaborated terms are *raw* natural numbers.
You can input the raw natural number `2` using the macro `nat_lit 2`.
```lean
#check nat_lit 2 -- Nat
```
Raw natural numbers are *not* polymorphic.
The `OfNat` instance is parametric on the numeral. So, you can define instances for particular numerals.
The second argument is often a variable as in the example above, or a *raw* natural number.
```lean
class Monoid (α : Type u) where
unit : α
op : ααα
instance [s : Monoid α] : OfNat α (nat_lit 1) where
ofNat := s.unit
def getUnit [Monoid α] : α :=
1
```
Because many users were forgetting the `nat_lit` when defining `OfNat` instances, Lean also accepts `OfNat` instance
declarations not using `nat_lit`. Thus, the following is also accepted.
```lean
class Monoid (α : Type u) where
unit : α
op : ααα
instance [s : Monoid α] : OfNat α 1 where
ofNat := s.unit
def getUnit [Monoid α] : α :=
1
```
## Output parameters
By default, Lean only tries to synthesize an instance `Inhabited T` when the term `T` is known and does not
contain missing parts. The following command produces the error
"failed to create type class instance for `Inhabited (Nat × ?m.1499)`" because the type has a missing part (i.e., the `_`).
```lean
# -- FIXME: should fail
#check (inferInstance : Inhabited (Nat × _))
```
You can view the parameter of the type class `Inhabited` as an *input* value for the type class synthesizer.
When a type class has multiple parameters, you can mark some of them as output parameters.
Lean will start type class synthesizer even when these parameters have missing parts.
In the following example, we use output parameters to define a *heterogeneous* polymorphic
multiplication.
```lean
# namespace Ex
class HMul (α : Type u) (β : Type v) (γ : outParam (Type w)) where
hMul : α → β → γ
export HMul (hMul)
instance : HMul Nat Nat Nat where
hMul := Nat.mul
instance : HMul Nat (Array Nat) (Array Nat) where
hMul a bs := bs.map (fun b => hMul a b)
#eval hMul 4 3 -- 12
#eval hMul 4 #[2, 3, 4] -- #[8, 12, 16]
# end Ex
```
The parameters `α` and `β` are considered input parameters and `γ` an output one.
Given an application `hMul a b`, after types of `a` and `b` are known, the type class
synthesizer is invoked, and the resulting type is obtained from the output parameter `γ`.
In the example above, we defined two instances. The first one is the homogeneous
multiplication for natural numbers. The second is the scalar multiplication for arrays.
Note that, you chain instances and generalize the second instance.
```lean
# namespace Ex
class HMul (α : Type u) (β : Type v) (γ : outParam (Type w)) where
hMul : α → β → γ
export HMul (hMul)
instance : HMul Nat Nat Nat where
hMul := Nat.mul
instance : HMul Int Int Int where
hMul := Int.mul
instance [HMul α β γ] : HMul α (Array β) (Array γ) where
hMul a bs := bs.map (fun b => hMul a b)
#eval hMul 4 3 -- 12
#eval hMul 4 #[2, 3, 4] -- #[8, 12, 16]
#eval hMul (-2) #[3, -1, 4] -- #[-6, 2, -8]
#eval hMul 2 #[#[2, 3], #[0, 4]] -- #[#[4, 6], #[0, 8]]
# end Ex
```
You can use our new scalar array multiplication instance on arrays of type `Array β`
with a scalar of type `α` whenever you have an instance `HMul α β γ`.
In the last `#eval`, note that the instance was used twice on an array of arrays.
## Default instances
In the class `HMul`, the parameters `α` and `β` are treated as input values.
Thus, type class synthesis only starts after these two types are known. This may often
be too restrictive.
```lean
# namespace Ex
class HMul (α : Type u) (β : Type v) (γ : outParam (Type w)) where
hMul : α → β → γ
export HMul (hMul)
instance : HMul Int Int Int where
hMul := Int.mul
def xs : List Int := [1, 2, 3]
# -- TODO: fix error message
-- Error "failed to create type class instance for HMul Int ?m.1767 (?m.1797 x)"
-- #check fun y => xs.map (fun x => hMul x y)
# end Ex
```
The instance `HMul` is not synthesized by Lean because the type of `y` has not been provided.
However, it is natural to assume that the type of `y` and `x` should be the same in
this kind of situation. We can achieve exactly that using *default instances*.
```lean
# namespace Ex
class HMul (α : Type u) (β : Type v) (γ : outParam (Type w)) where
hMul : α → β → γ
export HMul (hMul)
@[default_instance]
instance : HMul Int Int Int where
hMul := Int.mul
def xs : List Int := [1, 2, 3]
#check fun y => xs.map (fun x => hMul x y) -- Int -> List Int
# end Ex
```
By tagging the instance above with the attribute `default_instance`, we are instructing Lean
to use this instance on pending type class synthesis problems.
The actual Lean implementation defines homogeneous and heterogeneous classes for arithmetical operators.
Moreover, `a+b`, `a*b`, `a-b`, `a/b`, and `a%b` are notations for the heterogeneous versions.
The instance `OfNat Nat n` is the default instance (with priority `100`) for the `OfNat` class. This is why the numeral
`2` has type `Nat` when the expected type is not known. You can define default instances with higher
priority to override the builtin ones.
```lean
structure Rational where
num : Int
den : Nat
inv : den ≠ 0
@[default_instance 200]
instance : OfNat Rational n where
ofNat := { num := n, den := 1, inv := by decide }
instance : ToString Rational where
toString r := s!"{r.num}/{r.den}"
#check 2 -- Rational
```
Priorities are also useful to control the interaction between different default instances.
For example, suppose `xs` has type `α`, when elaboration `xs.map (fun x => 2 * x)`, we want the homogeneous instance for multiplication
to have higher priority than the default instance for `OfNat`. This is particularly important when we have implemented only the instance
`HMul α α α`, and did not implement `HMul Nat α α`.
Now, we reveal how the notation `a*b` is defined in Lean.
```lean
# namespace Ex
class OfNat (α : Type u) (n : Nat) where
ofNat : α
@[default_instance]
instance (n : Nat) : OfNat Nat n where
ofNat := n
class HMul (α : Type u) (β : Type v) (γ : outParam (Type w)) where
hMul : α → β → γ
class Mul (α : Type u) where
mul : ααα
@[default_instance 10]
instance [Mul α] : HMul α α α where
hMul a b := Mul.mul a b
infixl:70 " * " => HMul.hMul
# end Ex
```
The `Mul` class is convenient for types that only implement the homogeneous multiplication.
## Scoped Instances
TODO
## Local Instances
TODO

View File

@@ -1 +0,0 @@
# Fixed precision unsigned integers

View File

@@ -1,5 +0,0 @@
# Unification Hints
TODO

28
flake.lock generated
View File

@@ -36,17 +36,17 @@
},
"nixpkgs-cadical": {
"locked": {
"lastModified": 1722221733,
"narHash": "sha256-sga9SrrPb+pQJxG1ttJfMPheZvDOxApFfwXCFO0H9xw=",
"lastModified": 1740791350,
"narHash": "sha256-igS2Z4tVw5W/x3lCZeeadt0vcU9fxtetZ/RyrqsCRQ0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "12bf09802d77264e441f48e25459c10c93eada2e",
"rev": "199169a2135e6b864a888e89a2ace345703c025d",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "12bf09802d77264e441f48e25459c10c93eada2e",
"rev": "199169a2135e6b864a888e89a2ace345703c025d",
"type": "github"
}
},
@@ -67,12 +67,30 @@
"type": "github"
}
},
"nixpkgs-older": {
"flake": false,
"locked": {
"lastModified": 1523316493,
"narHash": "sha256-5qJS+i5ECICPAKA6FhPLIWkhPKDnOZsZbh2PHYF1Kbs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "0b307aa73804bbd7a7172899e59ae0b8c347a62d",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "0b307aa73804bbd7a7172899e59ae0b8c347a62d",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"nixpkgs-cadical": "nixpkgs-cadical",
"nixpkgs-old": "nixpkgs-old"
"nixpkgs-old": "nixpkgs-old",
"nixpkgs-older": "nixpkgs-older"
}
},
"systems": {

View File

@@ -5,17 +5,20 @@
# old nixpkgs used for portable release with older glibc (2.27)
inputs.nixpkgs-old.url = "github:NixOS/nixpkgs/nixos-19.03";
inputs.nixpkgs-old.flake = false;
# for cadical 1.9.5; sync with CMakeLists.txt
inputs.nixpkgs-cadical.url = "github:NixOS/nixpkgs/12bf09802d77264e441f48e25459c10c93eada2e";
# old nixpkgs used for portable release with older glibc (2.26)
inputs.nixpkgs-older.url = "github:NixOS/nixpkgs/0b307aa73804bbd7a7172899e59ae0b8c347a62d";
inputs.nixpkgs-older.flake = false;
# for cadical 2.1.2; sync with CMakeLists.txt by taking commit from https://www.nixhub.io/packages/cadical
inputs.nixpkgs-cadical.url = "github:NixOS/nixpkgs/199169a2135e6b864a888e89a2ace345703c025d";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, nixpkgs, nixpkgs-old, flake-utils, ... }@inputs: flake-utils.lib.eachDefaultSystem (system:
outputs = inputs: inputs.flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
pkgs = import inputs.nixpkgs { inherit system; };
# An old nixpkgs for creating releases with an old glibc
pkgsDist-old = import nixpkgs-old { inherit system; };
pkgsDist-old = import inputs.nixpkgs-older { inherit system; };
# An old nixpkgs for creating releases with an old glibc
pkgsDist-old-aarch = import nixpkgs-old { localSystem.config = "aarch64-unknown-linux-gnu"; };
pkgsDist-old-aarch = import inputs.nixpkgs-old { localSystem.config = "aarch64-unknown-linux-gnu"; };
pkgsCadical = import inputs.nixpkgs-cadical { inherit system; };
cadical = if pkgs.stdenv.isLinux then
# use statically-linked cadical on Linux to avoid glibc versioning troubles
@@ -28,7 +31,7 @@
stdenv = pkgs.overrideCC pkgs.stdenv lean-packages.llvmPackages.clang;
} ({
buildInputs = with pkgs; [
cmake gmp libuv ccache cadical
cmake gmp libuv ccache cadical pkg-config
lean-packages.llvmPackages.llvm # llvm-symbolizer for asan/lsan
gdb
tree # for CI
@@ -38,12 +41,29 @@
# more convenient `ctest` output
CTEST_OUTPUT_ON_FAILURE = 1;
} // pkgs.lib.optionalAttrs pkgs.stdenv.isLinux {
GMP = pkgsDist.gmp.override { withStatic = true; };
LIBUV = pkgsDist.libuv.overrideAttrs (attrs: { configureFlags = ["--enable-static"]; });
GMP = (pkgsDist.gmp.override { withStatic = true; }).overrideAttrs (attrs:
pkgs.lib.optionalAttrs (pkgs.stdenv.system == "aarch64-linux") {
# would need additional linking setup on Linux aarch64, we don't use it anywhere else either
hardeningDisable = [ "stackprotector" ];
});
LIBUV = pkgsDist.libuv.overrideAttrs (attrs: {
configureFlags = ["--enable-static"];
hardeningDisable = [ "stackprotector" ];
# Sync version with CMakeLists.txt
version = "1.48.0";
src = pkgs.fetchFromGitHub {
owner = "libuv";
repo = "libuv";
rev = "v1.48.0";
sha256 = "100nj16fg8922qg4m2hdjh62zv4p32wyrllsvqr659hdhjc03bsk";
};
doCheck = false;
});
GLIBC = pkgsDist.glibc;
GLIBC_DEV = pkgsDist.glibc.dev;
GCC_LIB = pkgsDist.gcc.cc.lib;
ZLIB = pkgsDist.zlib;
# for CI coredumps
GDB = pkgsDist.gdb;
});
in {

View File

@@ -1,12 +1,12 @@
{ src, debug ? false, stage0debug ? false, extraCMakeFlags ? [],
stdenv, lib, cmake, gmp, libuv, cadical, git, gnumake, bash, buildLeanPackage, writeShellScriptBin, runCommand, symlinkJoin, lndir, perl, gnused, darwin, llvmPackages, linkFarmFromDrvs,
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 ];
nativeBuildInputs = [ cmake pkg-config ];
buildInputs = [ gmp libuv llvmPackages.llvm ];
# https://github.com/NixOS/nixpkgs/issues/60919
hardeningDisable = [ "all" ];
@@ -170,7 +170,7 @@ lib.warn "The Nix-based build is deprecated" rec {
ln -sf ${lean-all}/* .
'';
buildPhase = ''
ctest --output-junit test-results.xml --output-on-failure -E 'leancomptest_(doc_example|foreign)|leanlaketest_reverse-ffi' -j$NIX_BUILD_CORES
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

292
releases/v4.0.0-m4.md Normal file
View File

@@ -0,0 +1,292 @@
v4.0.0-m4 (23 March 2022)
---------
* `simp` now takes user-defined simp-attributes. You can define a new `simp` attribute by creating a file (e.g., `MySimp.lean`) containing
```lean
import Lean
open Lean.Meta
initialize my_ext : SimpExtension ← registerSimpAttr `my_simp "my own simp attribute"
```
If you don't need to access `my_ext`, you can also use the macro
```lean
import Lean
register_simp_attr my_simp "my own simp attribute"
```
Recall that the new `simp` attribute is not active in the Lean file where it was defined.
Here is a small example using the new feature.
```lean
import MySimp
def f (x : Nat) := x + 2
def g (x : Nat) := x + 1
@[my_simp] theorem f_eq : f x = x + 2 := rfl
@[my_simp] theorem g_eq : g x = x + 1 := rfl
example : f x + g x = 2*x + 3 := by
simp_arith [my_simp]
```
* Extend `match` syntax: multiple left-hand-sides in a single alternative. Example:
```lean
def fib : Nat → Nat
| 0 | 1 => 1
| n+2 => fib n + fib (n+1)
```
This feature was discussed at [issue 371](https://github.com/leanprover/lean4/issues/371). It was implemented as a macro expansion. Thus, the following is accepted.
```lean
inductive StrOrNum where
| S (s : String)
| I (i : Int)
def StrOrNum.asString (x : StrOrNum) :=
match x with
| I a | S a => toString a
```
* Improve `#eval` command. Now, when it fails to synthesize a `Lean.MetaEval` instance for the result type, it reduces the type and tries again. The following example now works without additional annotations
```lean
def Foo := List Nat
def test (x : Nat) : Foo :=
[x, x+1, x+2]
#eval test 4
```
* `rw` tactic can now apply auto-generated equation theorems for a given definition. Example:
```lean
example (a : Nat) (h : n = 1) : [a].length = n := by
rw [List.length]
trace_state -- .. |- [].length + 1 = n
rw [List.length]
trace_state -- .. |- 0 + 1 = n
rw [h]
```
* [Fuzzy matching for auto completion](https://github.com/leanprover/lean4/pull/1023)
* Extend dot-notation `x.field` for arrow types. If type of `x` is an arrow, we look up for `Function.field`.
For example, given `f : Nat → Nat` and `g : Nat → Nat`, `f.comp g` is now notation for `Function.comp f g`.
* The new `.<identifier>` notation is now also accepted where a function type is expected.
```lean
example (xs : List Nat) : List Nat := .map .succ xs
example (xs : List α) : Std.RBTree α ord := xs.foldl .insert ∅
```
* [Add code folding support to the language server](https://github.com/leanprover/lean4/pull/1014).
* Support notation `let <pattern> := <expr> | <else-case>` in `do` blocks.
* Remove support for "auto" `pure`. In the [Zulip thread](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/for.2C.20unexpected.20need.20for.20type.20ascription/near/269083574), the consensus seemed to be that "auto" `pure` is more confusing than it's worth.
* Remove restriction in `congr` theorems that all function arguments on the left-hand-side must be free variables. For example, the following theorem is now a valid `congr` theorem.
```lean
@[congr]
theorem dep_congr [DecidableEq ι] {p : ι → Set α} [∀ i, Inhabited (p i)] :
∀ {i j} (h : i = j) (x : p i) (y : α) (hx : x = y), Pi.single (f := (p ·)) i x = Pi.single (f := (p ·)) j ⟨y, hx ▸ h ▸ x.2⟩ :=
```
* [Partially applied congruence theorems.](https://github.com/leanprover/lean4/issues/988)
* Improve elaboration postponement heuristic when expected type is a metavariable. Lean now reduces the expected type before performing the test.
* [Remove deprecated leanpkg](https://github.com/leanprover/lean4/pull/985) in favor of [Lake](https://github.com/leanprover/lake) now bundled with Lean.
* Various improvements to go-to-definition & find-all-references accuracy.
* Auto generated congruence lemmas with support for casts on proofs and `Decidable` instances (see [wishlist](https://github.com/leanprover/lean4/issues/988)).
* Rename option `autoBoundImplicitLocal` => `autoImplicit`.
* [Relax auto-implicit restrictions](https://github.com/leanprover/lean4/pull/1011). The command `set_option relaxedAutoImplicit false` disables the relaxations.
* `contradiction` tactic now closes the goal if there is a `False.elim` application in the target.
* Renamed tatic `byCases` => `by_cases` (motivation: enforcing naming convention).
* Local instances occurring in patterns are now considered by the type class resolution procedure. Example:
```lean
def concat : List ((α : Type) × ToString α × α) → String
| [] => ""
| ⟨_, _, a⟩ :: as => toString a ++ concat as
```
* Notation for providing the motive for `match` expressions has changed.
before:
```lean
match x, rfl : (y : Nat) → x = y → Nat with
| 0, h => ...
| x+1, h => ...
```
now:
```lean
match (motive := (y : Nat) → x = y → Nat) x, rfl with
| 0, h => ...
| x+1, h => ...
```
With this change, the notation for giving names to equality proofs in `match`-expressions is not whitespace sensitive anymore. That is,
we can now write
```lean
match h : sort.swap a b with
| (r₁, r₂) => ... -- `h : sort.swap a b = (r₁, r₂)`
```
* `(generalizing := true)` is the default behavior for `match` expressions even if the expected type is not a proposition. In the following example, we used to have to include `(generalizing := true)` manually.
```lean
inductive Fam : Type → Type 1 where
| any : Fam α
| nat : Nat → Fam Nat
example (a : α) (x : Fam α) : α :=
match x with
| Fam.any => a
| Fam.nat n => n
```
* We now use `PSum` (instead of `Sum`) when compiling mutually recursive definitions using well-founded recursion.
* Better support for parametric well-founded relations. See [issue #1017](https://github.com/leanprover/lean4/issues/1017). This change affects the low-level `termination_by'` hint because the fixed prefix of the function parameters in not "packed" anymore when constructing the well-founded relation type. For example, in the following definition, `as` is part of the fixed prefix, and is not packed anymore. In previous versions, the `termination_by'` term would be written as `measure fun ⟨as, i, _⟩ => as.size - i`
```lean
def sum (as : Array Nat) (i : Nat) (s : Nat) : Nat :=
if h : i < as.size then
sum as (i+1) (s + as.get ⟨i, h⟩)
else
s
termination_by' measure fun ⟨i, _⟩ => as.size - i
```
* Add `while <cond> do <do-block>`, `repeat <do-block>`, and `repeat <do-block> until <cond>` macros for `do`-block. These macros are based on `partial` definitions, and consequently are useful only for writing programs we don't want to prove anything about.
* Add `arith` option to `Simp.Config`, the macro `simp_arith` expands to `simp (config := { arith := true })`. Only `Nat` and linear arithmetic is currently supported. Example:
```lean
example : 0 < 1 + x ∧ x + y + 2 ≥ y + 1 := by
simp_arith
```
* Add `fail <string>?` tactic that always fail.
* Add support for acyclicity at dependent elimination. See [issue #1022](https://github.com/leanprover/lean4/issues/1022).
* Add `trace <string>` tactic for debugging purposes.
* Add nontrivial `SizeOf` instance for types `Unit → α`, and add support for them in the auto-generated `SizeOf` instances for user-defined inductive types. For example, given the inductive datatype
```lean
inductive LazyList (α : Type u) where
| nil : LazyList α
| cons (hd : α) (tl : LazyList α) : LazyList α
| delayed (t : Thunk (LazyList α)) : LazyList α
```
we now have `sizeOf (LazyList.delayed t) = 1 + sizeOf t` instead of `sizeOf (LazyList.delayed t) = 2`.
* Add support for guessing (very) simple well-founded relations when proving termination. For example, the following function does not require a `termination_by` annotation anymore.
```lean
def Array.insertAtAux (i : Nat) (as : Array α) (j : Nat) : Array α :=
if h : i < j then
let as := as.swap! (j-1) j;
insertAtAux i as (j-1)
else
as
```
* Add support for `for h : x in xs do ...` notation where `h : x ∈ xs`. This is mainly useful for showing termination.
* Auto implicit behavior changed for inductive families. An auto implicit argument occurring in inductive family index is also treated as an index (IF it is not fixed, see next item). For example
```lean
inductive HasType : Index n → Vector Ty n → Ty → Type where
```
is now interpreted as
```lean
inductive HasType : {n : Nat} → Index n → Vector Ty n → Ty → Type where
```
* To make the previous feature more convenient to use, we promote a fixed prefix of inductive family indices to parameters. For example, the following declaration is now accepted by Lean
```lean
inductive Lst : Type u → Type u
| nil : Lst α
| cons : α → Lst α → Lst α
```
and `α` in `Lst α` is a parameter. The actual number of parameters can be inspected using the command `#print Lst`. This feature also makes sure we still accept the declaration
```lean
inductive Sublist : List α → List α → Prop
| slnil : Sublist [] []
| cons l₁ l₂ a : Sublist l₁ l₂ → Sublist l₁ (a :: l₂)
| cons2 l₁ l₂ a : Sublist l₁ l₂ → Sublist (a :: l₁) (a :: l₂)
```
* Added auto implicit "chaining". Unassigned metavariables occurring in the auto implicit types now become new auto implicit locals. Consider the following example:
```lean
inductive HasType : Fin n → Vector Ty n → Ty → Type where
| stop : HasType 0 (ty :: ctx) ty
| pop : HasType k ctx ty → HasType k.succ (u :: ctx) ty
```
`ctx` is an auto implicit local in the two constructors, and it has type `ctx : Vector Ty ?m`. Without auto implicit "chaining", the metavariable `?m` will remain unassigned. The new feature creates yet another implicit local `n : Nat` and assigns `n` to `?m`. So, the declaration above is shorthand for
```lean
inductive HasType : {n : Nat} → Fin n → Vector Ty n → Ty → Type where
| stop : {ty : Ty} → {n : Nat} → {ctx : Vector Ty n} → HasType 0 (ty :: ctx) ty
| pop : {n : Nat} → {k : Fin n} → {ctx : Vector Ty n} → {ty : Ty} → HasType k ctx ty → HasType k.succ (u :: ctx) ty
```
* Eliminate auxiliary type annotations (e.g, `autoParam` and `optParam`) from recursor minor premises and projection declarations. Consider the following example
```lean
structure A :=
x : Nat
h : x = 1 := by trivial
example (a : A) : a.x = 1 := by
have aux := a.h
-- `aux` has now type `a.x = 1` instead of `autoParam (a.x = 1) auto✝`
exact aux
example (a : A) : a.x = 1 := by
cases a with
| mk x h =>
-- `h` has now type `x = 1` instead of `autoParam (x = 1) auto✝`
assumption
```
* We now accept overloaded notation in patterns, but we require the set of pattern variables in each alternative to be the same. Example:
```lean
inductive Vector (α : Type u) : Nat → Type u
| nil : Vector α 0
| cons : α → Vector α n → Vector α (n+1)
infix:67 " :: " => Vector.cons -- Overloading the `::` notation
def head1 (x : List α) (h : x ≠ []) : α :=
match x with
| a :: as => a -- `::` is `List.cons` here
def head2 (x : Vector α (n+1)) : α :=
match x with
| a :: as => a -- `::` is `Vector.cons` here
```
* New notation `.<identifier>` based on Swift. The namespace is inferred from the expected type. See [issue #944](https://github.com/leanprover/lean4/issues/944). Examples:
```lean
def f (x : Nat) : Except String Nat :=
if x > 0 then
.ok x
else
.error "x is zero"
namespace Lean.Elab
open Lsp
def identOf : Info → Option (RefIdent × Bool)
| .ofTermInfo ti => match ti.expr with
| .const n .. => some (.const n, ti.isBinder)
| .fvar id .. => some (.fvar id, ti.isBinder)
| _ => none
| .ofFieldInfo fi => some (.const fi.projName, false)
| _ => none
def isImplicit (bi : BinderInfo) : Bool :=
bi matches .implicit
end Lean.Elab
```

715
releases/v4.0.0-m5.md Normal file
View File

@@ -0,0 +1,715 @@
v4.0.0-m5 (07 August 2022)
---------
* Update Lake to v4.0.0. See the [v4.0.0 release notes](https://github.com/leanprover/lake/releases/tag/v4.0.0) for detailed changes.
* Mutual declarations in different namespaces are now supported. Example:
```lean
mutual
def Foo.boo (x : Nat) :=
match x with
| 0 => 1
| x + 1 => 2*Boo.bla x
def Boo.bla (x : Nat) :=
match x with
| 0 => 2
| x+1 => 3*Foo.boo x
end
```
A `namespace` is automatically created for the common prefix. Example:
```lean
mutual
def Tst.Foo.boo (x : Nat) := ...
def Tst.Boo.bla (x : Nat) := ...
end
```
expands to
```lean
namespace Tst
mutual
def Foo.boo (x : Nat) := ...
def Boo.bla (x : Nat) := ...
end
end Tst
```
* Allow users to install their own `deriving` handlers for existing type classes.
See example at [Simple.lean](https://github.com/leanprover/lean4/blob/master/tests/pkg/deriving/UserDeriving/Simple.lean).
* Add tactic `congr (num)?`. See doc string for additional details.
* [Missing doc linter](https://github.com/leanprover/lean4/pull/1390)
* `match`-syntax notation now checks for unused alternatives. See issue [#1371](https://github.com/leanprover/lean4/issues/1371).
* Auto-completion for structure instance fields. Example:
```lean
example : Nat × Nat := {
f -- HERE
}
```
`fst` now appears in the list of auto-completion suggestions.
* Auto-completion for dotted identifier notation. Example:
```lean
example : Nat :=
.su -- HERE
```
`succ` now appears in the list of auto-completion suggestions.
* `nat_lit` is not needed anymore when declaring `OfNat` instances. See issues [#1389](https://github.com/leanprover/lean4/issues/1389) and [#875](https://github.com/leanprover/lean4/issues/875). Example:
```lean
inductive Bit where
| zero
| one
instance inst0 : OfNat Bit 0 where
ofNat := Bit.zero
instance : OfNat Bit 1 where
ofNat := Bit.one
example : Bit := 0
example : Bit := 1
```
* Add `[elabAsElim]` attribute (it is called `elab_as_eliminator` in Lean 3). Motivation: simplify the Mathlib port to Lean 4.
* `Trans` type class now accepts relations in `Type u`. See this [Zulip issue](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Calc.20mode/near/291214574).
* Accept unescaped keywords as inductive constructor names. Escaping can often be avoided at use sites via dot notation.
```lean
inductive MyExpr
| let : ...
def f : MyExpr → MyExpr
| .let ... => .let ...
```
* Throw an error message at parametric local instances such as `[Nat -> Decidable p]`. The type class resolution procedure
cannot use this kind of local instance because the parameter does not have a forward dependency.
This check can be disabled using `set_option checkBinderAnnotations false`.
* Add option `pp.showLetValues`. When set to `false`, the info view hides the value of `let`-variables in a goal.
By default, it is `true` when visualizing tactic goals, and `false` otherwise.
See [issue #1345](https://github.com/leanprover/lean4/issues/1345) for additional details.
* Add option `warningAsError`. When set to true, warning messages are treated as errors.
* Support dotted notation and named arguments in patterns. Example:
```lean
def getForallBinderType (e : Expr) : Expr :=
match e with
| .forallE (binderType := type) .. => type
| _ => panic! "forall expected"
```
* "jump-to-definition" now works for function names embedded in the following attributes
`@[implementedBy funName]`, `@[tactic parserName]`, `@[termElab parserName]`, `@[commandElab parserName]`,
`@[builtinTactic parserName]`, `@[builtinTermElab parserName]`, and `@[builtinCommandElab parserName]`.
See [issue #1350](https://github.com/leanprover/lean4/issues/1350).
* Improve `MVarId` methods discoverability. See [issue #1346](https://github.com/leanprover/lean4/issues/1346).
We still have to add similar methods for `FVarId`, `LVarId`, `Expr`, and other objects.
Many existing methods have been marked as deprecated.
* Add attribute `[deprecated]` for marking deprecated declarations. Examples:
```lean
def g (x : Nat) := x + 1
-- Whenever `f` is used, a warning message is generated suggesting to use `g` instead.
@[deprecated g]
def f (x : Nat) := x + 1
#check f 0 -- warning: `f` has been deprecated, use `g` instead
-- Whenever `h` is used, a warning message is generated.
@[deprecated]
def h (x : Nat) := x + 1
#check h 0 -- warning: `h` has been deprecated
```
* Add type `LevelMVarId` (and abbreviation `LMVarId`) for universe level metavariable ids.
Motivation: prevent meta-programmers from mixing up universe and expression metavariable ids.
* Improve `calc` term and tactic. See [issue #1342](https://github.com/leanprover/lean4/issues/1342).
* [Relaxed antiquotation parsing](https://github.com/leanprover/lean4/pull/1272) further reduces the need for explicit `$x:p` antiquotation kind annotations.
* Add support for computed fields in inductives. Example:
```lean
inductive Exp
| var (i : Nat)
| app (a b : Exp)
with
@[computedField] hash : Exp → Nat
| .var i => i
| .app a b => a.hash * b.hash + 1
```
The result of the `Exp.hash` function is then stored as an extra "computed" field in the `.var` and `.app` constructors;
`Exp.hash` accesses this field and thus runs in constant time (even on dag-like values).
* Update `a[i]` notation. It is now based on the typeclass
```lean
class GetElem (cont : Type u) (idx : Type v) (elem : outParam (Type w)) (dom : outParam (cont → idx → Prop)) where
getElem (xs : cont) (i : idx) (h : dom xs i) : Elem
```
The notation `a[i]` is now defined as follows
```lean
macro:max x:term noWs "[" i:term "]" : term => `(getElem $x $i (by get_elem_tactic))
```
The proof that `i` is a valid index is synthesized using the tactic `get_elem_tactic`.
For example, the type `Array α` has the following instances
```lean
instance : GetElem (Array α) Nat α fun xs i => LT.lt i xs.size where ...
instance : GetElem (Array α) USize α fun xs i => LT.lt i.toNat xs.size where ...
```
You can use the notation `a[i]'h` to provide the proof manually.
Two other notations were introduced: `a[i]!` and `a[i]?`, For `a[i]!`, a panic error message is produced at
runtime if `i` is not a valid index. `a[i]?` has type `Option α`, and `a[i]?` evaluates to `none` if the
index `i` is not valid.
The three new notations are defined as follows:
```lean
@[inline] def getElem' [GetElem cont idx elem dom] (xs : cont) (i : idx) (h : dom xs i) : elem :=
getElem xs i h
@[inline] def getElem! [GetElem cont idx elem dom] [Inhabited elem] (xs : cont) (i : idx) [Decidable (dom xs i)] : elem :=
if h : _ then getElem xs i h else panic! "index out of bounds"
@[inline] def getElem? [GetElem cont idx elem dom] (xs : cont) (i : idx) [Decidable (dom xs i)] : Option elem :=
if h : _ then some (getElem xs i h) else none
macro:max x:term noWs "[" i:term "]" noWs "?" : term => `(getElem? $x $i)
macro:max x:term noWs "[" i:term "]" noWs "!" : term => `(getElem! $x $i)
macro x:term noWs "[" i:term "]'" h:term:max : term => `(getElem' $x $i $h)
```
See discussion on [Zulip](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/String.2EgetOp/near/287855425).
Examples:
```lean
example (a : Array Int) (i : Nat) : Int :=
a[i] -- Error: failed to prove index is valid ...
example (a : Array Int) (i : Nat) (h : i < a.size) : Int :=
a[i] -- Ok
example (a : Array Int) (i : Nat) : Int :=
a[i]! -- Ok
example (a : Array Int) (i : Nat) : Option Int :=
a[i]? -- Ok
example (a : Array Int) (h : a.size = 2) : Int :=
a[0]'(by rw [h]; decide) -- Ok
example (a : Array Int) (h : a.size = 2) : Int :=
have : 0 < a.size := by rw [h]; decide
have : 1 < a.size := by rw [h]; decide
a[0] + a[1] -- Ok
example (a : Array Int) (i : USize) (h : i.toNat < a.size) : Int :=
a[i] -- Ok
```
The `get_elem_tactic` is defined as
```lean
macro "get_elem_tactic" : tactic =>
`(first
| get_elem_tactic_trivial
| fail "failed to prove index is valid, ..."
)
```
The `get_elem_tactic_trivial` auxiliary tactic can be extended using `macro_rules`. By default, it tries `trivial`, `simp_arith`, and a special case for `Fin`. In the future, it will also try `linarith`.
You can extend `get_elem_tactic_trivial` using `my_tactic` as follows
```lean
macro_rules
| `(tactic| get_elem_tactic_trivial) => `(tactic| my_tactic)
```
Note that `Idx`'s type in `GetElem` does not depend on `Cont`. So, you cannot write the instance `instance : GetElem (Array α) (Fin ??) α fun xs i => ...`, but the Lean library comes equipped with the following auxiliary instance:
```lean
instance [GetElem cont Nat elem dom] : GetElem cont (Fin n) elem fun xs i => dom xs i where
getElem xs i h := getElem xs i.1 h
```
and helper tactic
```lean
macro_rules
| `(tactic| get_elem_tactic_trivial) => `(tactic| apply Fin.val_lt_of_le; get_elem_tactic_trivial; done)
```
Example:
```lean
example (a : Array Nat) (i : Fin a.size) :=
a[i] -- Ok
example (a : Array Nat) (h : n ≤ a.size) (i : Fin n) :=
a[i] -- Ok
```
* Better support for qualified names in recursive declarations. The following is now supported:
```lean
namespace Nat
def fact : Nat → Nat
| 0 => 1
| n+1 => (n+1) * Nat.fact n
end Nat
```
* Add support for `CommandElabM` monad at `#eval`. Example:
```lean
import Lean
open Lean Elab Command
#eval do
let id := mkIdent `foo
elabCommand (← `(def $id := 10))
#eval foo -- 10
```
* Try to elaborate `do` notation even if the expected type is not available. We still delay elaboration when the expected type
is not available. This change is particularly useful when writing examples such as
```lean
#eval do
IO.println "hello"
IO.println "world"
```
That is, we don't have to use the idiom `#eval show IO _ from do ...` anymore.
Note that auto monadic lifting is less effective when the expected type is not available.
Monadic polymorphic functions (e.g., `ST.Ref.get`) also require the expected type.
* On Linux, panics now print a backtrace by default, which can be disabled by setting the environment variable `LEAN_BACKTRACE` to `0`.
Other platforms are TBD.
* The `group(·)` `syntax` combinator is now introduced automatically where necessary, such as when using multiple parsers inside `(...)+`.
* Add ["Typed Macros"](https://github.com/leanprover/lean4/pull/1251): syntax trees produced and accepted by syntax antiquotations now remember their syntax kinds, preventing accidental production of ill-formed syntax trees and reducing the need for explicit `:kind` antiquotation annotations. See PR for details.
* Aliases of protected definitions are protected too. Example:
```lean
protected def Nat.double (x : Nat) := 2*x
namespace Ex
export Nat (double) -- Add alias Ex.double for Nat.double
end Ex
open Ex
#check Ex.double -- Ok
#check double -- Error, `Ex.double` is alias for `Nat.double` which is protected
```
* Use `IO.getRandomBytes` to initialize random seed for `IO.rand`. See discussion at [this PR](https://github.com/leanprover/lean4-samples/pull/2).
* Improve dot notation and aliases interaction. See discussion on [Zulip](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Namespace-based.20overloading.20does.20not.20find.20exports/near/282946185) for additional details.
Example:
```lean
def Set (α : Type) := α → Prop
def Set.union (s₁ s₂ : Set α) : Set α := fun a => s₁ a s₂ a
def FinSet (n : Nat) := Fin n → Prop
namespace FinSet
export Set (union) -- FinSet.union is now an alias for `Set.union`
end FinSet
example (x y : FinSet 10) : FinSet 10 :=
x.union y -- Works
```
* `ext` and `enter` conv tactics can now go inside let-declarations. Example:
```lean
example (g : Nat → Nat) (y : Nat) (h : let x := y + 1; g (0+x) = x) : g (y + 1) = y + 1 := by
conv at h => enter [x, 1, 1]; rw [Nat.zero_add]
/-
g : Nat → Nat
y : Nat
h : let x := y + 1;
g x = x
⊢ g (y + 1) = y + 1
-/
exact h
```
* Add `zeta` conv tactic to expand let-declarations. Example:
```lean
example (h : let x := y + 1; 0 + x = y) : False := by
conv at h => zeta; rw [Nat.zero_add]
/-
y : Nat
h : y + 1 = y
⊢ False
-/
simp_arith at h
```
* Improve namespace resolution. See issue [#1224](https://github.com/leanprover/lean4/issues/1224). Example:
```lean
import Lean
open Lean Parser Elab
open Tactic -- now opens both `Lean.Parser.Tactic` and `Lean.Elab.Tactic`
```
* Rename `constant` command to `opaque`. See discussion at [Zulip](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/What.20is.20.60opaque.60.3F/near/284926171).
* Extend `induction` and `cases` syntax: multiple left-hand-sides in a single alternative. This extension is very similar to the one implemented for `match` expressions. Examples:
```lean
inductive Foo where
| mk1 (x : Nat) | mk2 (x : Nat) | mk3
def f (v : Foo) :=
match v with
| .mk1 x => x + 1
| .mk2 x => 2*x + 1
| .mk3 => 1
theorem f_gt_zero : f v > 0 := by
cases v with
| mk1 x | mk2 x => simp_arith! -- New feature used here!
| mk3 => decide
```
* [`let/if` indentation in `do` blocks in now supported.](https://github.com/leanprover/lean4/issues/1120)
* Add unnamed antiquotation `$_` for use in syntax quotation patterns.
* [Add unused variables linter](https://github.com/leanprover/lean4/pull/1159). Feedback welcome!
* Lean now generates an error if the body of a declaration body contains a universe parameter that does not occur in the declaration type, nor is an explicit parameter.
Examples:
```lean
/-
The following declaration now produces an error because `PUnit` is universe polymorphic,
but the universe parameter does not occur in the function type `Nat → Nat`
-/
def f (n : Nat) : Nat :=
let aux (_ : PUnit) : Nat := n + 1
aux ⟨⟩
/-
The following declaration is accepted because the universe parameter was explicitly provided in the
function signature.
-/
def g.{u} (n : Nat) : Nat :=
let aux (_ : PUnit.{u}) : Nat := n + 1
aux ⟨⟩
```
* Add `subst_vars` tactic.
* [Fix `autoParam` in structure fields lost in multiple inheritance.](https://github.com/leanprover/lean4/issues/1158).
* Add `[eliminator]` attribute. It allows users to specify default recursor/eliminators for the `induction` and `cases` tactics.
It is an alternative for the `using` notation. Example:
```lean
@[eliminator] protected def recDiag {motive : Nat → Nat → Sort u}
(zero_zero : motive 0 0)
(succ_zero : (x : Nat) → motive x 0 → motive (x + 1) 0)
(zero_succ : (y : Nat) → motive 0 y → motive 0 (y + 1))
(succ_succ : (x y : Nat) → motive x y → motive (x + 1) (y + 1))
(x y : Nat) : motive x y :=
let rec go : (x y : Nat) → motive x y
| 0, 0 => zero_zero
| x+1, 0 => succ_zero x (go x 0)
| 0, y+1 => zero_succ y (go 0 y)
| x+1, y+1 => succ_succ x y (go x y)
go x y
termination_by go x y => (x, y)
def f (x y : Nat) :=
match x, y with
| 0, 0 => 1
| x+1, 0 => f x 0
| 0, y+1 => f 0 y
| x+1, y+1 => f x y
termination_by f x y => (x, y)
example (x y : Nat) : f x y > 0 := by
induction x, y <;> simp [f, *]
```
* Add support for `casesOn` applications to structural and well-founded recursion modules.
This feature is useful when writing definitions using tactics. Example:
```lean
inductive Foo where
| a | b | c
| pair: Foo × Foo → Foo
def Foo.deq (a b : Foo) : Decidable (a = b) := by
cases a <;> cases b
any_goals apply isFalse Foo.noConfusion
any_goals apply isTrue rfl
case pair a b =>
let (a₁, a₂) := a
let (b₁, b₂) := b
exact match deq a₁ b₁, deq a₂ b₂ with
| isTrue h₁, isTrue h₂ => isTrue (by rw [h₁,h₂])
| isFalse h₁, _ => isFalse (fun h => by cases h; cases (h₁ rfl))
| _, isFalse h₂ => isFalse (fun h => by cases h; cases (h₂ rfl))
```
* `Option` is again a monad. The auxiliary type `OptionM` has been removed. See [Zulip thread](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Do.20we.20still.20need.20OptionM.3F/near/279761084).
* Improve `split` tactic. It used to fail on `match` expressions of the form `match h : e with ...` where `e` is not a free variable.
The failure used to occur during generalization.
* New encoding for `match`-expressions that use the `h :` notation for discriminants. The information is not lost during delaboration,
and it is the foundation for a better `split` tactic. at delaboration time. Example:
```lean
#print Nat.decEq
/-
protected def Nat.decEq : (n m : Nat) → Decidable (n = m) :=
fun n m =>
match h : Nat.beq n m with
| true => isTrue (_ : n = m)
| false => isFalse (_ : ¬n = m)
-/
```
* `exists` tactic is now takes a comma separated list of terms.
* Add `dsimp` and `dsimp!` tactics. They guarantee the result term is definitionally equal, and only apply
`rfl`-theorems.
* Fix binder information for `match` patterns that use definitions tagged with `[matchPattern]` (e.g., `Nat.add`).
We now have proper binder information for the variable `y` in the following example.
```lean
def f (x : Nat) : Nat :=
match x with
| 0 => 1
| y + 1 => y
```
* (Fix) the default value for structure fields may now depend on the structure parameters. Example:
```lean
structure Something (i: Nat) where
n1: Nat := 1
n2: Nat := 1 + i
def s : Something 10 := {}
example : s.n2 = 11 := rfl
```
* Apply `rfl` theorems at the `dsimp` auxiliary method used by `simp`. `dsimp` can be used anywhere in an expression
because it preserves definitional equality.
* Refine auto bound implicit feature. It does not consider anymore unbound variables that have the same
name of a declaration being defined. Example:
```lean
def f : f → Bool := -- Error at second `f`
fun _ => true
inductive Foo : List Foo → Type -- Error at second `Foo`
| x : Foo []
```
Before this refinement, the declarations above would be accepted and the
second `f` and `Foo` would be treated as auto implicit variables. That is,
`f : {f : Sort u} → f → Bool`, and
`Foo : {Foo : Type u} → List Foo → Type`.
* Fix syntax highlighting for recursive declarations. Example
```lean
inductive List (α : Type u) where
| nil : List α -- `List` is not highlighted as a variable anymore
| cons (head : α) (tail : List α) : List α
def List.map (f : α → β) : List α → List β
| [] => []
| a::as => f a :: map f as -- `map` is not highlighted as a variable anymore
```
* Add `autoUnfold` option to `Lean.Meta.Simp.Config`, and the following macros
- `simp!` for `simp (config := { autoUnfold := true })`
- `simp_arith!` for `simp (config := { autoUnfold := true, arith := true })`
- `simp_all!` for `simp_all (config := { autoUnfold := true })`
- `simp_all_arith!` for `simp_all (config := { autoUnfold := true, arith := true })`
When the `autoUnfold` is set to true, `simp` tries to unfold the following kinds of definition
- Recursive definitions defined by structural recursion.
- Non-recursive definitions where the body is a `match`-expression. This
kind of definition is only unfolded if the `match` can be reduced.
Example:
```lean
def append (as bs : List α) : List α :=
match as with
| [] => bs
| a :: as => a :: append as bs
theorem append_nil (as : List α) : append as [] = as := by
induction as <;> simp_all!
theorem append_assoc (as bs cs : List α) : append (append as bs) cs = append as (append bs cs) := by
induction as <;> simp_all!
```
* Add `save` tactic for creating checkpoints more conveniently. Example:
```lean
example : <some-proposition> := by
tac_1
tac_2
save
tac_3
...
```
is equivalent to
```lean
example : <some-proposition> := by
checkpoint
tac_1
tac_2
tac_3
...
```
* Remove support for `{}` annotation from inductive datatype constructors. This annotation was barely used, and we can control the binder information for parameter bindings using the new inductive family indices to parameter promotion. Example: the following declaration using `{}`
```lean
inductive LE' (n : Nat) : Nat → Prop where
| refl {} : LE' n n -- Want `n` to be explicit
| succ : LE' n m → LE' n (m+1)
```
can now be written as
```lean
inductive LE' : Nat → Nat → Prop where
| refl (n : Nat) : LE' n n
| succ : LE' n m → LE' n (m+1)
```
In both cases, the inductive family has one parameter and one index.
Recall that the actual number of parameters can be retrieved using the command `#print`.
* Remove support for `{}` annotation in the `structure` command.
* Several improvements to LSP server. Examples: "jump to definition" in mutually recursive sections, fixed incorrect hover information in "match"-expression patterns, "jump to definition" for pattern variables, fixed auto-completion in function headers, etc.
* In `macro ... xs:p* ...` and similar macro bindings of combinators, `xs` now has the correct type `Array Syntax`
* Identifiers in syntax patterns now ignore macro scopes during matching.
* Improve binder names for constructor auto implicit parameters. Example, given the inductive datatype
```lean
inductive Member : α → List α → Type u
| head : Member a (a::as)
| tail : Member a bs → Member a (b::bs)
```
before:
```lean
#check @Member.head
-- @Member.head : {x : Type u_1} → {a : x} → {as : List x} → Member a (a :: as)
```
now:
```lean
#check @Member.head
-- @Member.head : {α : Type u_1} → {a : α} → {as : List α} → Member a (a :: as)
```
* Improve error message when constructor parameter universe level is too big.
* Add support for `for h : i in [start:stop] do .. ` where `h : i ∈ [start:stop]`. This feature is useful for proving
termination of functions such as:
```lean
inductive Expr where
| app (f : String) (args : Array Expr)
def Expr.size (e : Expr) : Nat := Id.run do
match e with
| app f args =>
let mut sz := 1
for h : i in [: args.size] do
-- h.upper : i < args.size
sz := sz + size (args.get ⟨i, h.upper⟩)
return sz
```
* Add tactic `case'`. It is similar to `case`, but does not admit the goal on failure.
For example, the new tactic is useful when writing tactic scripts where we need to use `case'`
at `first | ... | ...`, and we want to take the next alternative when `case'` fails.
* Add tactic macro
```lean
macro "stop" s:tacticSeq : tactic => `(repeat sorry)
```
See discussion on [Zulip](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Partial.20evaluation.20of.20a.20file).
* When displaying goals, we do not display inaccessible proposition names
if they do not have forward dependencies. We still display their types.
For example, the goal
```lean
case node.inl.node
β : Type u_1
b : BinTree β
k : Nat
v : β
left : Tree β
key : Nat
value : β
right : Tree β
ihl : BST left → Tree.find? (Tree.insert left k v) k = some v
ihr : BST right → Tree.find? (Tree.insert right k v) k = some v
h✝ : k < key
a✝³ : BST left
a✝² : ForallTree (fun k v => k < key) left
a✝¹ : BST right
a✝ : ForallTree (fun k v => key < k) right
⊢ BST left
```
is now displayed as
```lean
case node.inl.node
β : Type u_1
b : BinTree β
k : Nat
v : β
left : Tree β
key : Nat
value : β
right : Tree β
ihl : BST left → Tree.find? (Tree.insert left k v) k = some v
ihr : BST right → Tree.find? (Tree.insert right k v) k = some v
: k < key
: BST left
: ForallTree (fun k v => k < key) left
: BST right
: ForallTree (fun k v => key < k) right
⊢ BST left
```
* The hypothesis name is now optional in the `by_cases` tactic.
* [Fix inconsistency between `syntax` and kind names](https://github.com/leanprover/lean4/issues/1090).
The node kinds `numLit`, `charLit`, `nameLit`, `strLit`, and `scientificLit` are now called
`num`, `char`, `name`, `str`, and `scientific` respectively. Example: we now write
```lean
macro_rules | `($n:num) => `("hello")
```
instead of
```lean
macro_rules | `($n:numLit) => `("hello")
```
* (Experimental) New `checkpoint <tactic-seq>` tactic for big interactive proofs.
* Rename tactic `nativeDecide` => `native_decide`.
* Antiquotations are now accepted in any syntax. The `incQuotDepth` `syntax` parser is therefore obsolete and has been removed.
* Renamed tactic `nativeDecide` => `native_decide`.
* "Cleanup" local context before elaborating a `match` alternative right-hand-side. Examples:
```lean
example (x : Nat) : Nat :=
match g x with
| (a, b) => _ -- Local context does not contain the auxiliary `_discr := g x` anymore
example (x : Nat × Nat) (h : x.1 > 0) : f x > 0 := by
match x with
| (a, b) => _ -- Local context does not contain the `h✝ : x.fst > 0` anymore
```
* Improve `let`-pattern (and `have`-pattern) macro expansion. In the following example,
```lean
example (x : Nat × Nat) : f x > 0 := by
let (a, b) := x
done
```
The resulting goal is now `... |- f (a, b) > 0` instead of `... |- f x > 0`.
* Add cross-compiled [aarch64 Linux](https://github.com/leanprover/lean4/pull/1066) and [aarch64 macOS](https://github.com/leanprover/lean4/pull/1076) releases.
* [Add tutorial-like examples to our documentation](https://github.com/leanprover/lean4/tree/master/doc/examples), rendered using LeanInk+Alectryon.

120
releases/v4.0.0.md Normal file
View File

@@ -0,0 +1,120 @@
v4.0.0
---------
* [`Lean.Meta.getConst?` has been renamed](https://github.com/leanprover/lean4/pull/2454).
We have renamed `getConst?` to `getUnfoldableConst?` (and `getConstNoEx?` to `getUnfoldableConstNoEx?`).
These were not intended to be part of the public API, but downstream projects had been using them
(sometimes expecting different behaviour) incorrectly instead of `Lean.getConstInfo`.
* [`dsimp` / `simp` / `simp_all` now fail by default if they make no progress](https://github.com/leanprover/lean4/pull/2336).
This can be overridden with the `(config := { failIfUnchanged := false })` option.
This change was made to ease manual use of `simp` (with complicated goals it can be hard to tell if it was effective)
and to allow easier flow control in tactics internally using `simp`.
See the [summary discussion](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/simp.20fails.20if.20no.20progress/near/380153295)
on zulip for more details.
* [`simp_all` now preserves order of hypotheses](https://github.com/leanprover/lean4/pull/2334).
In order to support the `failIfUnchanged` configuration option for `dsimp` / `simp` / `simp_all`
the way `simp_all` replaces hypotheses has changed.
In particular it is now more likely to preserve the order of hypotheses.
See [`simp_all` reorders hypotheses unnecessarily](https://github.com/leanprover/lean4/pull/2334).
(Previously all non-dependent propositional hypotheses were reverted and reintroduced.
Now only such hypotheses which were changed, or which come after a changed hypothesis,
are reverted and reintroduced.
This has the effect of preserving the ordering amongst the non-dependent propositional hypotheses,
but now any dependent or non-propositional hypotheses retain their position amongst the unchanged
non-dependent propositional hypotheses.)
This may affect proofs that use `rename_i`, `case ... =>`, or `next ... =>`.
* [New `have this` implementation](https://github.com/leanprover/lean4/pull/2247).
`this` is now a regular identifier again that is implicitly introduced by anonymous `have :=` for the remainder of the tactic block. It used to be a keyword that was visible in all scopes and led to unexpected behavior when explicitly used as a binder name.
* [Show typeclass and tactic names in profile output](https://github.com/leanprover/lean4/pull/2170).
* [Make `calc` require the sequence of relation/proof-s to have the same indentation](https://github.com/leanprover/lean4/pull/1844),
and [add `calc` alternative syntax allowing underscores `_` in the first relation](https://github.com/leanprover/lean4/pull/1844).
The flexible indentation in `calc` was often used to align the relation symbols:
```lean
example (x y : Nat) : (x + y) * (x + y) = x * x + y * x + x * y + y * y :=
calc
(x + y) * (x + y) = (x + y) * x + (x + y) * y := by rw [Nat.mul_add]
-- improper indentation
_ = x * x + y * x + (x + y) * y := by rw [Nat.add_mul]
_ = x * x + y * x + (x * y + y * y) := by rw [Nat.add_mul]
_ = x * x + y * x + x * y + y * y := by rw [←Nat.add_assoc]
```
This is no longer legal. The new syntax puts the first term right after the `calc` and each step has the same indentation:
```lean
example (x y : Nat) : (x + y) * (x + y) = x * x + y * x + x * y + y * y :=
calc (x + y) * (x + y)
_ = (x + y) * x + (x + y) * y := by rw [Nat.mul_add]
_ = x * x + y * x + (x + y) * y := by rw [Nat.add_mul]
_ = x * x + y * x + (x * y + y * y) := by rw [Nat.add_mul]
_ = x * x + y * x + x * y + y * y := by rw [←Nat.add_assoc]
```
* Update Lake to latest prerelease.
* [Make go-to-definition on a typeclass projection application go to the instance(s)](https://github.com/leanprover/lean4/pull/1767).
* [Include timings in trace messages when `profiler` is true](https://github.com/leanprover/lean4/pull/1995).
* [Pretty-print signatures in hover and `#check <ident>`](https://github.com/leanprover/lean4/pull/1943).
* [Introduce parser memoization to avoid exponential behavior](https://github.com/leanprover/lean4/pull/1799).
* [feat: allow `doSeq` in `let x <- e | seq`](https://github.com/leanprover/lean4/pull/1809).
* [Add hover/go-to-def/refs for options](https://github.com/leanprover/lean4/pull/1783).
* [Add empty type ascription syntax `(e :)`](https://github.com/leanprover/lean4/pull/1797).
* [Make tokens in `<|>` relevant to syntax match](https://github.com/leanprover/lean4/pull/1744).
* [Add `linter.deprecated` option to silence deprecation warnings](https://github.com/leanprover/lean4/pull/1768).
* [Improve fuzzy-matching heuristics](https://github.com/leanprover/lean4/pull/1710).
* [Implementation-detail hypotheses](https://github.com/leanprover/lean4/pull/1692).
* [Hover information for `cases`/`induction` case names](https://github.com/leanprover/lean4/pull/1660).
* [Prefer longer parse even if unsuccessful](https://github.com/leanprover/lean4/pull/1658).
* [Show declaration module in hover](https://github.com/leanprover/lean4/pull/1638).
* [New `conv` mode structuring tactics](https://github.com/leanprover/lean4/pull/1636).
* `simp` can track information and can print an equivalent `simp only`. [PR #1626](https://github.com/leanprover/lean4/pull/1626).
* Enforce uniform indentation in tactic blocks / do blocks. See issue [#1606](https://github.com/leanprover/lean4/issues/1606).
* Moved `AssocList`, `HashMap`, `HashSet`, `RBMap`, `RBSet`, `PersistentArray`, `PersistentHashMap`, `PersistentHashSet` to the Lean package. The [standard library](https://github.com/leanprover/std4) contains versions that will evolve independently to simplify bootstrapping process.
* Standard library moved to the [std4 GitHub repository](https://github.com/leanprover/std4).
* `InteractiveGoals` now has information that a client infoview can use to show what parts of the goal have changed after applying a tactic. [PR #1610](https://github.com/leanprover/lean4/pull/1610).
* Add `[inheritDoc]` attribute. [PR #1480](https://github.com/leanprover/lean4/pull/1480).
* Expose that `panic = default`. [PR #1614](https://github.com/leanprover/lean4/pull/1614).
* New [code generator](https://github.com/leanprover/lean4/tree/master/src/Lean/Compiler/LCNF) project has started.
* Remove description argument from `register_simp_attr`. [PR #1566](https://github.com/leanprover/lean4/pull/1566).
* [Additional concurrency primitives](https://github.com/leanprover/lean4/pull/1555).
* [Collapsible traces with messages](https://github.com/leanprover/lean4/pull/1448).
* [Hygienic resolution of namespaces](https://github.com/leanprover/lean4/pull/1442).
* [New `Float` functions](https://github.com/leanprover/lean4/pull/1460).
* Many new doc strings have been added to declarations at `Init`.

21
releases/v4.1.0.md Normal file
View File

@@ -0,0 +1,21 @@
v4.1.0
---------
* The error positioning on missing tokens has been [improved](https://github.com/leanprover/lean4/pull/2393). In particular, this should make it easier to spot errors in incomplete tactic proofs.
* After elaborating a configuration file, Lake will now cache the configuration to a `lakefile.olean`. Subsequent runs of Lake will import this OLean instead of elaborating the configuration file. This provides a significant performance improvement (benchmarks indicate that using the OLean cuts Lake's startup time in half), but there are some important details to keep in mind:
+ Lake will regenerate this OLean after each modification to the `lakefile.lean` or `lean-toolchain`. You can also force a reconfigure by passing the new `--reconfigure` / `-R` option to `lake`.
+ Lake configuration options (i.e., `-K`) will be fixed at the moment of elaboration. Setting these options when `lake` is using the cached configuration will have no effect. To change options, run `lake` with `-R` / `--reconfigure`.
+ **The `lakefile.olean` is a local configuration and should not be committed to Git. Therefore, existing Lake packages need to add it to their `.gitignore`.**
* The signature of `Lake.buildO` has changed, `args` has been split into `weakArgs` and `traceArgs`. `traceArgs` are included in the input trace and `weakArgs` are not. See Lake's [FFI example](src/lake/examples/ffi/lib/lakefile.lean) for a demonstration of how to adapt to this change.
* The signatures of `Lean.importModules`, `Lean.Elab.headerToImports`, and `Lean.Elab.parseImports`
have [changed](https://github.com/leanprover/lean4/pull/2480) from taking `List Import` to `Array Import`.
* There is now [an `occs` field](https://github.com/leanprover/lean4/pull/2470)
in the configuration object for the `rewrite` tactic,
allowing control of which occurrences of a pattern should be rewritten.
This was previously a separate argument for `Lean.MVarId.rewrite`,
and this has been removed in favour of an additional field of `Rewrite.Config`.
It was not previously accessible from user tactics.

281
releases/v4.10.0.md Normal file
View File

@@ -0,0 +1,281 @@
v4.10.0
----------
### Language features, tactics, and metaprograms
* `split` tactic:
* [#4401](https://github.com/leanprover/lean4/pull/4401) improves the strategy `split` uses to generalize discriminants of matches and adds `trace.split.failure` trace class for diagnosing issues.
* `rw` tactic:
* [#4385](https://github.com/leanprover/lean4/pull/4385) prevents the tactic from claiming pre-existing goals are new subgoals.
* [dac1da](https://github.com/leanprover/lean4/commit/dac1dacc5b39911827af68247d575569d9c399b5) adds configuration for ordering new goals, like for `apply`.
* `simp` tactic:
* [#4430](https://github.com/leanprover/lean4/pull/4430) adds `dsimproc`s for `if` expressions (`ite` and `dite`).
* [#4434](https://github.com/leanprover/lean4/pull/4434) improves heuristics for unfolding. Equational lemmas now have priorities where more-specific equationals lemmas are tried first before a possible catch-all.
* [#4481](https://github.com/leanprover/lean4/pull/4481) fixes an issue where function-valued `OfNat` numeric literals would become denormalized.
* [#4467](https://github.com/leanprover/lean4/pull/4467) fixes an issue where dsimp theorems might not apply to literals.
* [#4484](https://github.com/leanprover/lean4/pull/4484) fixes the source position for the warning for deprecated simp arguments.
* [#4258](https://github.com/leanprover/lean4/pull/4258) adds docstrings for `dsimp` configuration.
* [#4567](https://github.com/leanprover/lean4/pull/4567) improves the accuracy of used simp lemmas reported by `simp?`.
* [fb9727](https://github.com/leanprover/lean4/commit/fb97275dcbb683efe6da87ed10a3f0cd064b88fd) adds (but does not implement) the simp configuration option `implicitDefEqProofs`, which will enable including `rfl`-theorems in proof terms.
* `omega` tactic:
* [#4360](https://github.com/leanprover/lean4/pull/4360) makes the tactic generate error messages lazily, improving its performance when used in tactic combinators.
* `bv_omega` tactic:
* [#4579](https://github.com/leanprover/lean4/pull/4579) works around changes to the definition of `Fin.sub` in this release.
* [#4490](https://github.com/leanprover/lean4/pull/4490) sets up groundwork for a tactic index in generated documentation, as there was in Lean 3. See PR description for details.
* **Commands**
* [#4370](https://github.com/leanprover/lean4/pull/4370) makes the `variable` command fully elaborate binders during validation, fixing an issue where some errors would be reported only at the next declaration.
* [#4408](https://github.com/leanprover/lean4/pull/4408) fixes a discrepancy in universe parameter order between `theorem` and `def` declarations.
* [#4493](https://github.com/leanprover/lean4/pull/4493) and
[#4482](https://github.com/leanprover/lean4/pull/4482) fix a discrepancy in the elaborators for `theorem`, `def`, and `example`,
making `Prop`-valued `example`s and other definition commands elaborate like `theorem`s.
* [8f023b](https://github.com/leanprover/lean4/commit/8f023b85c554186ae562774b8122322d856c674e), [3c4d6b](https://github.com/leanprover/lean4/commit/3c4d6ba8648eb04d90371eb3fdbd114d16949501) and [0783d0](https://github.com/leanprover/lean4/commit/0783d0fcbe31b626fbd3ed2f29d838e717f09101) change the `#reduce` command to be able to control what gets reduced.
For example, `#reduce (proofs := true) (types := false) e` reduces both proofs and types in the expression `e`.
By default, neither proofs or types are reduced.
* [#4489](https://github.com/leanprover/lean4/pull/4489) fixes an elaboration bug in `#check_tactic`.
* [#4505](https://github.com/leanprover/lean4/pull/4505) adds support for `open _root_.<namespace>`.
* **Options**
* [#4576](https://github.com/leanprover/lean4/pull/4576) adds the `debug.byAsSorry` option. Setting `set_option debug.byAsSorry true` causes all `by ...` terms to elaborate as `sorry`.
* [7b56eb](https://github.com/leanprover/lean4/commit/7b56eb20a03250472f4b145118ae885274d1f8f7) and [d8e719](https://github.com/leanprover/lean4/commit/d8e719f9ab7d049e423473dfc7a32867d32c856f) add the `debug.skipKernelTC` option. Setting `set_option debug.skipKernelTC true` turns off kernel typechecking. This is meant for temporarily working around kernel performance issues, and it compromises soundness since buggy tactics may produce invalid proofs, which will not be caught if this option is set to true.
* [#4301](https://github.com/leanprover/lean4/pull/4301)
adds a linter to flag situations where a local variable's name is one of
the argumentless constructors of its type. This can arise when a user either
doesn't open a namespace or doesn't add a dot or leading qualifier, as
in the following:
```lean
inductive Tree (α : Type) where
| leaf
| branch (left : Tree α) (val : α) (right : Tree α)
def depth : Tree α → Nat
| leaf => 0
```
With this linter, the `leaf` pattern is highlighted as a local
variable whose name overlaps with the constructor `Tree.leaf`.
The linter can be disabled with `set_option linter.constructorNameAsVariable false`.
Additionally, the error message that occurs when a name in a pattern that takes arguments isn't valid now suggests similar names that would be valid. This means that the following definition:
```lean
def length (list : List α) : Nat :=
match list with
| nil => 0
| cons x xs => length xs + 1
```
now results in the following warning:
```
warning: Local variable 'nil' resembles constructor 'List.nil' - write '.nil' (with a dot) or 'List.nil' to use the constructor.
note: this linter can be disabled with `set_option linter.constructorNameAsVariable false`
```
and error:
```
invalid pattern, constructor or constant marked with '[match_pattern]' expected
Suggestion: 'List.cons' is similar
```
* **Metaprogramming**
* [#4454](https://github.com/leanprover/lean4/pull/4454) adds public `Name.isInternalDetail` function for filtering declarations using naming conventions for internal names.
* **Other fixes or improvements**
* [#4416](https://github.com/leanprover/lean4/pull/4416) sorts the output of `#print axioms` for determinism.
* [#4528](https://github.com/leanprover/lean4/pull/4528) fixes error message range for the cdot focusing tactic.
### Language server, widgets, and IDE extensions
* [#4443](https://github.com/leanprover/lean4/pull/4443) makes the watchdog be more resilient against badly behaving clients.
### Pretty printing
* [#4433](https://github.com/leanprover/lean4/pull/4433) restores fallback pretty printers when context is not available, and documents `addMessageContext`.
* [#4556](https://github.com/leanprover/lean4/pull/4556) introduces `pp.maxSteps` option and sets the default value of `pp.deepTerms` to `false`. Together, these keep excessively large or deep terms from overwhelming the Infoview.
### Library
* [#4560](https://github.com/leanprover/lean4/pull/4560) splits `GetElem` class into `GetElem` and `GetElem?`.
This enables removing `Decidable` instance arguments from `GetElem.getElem?` and `GetElem.getElem!`, improving their rewritability.
See the docstrings for these classes for more information.
* `Array`
* [#4389](https://github.com/leanprover/lean4/pull/4389) makes `Array.toArrayAux_eq` be a `simp` lemma.
* [#4399](https://github.com/leanprover/lean4/pull/4399) improves robustness of the proof for `Array.reverse_data`.
* `List`
* [#4469](https://github.com/leanprover/lean4/pull/4469) and [#4475](https://github.com/leanprover/lean4/pull/4475) improve the organization of the `List` API.
* [#4470](https://github.com/leanprover/lean4/pull/4470) improves the `List.set` and `List.concat` API.
* [#4472](https://github.com/leanprover/lean4/pull/4472) upstreams lemmas about `List.filter` from Batteries.
* [#4473](https://github.com/leanprover/lean4/pull/4473) adjusts `@[simp]` attributes.
* [#4488](https://github.com/leanprover/lean4/pull/4488) makes `List.getElem?_eq_getElem` be a simp lemma.
* [#4487](https://github.com/leanprover/lean4/pull/4487) adds missing `List.replicate` API.
* [#4521](https://github.com/leanprover/lean4/pull/4521) adds lemmas about `List.map`.
* [#4500](https://github.com/leanprover/lean4/pull/4500) changes `List.length_cons` to use `as.length + 1` instead of `as.length.succ`.
* [#4524](https://github.com/leanprover/lean4/pull/4524) fixes the statement of `List.filter_congr`.
* [#4525](https://github.com/leanprover/lean4/pull/4525) changes binder explicitness in `List.bind_map`.
* [#4550](https://github.com/leanprover/lean4/pull/4550) adds `maximum?_eq_some_iff'` and `minimum?_eq_some_iff?`.
* [#4400](https://github.com/leanprover/lean4/pull/4400) switches the normal forms for indexing `List` and `Array` to `xs[n]` and `xs[n]?`.
* `HashMap`
* [#4372](https://github.com/leanprover/lean4/pull/4372) fixes linearity in `HashMap.insert` and `HashMap.erase`, leading to a 40% speedup in a replace-heavy workload.
* `Option`
* [#4403](https://github.com/leanprover/lean4/pull/4403) generalizes type of `Option.forM` from `Unit` to `PUnit`.
* [#4504](https://github.com/leanprover/lean4/pull/4504) remove simp attribute from `Option.elim` and instead adds it to individual reduction lemmas, making unfolding less aggressive.
* `Nat`
* [#4242](https://github.com/leanprover/lean4/pull/4242) adds missing theorems for `n + 1` and `n - 1` normal forms.
* [#4486](https://github.com/leanprover/lean4/pull/4486) makes `Nat.min_assoc` be a simp lemma.
* [#4522](https://github.com/leanprover/lean4/pull/4522) moves `@[simp]` from `Nat.pred_le` to `Nat.sub_one_le`.
* [#4532](https://github.com/leanprover/lean4/pull/4532) changes various `Nat.succ n` to `n + 1`.
* `Int`
* [#3850](https://github.com/leanprover/lean4/pull/3850) adds complete div/mod simprocs for `Int`.
* `String`/`Char`
* [#4357](https://github.com/leanprover/lean4/pull/4357) make the byte size interface be `Nat`-valued with functions `Char.utf8Size` and `String.utf8ByteSize`.
* [#4438](https://github.com/leanprover/lean4/pull/4438) upstreams `Char.ext` from Batteries and adds some `Char` documentation to the manual.
* `Fin`
* [#4421](https://github.com/leanprover/lean4/pull/4421) adjusts `Fin.sub` to be more performant in definitional equality checks.
* `Prod`
* [#4526](https://github.com/leanprover/lean4/pull/4526) adds missing `Prod.map` lemmas.
* [#4533](https://github.com/leanprover/lean4/pull/4533) fixes binder explicitness in lemmas.
* `BitVec`
* [#4428](https://github.com/leanprover/lean4/pull/4428) adds missing `simproc` for `BitVec` equality.
* [#4417](https://github.com/leanprover/lean4/pull/4417) adds `BitVec.twoPow` and lemmas, toward bitblasting multiplication for LeanSAT.
* `Std` library
* [#4499](https://github.com/leanprover/lean4/pull/4499) introduces `Std`, a library situated between `Init` and `Lean`, providing functionality not in the prelude both to Lean's implementation and to external users.
* **Other fixes or improvements**
* [#3056](https://github.com/leanprover/lean4/pull/3056) standardizes on using `(· == a)` over `(a == ·)`.
* [#4502](https://github.com/leanprover/lean4/pull/4502) fixes errors reported by running the library through the the Batteries linters.
### Lean internals
* [#4391](https://github.com/leanprover/lean4/pull/4391) makes `getBitVecValue?` recognize `BitVec.ofNatLt`.
* [#4410](https://github.com/leanprover/lean4/pull/4410) adjusts `instantiateMVars` algorithm to zeta reduce `let` expressions while beta reducing instantiated metavariables.
* [#4420](https://github.com/leanprover/lean4/pull/4420) fixes occurs check for metavariable assignments to also take metavariable types into account.
* [#4425](https://github.com/leanprover/lean4/pull/4425) fixes `forEachModuleInDir` to iterate over each Lean file exactly once.
* [#3886](https://github.com/leanprover/lean4/pull/3886) adds support to build Lean core oleans using Lake.
* **Defeq and WHNF algorithms**
* [#4387](https://github.com/leanprover/lean4/pull/4387) improves performance of `isDefEq` by eta reducing lambda-abstracted terms during metavariable assignments, since these are beta reduced during metavariable instantiation anyway.
* [#4388](https://github.com/leanprover/lean4/pull/4388) removes redundant code in `isDefEqQuickOther`.
* **Typeclass inference**
* [#4530](https://github.com/leanprover/lean4/pull/4530) fixes handling of metavariables when caching results at `synthInstance?`.
* **Elaboration**
* [#4426](https://github.com/leanprover/lean4/pull/4426) makes feature where the "don't know how to synthesize implicit argument" error reports the name of the argument more reliable.
* [#4497](https://github.com/leanprover/lean4/pull/4497) fixes a name resolution bug for generalized field notation (dot notation).
* [#4536](https://github.com/leanprover/lean4/pull/4536) blocks the implicit lambda feature for `(e :)` notation.
* [#4562](https://github.com/leanprover/lean4/pull/4562) makes it be an error for there to be two functions with the same name in a `where`/`let rec` block.
* Recursion principles
* [#4549](https://github.com/leanprover/lean4/pull/4549) refactors `findRecArg`, extracting `withRecArgInfo`.
Errors are now reported in parameter order rather than the order they are tried (non-indices are tried first).
For every argument, it will say why it wasn't tried, even if the reason is obvious (e.g. a fixed prefix or is `Prop`-typed, etc.).
* Porting core C++ to Lean
* [#4474](https://github.com/leanprover/lean4/pull/4474) takes a step to refactor `constructions` toward a future port to Lean.
* [#4498](https://github.com/leanprover/lean4/pull/4498) ports `mk_definition_inferring_unsafe` to Lean.
* [#4516](https://github.com/leanprover/lean4/pull/4516) ports `recOn` construction to Lean.
* [#4517](https://github.com/leanprover/lean4/pull/4517), [#4653](https://github.com/leanprover/lean4/pull/4653), and [#4651](https://github.com/leanprover/lean4/pull/4651) port `below` and `brecOn` construction to Lean.
* Documentation
* [#4501](https://github.com/leanprover/lean4/pull/4501) adds a more-detailed docstring for `PersistentEnvExtension`.
* **Other fixes or improvements**
* [#4382](https://github.com/leanprover/lean4/pull/4382) removes `@[inline]` attribute from `NameMap.find?`, which caused respecialization at each call site.
* [5f9ded](https://github.com/leanprover/lean4/commit/5f9dedfe5ee9972acdebd669f228f487844a6156) improves output of `trace.Elab.snapshotTree`.
* [#4424](https://github.com/leanprover/lean4/pull/4424) removes "you might need to open '{dir}' in your editor" message that is now handled by Lake and the VS Code extension.
* [#4451](https://github.com/leanprover/lean4/pull/4451) improves the performance of `CollectMVars` and `FindMVar`.
* [#4479](https://github.com/leanprover/lean4/pull/4479) adds missing `DecidableEq` and `Repr` instances for intermediate structures used by the `BitVec` and `Fin` simprocs.
* [#4492](https://github.com/leanprover/lean4/pull/4492) adds tests for a previous `isDefEq` issue.
* [9096d6](https://github.com/leanprover/lean4/commit/9096d6fc7180fe533c504f662bcb61550e4a2492) removes `PersistentHashMap.size`.
* [#4508](https://github.com/leanprover/lean4/pull/4508) fixes `@[implemented_by]` for functions defined by well-founded recursion.
* [#4509](https://github.com/leanprover/lean4/pull/4509) adds additional tests for `apply?` tactic.
* [d6eab3](https://github.com/leanprover/lean4/commit/d6eab393f4df9d473b5736d636b178eb26d197e6) fixes a benchmark.
* [#4563](https://github.com/leanprover/lean4/pull/4563) adds a workaround for a bug in `IndPredBelow.mkBelowMatcher`.
* **Cleanup:** [#4380](https://github.com/leanprover/lean4/pull/4380), [#4431](https://github.com/leanprover/lean4/pull/4431), [#4494](https://github.com/leanprover/lean4/pull/4494), [e8f768](https://github.com/leanprover/lean4/commit/e8f768f9fd8cefc758533bc76e3a12b398ed4a39), [de2690](https://github.com/leanprover/lean4/commit/de269060d17a581ed87f40378dbec74032633b27), [d3a756](https://github.com/leanprover/lean4/commit/d3a7569c97123d022828106468d54e9224ed8207), [#4404](https://github.com/leanprover/lean4/pull/4404), [#4537](https://github.com/leanprover/lean4/pull/4537).
### Compiler, runtime, and FFI
* [d85d3d](https://github.com/leanprover/lean4/commit/d85d3d5f3a09ff95b2ee47c6f89ef50b7e339126) fixes criterion for tail-calls in ownership calculation.
* [#3963](https://github.com/leanprover/lean4/pull/3963) adds validation of UTF-8 at the C++-to-Lean boundary in the runtime.
* [#4512](https://github.com/leanprover/lean4/pull/4512) fixes missing unboxing in interpreter when loading initialized value.
* [#4477](https://github.com/leanprover/lean4/pull/4477) exposes the compiler flags for the bundled C compiler (clang).
### Lake
* [#4384](https://github.com/leanprover/lean4/pull/4384) deprecates `inputFile` and replaces it with `inputBinFile` and `inputTextFile`. Unlike `inputBinFile` (and `inputFile`), `inputTextFile` normalizes line endings, which helps ensure text file traces are platform-independent.
* [#4371](https://github.com/leanprover/lean4/pull/4371) simplifies dependency resolution code.
* [#4439](https://github.com/leanprover/lean4/pull/4439) touches up the Lake configuration DSL and makes other improvements:
string literals can now be used instead of identifiers for names,
avoids using French quotes in `lake new` and `lake init` templates,
changes the `exe` template to use `Main` for the main module,
improves the `math` template error if `lean-toolchain` fails to download,
and downgrades unknown configuration fields from an error to a warning to improve cross-version compatibility.
* [#4496](https://github.com/leanprover/lean4/pull/4496) tweaks `require` syntax and updates docs. Now `require` in TOML for a package name such as `doc-gen4` does not need French quotes.
* [#4485](https://github.com/leanprover/lean4/pull/4485) fixes a bug where package versions in indirect dependencies would take precedence over direct dependencies.
* [#4478](https://github.com/leanprover/lean4/pull/4478) fixes a bug where Lake incorrectly included the module dynamic library in a platform-independent trace.
* [#4529](https://github.com/leanprover/lean4/pull/4529) fixes some issues with bad import errors.
A bad import in an executable no longer prevents the executable's root
module from being built. This also fixes a problem where the location
of a transitive bad import would not been shown.
The root module of the executable now respects `nativeFacets`.
* [#4564](https://github.com/leanprover/lean4/pull/4564) fixes a bug where non-identifier script names could not be entered on the CLI without French quotes.
* [#4566](https://github.com/leanprover/lean4/pull/4566) addresses a few issues with precompiled libraries.
* Fixes a bug where Lake would always precompile the package of a module.
* If a module is precompiled, it now precompiles its imports. Previously, it would only do this if imported.
* [#4495](https://github.com/leanprover/lean4/pull/4495), [#4692](https://github.com/leanprover/lean4/pull/4692), [#4849](https://github.com/leanprover/lean4/pull/4849)
add a new type of `require` that fetches package metadata from a
registry API endpoint (e.g. Reservoir) and then clones a Git package
using the information provided. To require such a dependency, the new
syntax is:
```lean
require <scope> / <pkg-name> [@ git <rev>]
-- Examples:
require "leanprover" / "doc-gen4"
require "leanprover-community" / "proofwidgets" @ git "v0.0.39"
```
Or in TOML:
```toml
[[require]]
name = "<pkg-name>"
scope = "<scope>"
rev = "<rev>"
```
Unlike with Git dependencies, Lake can make use of the richer
information provided by the registry to determine the default branch of
the package. This means for repositories of packages like `doc-gen4`
which have a default branch that is not `master`, Lake will now use said
default branch (e.g., in `doc-gen4`'s case, `main`).
Lake also supports configuring the registry endpoint via an environment
variable: `RESERVIOR_API_URL`. Thus, any server providing a similar
interface to Reservoir can be used as the registry. Further
configuration options paralleling those of Cargo's [Alternative Registries](https://doc.rust-lang.org/cargo/reference/registries.html)
and [Source Replacement](https://doc.rust-lang.org/cargo/reference/source-replacement.html)
will come in the future.
### DevOps/CI
* [#4427](https://github.com/leanprover/lean4/pull/4427) uses Namespace runners for CI for `leanprover/lean4`.
* [#4440](https://github.com/leanprover/lean4/pull/4440) fixes speedcenter tests in CI.
* [#4441](https://github.com/leanprover/lean4/pull/4441) fixes that workflow change would break CI for unrebased PRs.
* [#4442](https://github.com/leanprover/lean4/pull/4442) fixes Wasm release-ci.
* [6d265b](https://github.com/leanprover/lean4/commit/6d265b42b117eef78089f479790587a399da7690) fixes for `github.event.pull_request.merge_commit_sha` sometimes not being available.
* [16cad2](https://github.com/leanprover/lean4/commit/16cad2b45c6a77efe4dce850dcdbaafaa7c91fc3) adds optimization for CI to not fetch complete history.
* [#4544](https://github.com/leanprover/lean4/pull/4544) causes releases to be marked as prerelease on GitHub.
* [#4446](https://github.com/leanprover/lean4/pull/4446) switches Lake to using `src/lake/lakefile.toml` to avoid needing to load a version of Lake to build Lake.
* Nix
* [5eb5fa](https://github.com/leanprover/lean4/commit/5eb5fa49cf9862e99a5bccff8d4ca1a062f81900) fixes `update-stage0-commit` for Nix.
* [#4476](https://github.com/leanprover/lean4/pull/4476) adds gdb to Nix shell.
* [e665a0](https://github.com/leanprover/lean4/commit/e665a0d716dc42ba79b339b95e01eb99fe932cb3) fixes `update-stage0` for Nix.
* [4808eb](https://github.com/leanprover/lean4/commit/4808eb7c4bfb98f212b865f06a97d46c44978a61) fixes `cacheRoots` for Nix.
* [#3811](https://github.com/leanprover/lean4/pull/3811) adds platform-dependent flag to lib target.
* [#4587](https://github.com/leanprover/lean4/pull/4587) adds linking of `-lStd` back into nix build flags on darwin.
### Breaking changes
* `Char.csize` is replaced by `Char.utf8Size` ([#4357](https://github.com/leanprover/lean4/pull/4357)).
* Library lemmas now are in terms of `(· == a)` over `(a == ·)` ([#3056](https://github.com/leanprover/lean4/pull/3056)).
* Now the normal forms for indexing into `List` and `Array` is `xs[n]` and `xs[n]?` rather than using functions like `List.get` ([#4400](https://github.com/leanprover/lean4/pull/4400)).
* Sometimes terms created via a sequence of unifications will be more eta reduced than before and proofs will require adaptation ([#4387](https://github.com/leanprover/lean4/pull/4387)).
* The `GetElem` class has been split into two; see the docstrings for `GetElem` and `GetElem?` for more information ([#4560](https://github.com/leanprover/lean4/pull/4560)).

337
releases/v4.11.0.md Normal file
View File

@@ -0,0 +1,337 @@
v4.11.0
----------
### Language features, tactics, and metaprograms
* The variable inclusion mechanism has been changed. Like before, when a definition mentions a variable, Lean will add it as an argument of the definition, but now in theorem bodies, variables are not included based on usage in order to ensure that changes to the proof cannot change the statement of the overall theorem. Instead, variables are only available to the proof if they have been mentioned in the theorem header or in an **`include` command** or are instance implicit and depend only on such variables. The **`omit` command** can be used to omit included variables.
See breaking changes below.
PRs: [#4883](https://github.com/leanprover/lean4/pull/4883), [#4814](https://github.com/leanprover/lean4/pull/4814), [#5000](https://github.com/leanprover/lean4/pull/5000), [#5036](https://github.com/leanprover/lean4/pull/5036), [#5138](https://github.com/leanprover/lean4/pull/5138), [0edf1b](https://github.com/leanprover/lean4/commit/0edf1bac392f7e2fe0266b28b51c498306363a84).
* **Recursive definitions**
* Structural recursion can now be explicitly requested using
```
termination_by structural x
```
in analogy to the existing `termination_by x` syntax that causes well-founded recursion to be used.
[#4542](https://github.com/leanprover/lean4/pull/4542)
* [#4672](https://github.com/leanprover/lean4/pull/4672) fixes a bug that could lead to ill-typed terms.
* The `termination_by?` syntax no longer forces the use of well-founded recursion, and when structural
recursion is inferred, it will print the result using the `termination_by structural` syntax.
* **Mutual structural recursion** is now supported. This feature supports both mutual recursion over a non-mutual
data type, as well as recursion over mutual or nested data types:
```lean
mutual
def Even : Nat → Prop
| 0 => True
| n+1 => Odd n
def Odd : Nat → Prop
| 0 => False
| n+1 => Even n
end
mutual
inductive A
| other : B → A
| empty
inductive B
| other : A → B
| empty
end
mutual
def A.size : A → Nat
| .other b => b.size + 1
| .empty => 0
def B.size : B → Nat
| .other a => a.size + 1
| .empty => 0
end
inductive Tree where | node : List Tree → Tree
mutual
def Tree.size : Tree → Nat
| node ts => Tree.list_size ts
def Tree.list_size : List Tree → Nat
| [] => 0
| t::ts => Tree.size t + Tree.list_size ts
end
```
Functional induction principles are generated for these functions as well (`A.size.induct`, `A.size.mutual_induct`).
Nested structural recursion is still not supported.
PRs: [#4639](https://github.com/leanprover/lean4/pull/4639), [#4715](https://github.com/leanprover/lean4/pull/4715), [#4642](https://github.com/leanprover/lean4/pull/4642), [#4656](https://github.com/leanprover/lean4/pull/4656), [#4684](https://github.com/leanprover/lean4/pull/4684), [#4715](https://github.com/leanprover/lean4/pull/4715), [#4728](https://github.com/leanprover/lean4/pull/4728), [#4575](https://github.com/leanprover/lean4/pull/4575), [#4731](https://github.com/leanprover/lean4/pull/4731), [#4658](https://github.com/leanprover/lean4/pull/4658), [#4734](https://github.com/leanprover/lean4/pull/4734), [#4738](https://github.com/leanprover/lean4/pull/4738), [#4718](https://github.com/leanprover/lean4/pull/4718), [#4733](https://github.com/leanprover/lean4/pull/4733), [#4787](https://github.com/leanprover/lean4/pull/4787), [#4788](https://github.com/leanprover/lean4/pull/4788), [#4789](https://github.com/leanprover/lean4/pull/4789), [#4807](https://github.com/leanprover/lean4/pull/4807), [#4772](https://github.com/leanprover/lean4/pull/4772)
* [#4809](https://github.com/leanprover/lean4/pull/4809) makes unnecessary `termination_by` clauses cause warnings, not errors.
* [#4831](https://github.com/leanprover/lean4/pull/4831) improves handling of nested structural recursion through non-recursive types.
* [#4839](https://github.com/leanprover/lean4/pull/4839) improves support for structural recursive over inductive predicates when there are reflexive arguments.
* `simp` tactic
* [#4784](https://github.com/leanprover/lean4/pull/4784) sets configuration `Simp.Config.implicitDefEqProofs` to `true` by default.
* `omega` tactic
* [#4612](https://github.com/leanprover/lean4/pull/4612) normalizes the order that constraints appear in error messages.
* [#4695](https://github.com/leanprover/lean4/pull/4695) prevents pushing casts into multiplications unless it produces a non-trivial linear combination.
* [#4989](https://github.com/leanprover/lean4/pull/4989) fixes a regression.
* `decide` tactic
* [#4711](https://github.com/leanprover/lean4/pull/4711) switches from using default transparency to *at least* default transparency when reducing the `Decidable` instance.
* [#4674](https://github.com/leanprover/lean4/pull/4674) adds detailed feedback on `decide` tactic failure. It tells you which `Decidable` instances it unfolded, if it get stuck on `Eq.rec` it gives a hint about avoiding tactics when defining `Decidable` instances, and if it gets stuck on `Classical.choice` it gives hints about classical instances being in scope. During this process, it processes `Decidable.rec`s and matches to pin blame on a non-reducing instance.
* `@[ext]` attribute
* [#4543](https://github.com/leanprover/lean4/pull/4543) and [#4762](https://github.com/leanprover/lean4/pull/4762) make `@[ext]` realize `ext_iff` theorems from user `ext` theorems. Fixes the attribute so that `@[local ext]` and `@[scoped ext]` are usable. The `@[ext (iff := false)]` option can be used to turn off `ext_iff` realization.
* [#4694](https://github.com/leanprover/lean4/pull/4694) makes "go to definition" work for the generated lemmas. Also adjusts the core library to make use of `ext_iff` generation.
* [#4710](https://github.com/leanprover/lean4/pull/4710) makes `ext_iff` theorem preserve inst implicit binder types, rather than making all binder types implicit.
* `#eval` command
* [#4810](https://github.com/leanprover/lean4/pull/4810) introduces a safer `#eval` command that prevents evaluation of terms that contain `sorry`. The motivation is that failing tactics, in conjunction with operations such as array accesses, can lead to the Lean process crashing. Users can use the new `#eval!` command to use the previous unsafe behavior. ([#4829](https://github.com/leanprover/lean4/pull/4829) adjusts a test.)
* [#4447](https://github.com/leanprover/lean4/pull/4447) adds `#discr_tree_key` and `#discr_tree_simp_key` commands, for helping debug discrimination tree failures. The `#discr_tree_key t` command prints the discrimination tree keys for a term `t` (or, if it is a single identifier, the type of that constant). It uses the default configuration for generating keys. The `#discr_tree_simp_key` command is similar to `#discr_tree_key`, but treats the underlying type as one of a simp lemma, that is it transforms it into an equality and produces the key of the left-hand side.
For example,
```
#discr_tree_key (∀ {a n : Nat}, bar a (OfNat.ofNat n))
-- bar _ (@OfNat.ofNat Nat _ _)
#discr_tree_simp_key Nat.add_assoc
-- @HAdd.hAdd Nat Nat Nat _ (@HAdd.hAdd Nat Nat Nat _ _ _) _
```
* [#4741](https://github.com/leanprover/lean4/pull/4741) changes option parsing to allow user-defined options from the command line. Initial options are now re-parsed and validated after importing. Command line option assignments prefixed with `weak.` are silently discarded if the option name without the prefix does not exist.
* **Deriving handlers**
* [7253ef](https://github.com/leanprover/lean4/commit/7253ef8751f76bcbe0e6f46dcfa8069699a2bac7) and [a04f3c](https://github.com/leanprover/lean4/commit/a04f3cab5a9fe2870825af6544ca13c5bb766706) improve the construction of the `BEq` deriving handler.
* [86af04](https://github.com/leanprover/lean4/commit/86af04cc08c0dbbe0e735ea13d16edea3465f850) makes `BEq` deriving handler work when there are dependently typed fields.
* [#4826](https://github.com/leanprover/lean4/pull/4826) refactors the `DecidableEq` deriving handle to use `termination_by structural`.
* **Metaprogramming**
* [#4593](https://github.com/leanprover/lean4/pull/4593) adds `unresolveNameGlobalAvoidingLocals`.
* [#4618](https://github.com/leanprover/lean4/pull/4618) deletes deprecated functions from 2022.
* [#4642](https://github.com/leanprover/lean4/pull/4642) adds `Meta.lambdaBoundedTelescope`.
* [#4731](https://github.com/leanprover/lean4/pull/4731) adds `Meta.withErasedFVars`, to enter a context with some fvars erased from the local context.
* [#4777](https://github.com/leanprover/lean4/pull/4777) adds assignment validation at `closeMainGoal`, preventing users from circumventing the occurs check for tactics such as `exact`.
* [#4807](https://github.com/leanprover/lean4/pull/4807) introduces `Lean.Meta.PProdN` module for packing and projecting nested `PProd`s.
* [#5170](https://github.com/leanprover/lean4/pull/5170) fixes `Syntax.unsetTrailing`. A consequence of this is that "go to definition" now works on the last module name in an `import` block (issue [#4958](https://github.com/leanprover/lean4/issues/4958)).
### Language server, widgets, and IDE extensions
* [#4727](https://github.com/leanprover/lean4/pull/4727) makes it so that responses to info view requests come as soon as the relevant tactic has finished execution.
* [#4580](https://github.com/leanprover/lean4/pull/4580) makes it so that whitespace changes do not invalidate imports, and so starting to type the first declaration after imports should no longer cause them to reload.
* [#4780](https://github.com/leanprover/lean4/pull/4780) fixes an issue where hovering over unimported builtin names could result in a panic.
### Pretty printing
* [#4558](https://github.com/leanprover/lean4/pull/4558) fixes the `pp.instantiateMVars` setting and changes the default value to `true`.
* [#4631](https://github.com/leanprover/lean4/pull/4631) makes sure syntax nodes always run their formatters. Fixes an issue where if `ppSpace` appears in a `macro` or `elab` command then it does not format with a space.
* [#4665](https://github.com/leanprover/lean4/pull/4665) fixes a bug where pretty printed signatures (for example in `#check`) were overly hoverable due to `pp.tagAppFns` being set.
* [#4724](https://github.com/leanprover/lean4/pull/4724) makes `match` pretty printer be sensitive to `pp.explicit`, which makes hovering over a `match` in the Infoview show the underlying term.
* [#4764](https://github.com/leanprover/lean4/pull/4764) documents why anonymous constructor notation isn't pretty printed with flattening.
* [#4786](https://github.com/leanprover/lean4/pull/4786) adjusts the parenthesizer so that only the parentheses are hoverable, implemented by having the parentheses "steal" the term info from the parenthesized expression.
* [#4854](https://github.com/leanprover/lean4/pull/4854) allows arbitrarily long sequences of optional arguments to be omitted from the end of applications, versus the previous conservative behavior of omitting up to one optional argument.
### Library
* `Nat`
* [#4597](https://github.com/leanprover/lean4/pull/4597) adds bitwise lemmas `Nat.and_le_(left|right)`.
* [#4874](https://github.com/leanprover/lean4/pull/4874) adds simprocs for simplifying bit expressions.
* `Int`
* [#4903](https://github.com/leanprover/lean4/pull/4903) fixes performance of `HPow Int Nat Int` synthesis by rewriting it as a `NatPow Int` instance.
* `UInt*` and `Fin`
* [#4605](https://github.com/leanprover/lean4/pull/4605) adds lemmas.
* [#4629](https://github.com/leanprover/lean4/pull/4629) adds `*.and_toNat`.
* `Option`
* [#4599](https://github.com/leanprover/lean4/pull/4599) adds `get` lemmas.
* [#4600](https://github.com/leanprover/lean4/pull/4600) adds `Option.or`, a version of `Option.orElse` that is strict in the second argument.
* `GetElem`
* [#4603](https://github.com/leanprover/lean4/pull/4603) adds `getElem_congr` to help with rewriting indices.
* `List` and `Array`
* Upstreamed from Batteries: [#4586](https://github.com/leanprover/lean4/pull/4586) upstreams `List.attach` and `Array.attach`, [#4697](https://github.com/leanprover/lean4/pull/4697) upstreams `List.Subset` and `List.Sublist` and API, [#4706](https://github.com/leanprover/lean4/pull/4706) upstreams basic material on `List.Pairwise` and `List.Nodup`, [#4720](https://github.com/leanprover/lean4/pull/4720) upstreams more `List.erase` API, [#4836](https://github.com/leanprover/lean4/pull/4836) and [#4837](https://github.com/leanprover/lean4/pull/4837) upstream `List.IsPrefix`/`List.IsSuffix`/`List.IsInfix` and add `Decidable` instances, [#4855](https://github.com/leanprover/lean4/pull/4855) upstreams `List.tail`, `List.findIdx`, `List.indexOf`, `List.countP`, `List.count`, and `List.range'`, [#4856](https://github.com/leanprover/lean4/pull/4856) upstreams more List lemmas, [#4866](https://github.com/leanprover/lean4/pull/4866) upstreams `List.pairwise_iff_getElem`, [#4865](https://github.com/leanprover/lean4/pull/4865) upstreams `List.eraseIdx` lemmas.
* [#4687](https://github.com/leanprover/lean4/pull/4687) adjusts `List.replicate` simp lemmas and simprocs.
* [#4704](https://github.com/leanprover/lean4/pull/4704) adds characterizations of `List.Sublist`.
* [#4707](https://github.com/leanprover/lean4/pull/4707) adds simp normal form tests for `List.Pairwise` and `List.Nodup`.
* [#4708](https://github.com/leanprover/lean4/pull/4708) and [#4815](https://github.com/leanprover/lean4/pull/4815) reorganize lemmas on list getters.
* [#4765](https://github.com/leanprover/lean4/pull/4765) adds simprocs for literal array accesses such as `#[1,2,3,4,5][2]`.
* [#4790](https://github.com/leanprover/lean4/pull/4790) removes typeclass assumptions for `List.Nodup.eraseP`.
* [#4801](https://github.com/leanprover/lean4/pull/4801) adds efficient `usize` functions for array types.
* [#4820](https://github.com/leanprover/lean4/pull/4820) changes `List.filterMapM` to run left-to-right.
* [#4835](https://github.com/leanprover/lean4/pull/4835) fills in and cleans up gaps in List API.
* [#4843](https://github.com/leanprover/lean4/pull/4843), [#4868](https://github.com/leanprover/lean4/pull/4868), and [#4877](https://github.com/leanprover/lean4/pull/4877) correct `List.Subset` lemmas.
* [#4863](https://github.com/leanprover/lean4/pull/4863) splits `Init.Data.List.Lemmas` into function-specific files.
* [#4875](https://github.com/leanprover/lean4/pull/4875) fixes statement of `List.take_takeWhile`.
* Lemmas: [#4602](https://github.com/leanprover/lean4/pull/4602), [#4627](https://github.com/leanprover/lean4/pull/4627), [#4678](https://github.com/leanprover/lean4/pull/4678) for `List.head` and `list.getLast`, [#4723](https://github.com/leanprover/lean4/pull/4723) for `List.erase`, [#4742](https://github.com/leanprover/lean4/pull/4742)
* `ByteArray`
* [#4582](https://github.com/leanprover/lean4/pull/4582) eliminates `partial` from `ByteArray.toList` and `ByteArray.findIdx?`.
* `BitVec`
* [#4568](https://github.com/leanprover/lean4/pull/4568) adds recurrence theorems for bitblasting multiplication.
* [#4571](https://github.com/leanprover/lean4/pull/4571) adds `shiftLeftRec` lemmas.
* [#4872](https://github.com/leanprover/lean4/pull/4872) adds `ushiftRightRec` and lemmas.
* [#4873](https://github.com/leanprover/lean4/pull/4873) adds `getLsb_replicate`.
* `Std.HashMap` added:
* [#4583](https://github.com/leanprover/lean4/pull/4583) **adds `Std.HashMap`** as a verified replacement for `Lean.HashMap`. See the PR for naming differences, but [#4725](https://github.com/leanprover/lean4/pull/4725) renames `HashMap.remove` to `HashMap.erase`.
* [#4682](https://github.com/leanprover/lean4/pull/4682) adds `Inhabited` instances.
* [#4732](https://github.com/leanprover/lean4/pull/4732) improves `BEq` argument order in hash map lemmas.
* [#4759](https://github.com/leanprover/lean4/pull/4759) makes lemmas resolve instances via unification.
* [#4771](https://github.com/leanprover/lean4/pull/4771) documents that hash maps should be used linearly to avoid expensive copies.
* [#4791](https://github.com/leanprover/lean4/pull/4791) removes `bif` from hash map lemmas, which is inconvenient to work with in practice.
* [#4803](https://github.com/leanprover/lean4/pull/4803) adds more lemmas.
* `SMap`
* [#4690](https://github.com/leanprover/lean4/pull/4690) upstreams `SMap.foldM`.
* `BEq`
* [#4607](https://github.com/leanprover/lean4/pull/4607) adds `PartialEquivBEq`, `ReflBEq`, `EquivBEq`, and `LawfulHashable` classes.
* `IO`
* [#4660](https://github.com/leanprover/lean4/pull/4660) adds `IO.Process.Child.tryWait`.
* [#4747](https://github.com/leanprover/lean4/pull/4747), [#4730](https://github.com/leanprover/lean4/pull/4730), and [#4756](https://github.com/leanprover/lean4/pull/4756) add `×'` syntax for `PProd`. Adds a delaborator for `PProd` and `MProd` values to pretty print as flattened angle bracket tuples.
* **Other fixes or improvements**
* [#4604](https://github.com/leanprover/lean4/pull/4604) adds lemmas for cond.
* [#4619](https://github.com/leanprover/lean4/pull/4619) changes some definitions into theorems.
* [#4616](https://github.com/leanprover/lean4/pull/4616) fixes some names with duplicated namespaces.
* [#4620](https://github.com/leanprover/lean4/pull/4620) fixes simp lemmas flagged by the simpNF linter.
* [#4666](https://github.com/leanprover/lean4/pull/4666) makes the `Antisymm` class be a `Prop`.
* [#4621](https://github.com/leanprover/lean4/pull/4621) cleans up unused arguments flagged by linter.
* [#4680](https://github.com/leanprover/lean4/pull/4680) adds imports for orphaned `Init` modules.
* [#4679](https://github.com/leanprover/lean4/pull/4679) adds imports for orphaned `Std.Data` modules.
* [#4688](https://github.com/leanprover/lean4/pull/4688) adds forward and backward directions of `not_exists`.
* [#4689](https://github.com/leanprover/lean4/pull/4689) upstreams `eq_iff_true_of_subsingleton`.
* [#4709](https://github.com/leanprover/lean4/pull/4709) fixes precedence handling for `Repr` instances for negative numbers for `Int` and `Float`.
* [#4760](https://github.com/leanprover/lean4/pull/4760) renames `TC` ("transitive closure") to `Relation.TransGen`.
* [#4842](https://github.com/leanprover/lean4/pull/4842) fixes `List` deprecations.
* [#4852](https://github.com/leanprover/lean4/pull/4852) upstreams some Mathlib attributes applied to lemmas.
* [93ac63](https://github.com/leanprover/lean4/commit/93ac635a89daa5a8e8ef33ec96b0bcbb5d7ec1ea) improves proof.
* [#4862](https://github.com/leanprover/lean4/pull/4862) and [#4878](https://github.com/leanprover/lean4/pull/4878) generalize the universe for `PSigma.exists` and rename it to `Exists.of_psigma_prop`.
* Typos: [#4737](https://github.com/leanprover/lean4/pull/4737), [7d2155](https://github.com/leanprover/lean4/commit/7d2155943c67c743409420b4546d47fadf73af1c)
* Docs: [#4782](https://github.com/leanprover/lean4/pull/4782), [#4869](https://github.com/leanprover/lean4/pull/4869), [#4648](https://github.com/leanprover/lean4/pull/4648)
### Lean internals
* **Elaboration**
* [#4596](https://github.com/leanprover/lean4/pull/4596) enforces `isDefEqStuckEx` at `unstuckMVar` procedure, causing isDefEq to throw a stuck defeq exception if the metavariable was created in a previous level. This results in some better error messages, and it helps `rw` succeed in synthesizing instances (see issue [#2736](https://github.com/leanprover/lean4/issues/2736)).
* [#4713](https://github.com/leanprover/lean4/pull/4713) fixes deprecation warnings when there are overloaded symbols.
* `elab_as_elim` algorithm:
* [#4722](https://github.com/leanprover/lean4/pull/4722) adds check that inferred motive is type-correct.
* [#4800](https://github.com/leanprover/lean4/pull/4800) elaborates arguments for parameters appearing in the types of targets.
* [#4817](https://github.com/leanprover/lean4/pull/4817) makes the algorithm correctly handle eliminators with explicit motive arguments.
* [#4792](https://github.com/leanprover/lean4/pull/4792) adds term elaborator for `Lean.Parser.Term.namedPattern` (e.g. `n@(n' + 1)`) to report errors when used in non-pattern-matching contexts.
* [#4818](https://github.com/leanprover/lean4/pull/4818) makes anonymous dot notation work when the expected type is a pi-type-valued type synonym.
* **Typeclass inference**
* [#4646](https://github.com/leanprover/lean4/pull/4646) improves `synthAppInstances`, the function responsible for synthesizing instances for the `rw` and `apply` tactics. Adds a synthesis loop to handle functions whose instances need to be synthesized in a complex order.
* **Inductive types**
* [#4684](https://github.com/leanprover/lean4/pull/4684) (backported as [98ee78](https://github.com/leanprover/lean4/commit/98ee789990f91ff5935627787b537911ef8773c4)) refactors `InductiveVal` to have a `numNested : Nat` field instead of `isNested : Bool`. This modifies the kernel.
* **Definitions**
* [#4776](https://github.com/leanprover/lean4/pull/4776) improves performance of `Replacement.apply`.
* [#4712](https://github.com/leanprover/lean4/pull/4712) fixes `.eq_def` theorem generation with messy universes.
* [#4841](https://github.com/leanprover/lean4/pull/4841) improves success of finding `T.below x` hypothesis when transforming `match` statements for `IndPredBelow`.
* **Diagnostics and profiling**
* [#4611](https://github.com/leanprover/lean4/pull/4611) makes kernel diagnostics appear when `diagnostics` is enabled even if it is the only section.
* [#4753](https://github.com/leanprover/lean4/pull/4753) adds missing `profileitM` functions.
* [#4754](https://github.com/leanprover/lean4/pull/4754) adds `Lean.Expr.numObjs` to compute the number of allocated sub-expressions in a given expression, primarily for diagnosing performance issues.
* [#4769](https://github.com/leanprover/lean4/pull/4769) adds missing `withTraceNode`s to improve `trace.profiler` output.
* [#4781](https://github.com/leanprover/lean4/pull/4781) and [#4882](https://github.com/leanprover/lean4/pull/4882) make the "use `set_option diagnostics true`" message be conditional on current setting of `diagnostics`.
* **Performance**
* [#4767](https://github.com/leanprover/lean4/pull/4767), [#4775](https://github.com/leanprover/lean4/pull/4775), and [#4887](https://github.com/leanprover/lean4/pull/4887) add `ShareCommon.shareCommon'` for sharing common terms. In an example with 16 million subterms, it is 20 times faster than the old `shareCommon` procedure.
* [#4779](https://github.com/leanprover/lean4/pull/4779) ensures `Expr.replaceExpr` preserves DAG structure in `Expr`s.
* [#4783](https://github.com/leanprover/lean4/pull/4783) documents performance issue in `Expr.replaceExpr`.
* [#4794](https://github.com/leanprover/lean4/pull/4794), [#4797](https://github.com/leanprover/lean4/pull/4797), [#4798](https://github.com/leanprover/lean4/pull/4798) make `for_each` use precise cache.
* [#4795](https://github.com/leanprover/lean4/pull/4795) makes `Expr.find?` and `Expr.findExt?` use the kernel implementations.
* [#4799](https://github.com/leanprover/lean4/pull/4799) makes `Expr.replace` use the kernel implementation.
* [#4871](https://github.com/leanprover/lean4/pull/4871) makes `Expr.foldConsts` use a precise cache.
* [#4890](https://github.com/leanprover/lean4/pull/4890) makes `expr_eq_fn` use a precise cache.
* **Utilities**
* [#4453](https://github.com/leanprover/lean4/pull/4453) upstreams `ToExpr FilePath` and `compile_time_search_path%`.
* **Module system**
* [#4652](https://github.com/leanprover/lean4/pull/4652) fixes handling of `const2ModIdx` in `finalizeImport`, making it prefer the original module for a declaration when a declaration is re-declared.
* **Kernel**
* [#4637](https://github.com/leanprover/lean4/pull/4637) adds a check to prevent large `Nat` exponentiations from evaluating. Elaborator reduction is controlled by the option `exponentiation.threshold`.
* [#4683](https://github.com/leanprover/lean4/pull/4683) updates comments in `kernel/declaration.h`, making sure they reflect the current Lean 4 types.
* [#4796](https://github.com/leanprover/lean4/pull/4796) improves performance by using `replace` with a precise cache.
* [#4700](https://github.com/leanprover/lean4/pull/4700) improves performance by fixing the implementation of move constructors and move assignment operators. Expression copying was taking 10% of total runtime in some workloads. See issue [#4698](https://github.com/leanprover/lean4/issues/4698).
* [#4702](https://github.com/leanprover/lean4/pull/4702) improves performance in `replace_rec_fn::apply` by avoiding expression copies. These copies represented about 13% of time spent in `save_result` in some workloads. See the same issue.
* **Other fixes or improvements**
* [#4590](https://github.com/leanprover/lean4/pull/4590) fixes a typo in some constants and `trace.profiler.useHeartbeats`.
* [#4617](https://github.com/leanprover/lean4/pull/4617) add 'since' dates to `deprecated` attributes.
* [#4625](https://github.com/leanprover/lean4/pull/4625) improves the robustness of the constructor-as-variable test.
* [#4740](https://github.com/leanprover/lean4/pull/4740) extends test with nice example reported on Zulip.
* [#4766](https://github.com/leanprover/lean4/pull/4766) moves `Syntax.hasIdent` to be available earlier and shakes dependencies.
* [#4881](https://github.com/leanprover/lean4/pull/4881) splits out `Lean.Language.Lean.Types`.
* [#4893](https://github.com/leanprover/lean4/pull/4893) adds `LEAN_EXPORT` for `sharecommon` functions.
* Typos: [#4635](https://github.com/leanprover/lean4/pull/4635), [#4719](https://github.com/leanprover/lean4/pull/4719), [af40e6](https://github.com/leanprover/lean4/commit/af40e618111581c82fc44de922368a02208b499f)
* Docs: [#4748](https://github.com/leanprover/lean4/pull/4748) (`Command.Scope`)
### Compiler, runtime, and FFI
* [#4661](https://github.com/leanprover/lean4/pull/4661) moves `Std` from `libleanshared` to much smaller `libInit_shared`. This fixes the Windows build.
* [#4668](https://github.com/leanprover/lean4/pull/4668) fixes initialization, explicitly initializing `Std` in `lean_initialize`.
* [#4746](https://github.com/leanprover/lean4/pull/4746) adjusts `shouldExport` to exclude more symbols to get below Windows symbol limit. Some exceptions are added by [#4884](https://github.com/leanprover/lean4/pull/4884) and [#4956](https://github.com/leanprover/lean4/pull/4956) to support Verso.
* [#4778](https://github.com/leanprover/lean4/pull/4778) adds `lean_is_exclusive_obj` (`Lean.isExclusiveUnsafe`) and `lean_set_external_data`.
* [#4515](https://github.com/leanprover/lean4/pull/4515) fixes calling programs with spaces on Windows.
### Lake
* [#4735](https://github.com/leanprover/lean4/pull/4735) improves a number of elements related to Git checkouts, cloud releases,
and related error handling.
* On error, Lake now prints all top-level logs. Top-level logs are those produced by Lake outside of the job monitor (e.g., when cloning dependencies).
* When fetching a remote for a dependency, Lake now forcibly fetches tags. This prevents potential errors caused by a repository recreating tags already fetched.
* Git error handling is now more informative.
* The builtin package facets `release`, `optRelease`, `extraDep` are now captions in the same manner as other facets.
* `afterReleaseSync` and `afterReleaseAsync` now fetch `optRelease` rather than `release`.
* Added support for optional jobs, whose failure does not cause the whole build to failure. Now `optRelease` is such a job.
* [#4608](https://github.com/leanprover/lean4/pull/4608) adds draft CI workflow when creating new projects.
* [#4847](https://github.com/leanprover/lean4/pull/4847) adds CLI options to control log levels. The `--log-level=<lv>` controls the minimum log level Lake should output. For instance, `--log-level=error` will only print errors (not warnings or info). Also, adds an analogous `--fail-level` option to control the minimum log level for build failures. The existing `--iofail` and `--wfail` options are respectively equivalent to `--fail-level=info` and `--fail-level=warning`.
* Docs: [#4853](https://github.com/leanprover/lean4/pull/4853)
### DevOps/CI
* **Workflows**
* [#4531](https://github.com/leanprover/lean4/pull/4531) makes release trigger an update of `release.lean-lang.org`.
* [#4598](https://github.com/leanprover/lean4/pull/4598) adjusts `pr-release` to the new `lakefile.lean` syntax.
* [#4632](https://github.com/leanprover/lean4/pull/4632) makes `pr-release` use the correct tag name.
* [#4638](https://github.com/leanprover/lean4/pull/4638) adds ability to manually trigger nightly release.
* [#4640](https://github.com/leanprover/lean4/pull/4640) adds more debugging output for `restart-on-label` CI.
* [#4663](https://github.com/leanprover/lean4/pull/4663) bumps up waiting for 10s to 30s for `restart-on-label`.
* [#4664](https://github.com/leanprover/lean4/pull/4664) bumps versions for `actions/checkout` and `actions/upload-artifacts`.
* [582d6e](https://github.com/leanprover/lean4/commit/582d6e7f7168e0dc0819099edaace27d913b893e) bumps version for `actions/download-artifact`.
* [6d9718](https://github.com/leanprover/lean4/commit/6d971827e253a4dc08cda3cf6524d7f37819eb47) adds back dropped `check-stage3`.
* [0768ad](https://github.com/leanprover/lean4/commit/0768ad4eb9020af0777587a25a692d181e857c14) adds Jira sync (for FRO).
* [#4830](https://github.com/leanprover/lean4/pull/4830) adds support to report CI errors on FRO Zulip.
* [#4838](https://github.com/leanprover/lean4/pull/4838) adds trigger for `nightly_bump_toolchain` on mathlib4 upon nightly release.
* [abf420](https://github.com/leanprover/lean4/commit/abf4206e9c0fcadf17b6f7933434fd1580175015) fixes msys2.
* [#4895](https://github.com/leanprover/lean4/pull/4895) deprecates Nix-based builds and removes interactive components. Users who prefer the flake build should maintain it externally.
* [#4693](https://github.com/leanprover/lean4/pull/4693), [#4458](https://github.com/leanprover/lean4/pull/4458), and [#4876](https://github.com/leanprover/lean4/pull/4876) update the **release checklist**.
* [#4669](https://github.com/leanprover/lean4/pull/4669) fixes the "max dynamic symbols" metric per static library.
* [#4691](https://github.com/leanprover/lean4/pull/4691) improves compatibility of `tests/list_simp` for retesting simp normal forms with Mathlib.
* [#4806](https://github.com/leanprover/lean4/pull/4806) updates the quickstart guide.
* [c02aa9](https://github.com/leanprover/lean4/commit/c02aa98c6a08c3a9b05f68039c071085a4ef70d7) documents the **triage team** in the contribution guide.
### Breaking changes
* For `@[ext]`-generated `ext` and `ext_iff` lemmas, the `x` and `y` term arguments are now implicit. Furthermore these two lemmas are now protected ([#4543](https://github.com/leanprover/lean4/pull/4543)).
* Now `trace.profiler.useHearbeats` is `trace.profiler.useHeartbeats` ([#4590](https://github.com/leanprover/lean4/pull/4590)).
* A bugfix in the structural recursion code may in some cases break existing code, when a parameter of the type of the recursive argument is bound behind indices of that type. This can usually be fixed by reordering the parameters of the function ([#4672](https://github.com/leanprover/lean4/pull/4672)).
* Now `List.filterMapM` sequences monadic actions left-to-right ([#4820](https://github.com/leanprover/lean4/pull/4820)).
* The effect of the `variable` command on proofs of `theorem`s has been changed. Whether such section variables are accessible in the proof now depends only on the theorem signature and other top-level commands, not on the proof itself. This change ensures that
* the statement of a theorem is independent of its proof. In other words, changes in the proof cannot change the theorem statement.
* tactics such as `induction` cannot accidentally include a section variable.
* the proof can be elaborated in parallel to subsequent declarations in a future version of Lean.
The effect of `variable`s on the theorem header as well as on other kinds of declarations is unchanged.
Specifically, section variables are included if they
* are directly referenced by the theorem header,
* are included via the new `include` command in the current section and not subsequently mentioned in an `omit` statement,
* are directly referenced by any variable included by these rules, OR
* are instance-implicit variables that reference only variables included by these rules.
For porting, a new option `deprecated.oldSectionVars` is included to locally switch back to the old behavior.

312
releases/v4.12.0.md Normal file
View File

@@ -0,0 +1,312 @@
v4.12.0
----------
### Language features, tactics, and metaprograms
* `bv_decide` tactic. This release introduces a new tactic for proving goals involving `BitVec` and `Bool`. It reduces the goal to a SAT instance that is refuted by an external solver, and the resulting LRAT proof is checked in Lean. This is used to synthesize a proof of the goal by reflection. As this process uses verified algorithms, proofs generated by this tactic use `Lean.ofReduceBool`, so this tactic includes the Lean compiler as part of the trusted code base. The external solver CaDiCaL is included with Lean and does not need to be installed separately to make use of `bv_decide`.
For example, we can use `bv_decide` to verify that a bit twiddling formula leaves at most one bit set:
```lean
def popcount (x : BitVec 64) : BitVec 64 :=
let rec go (x pop : BitVec 64) : Nat → BitVec 64
| 0 => pop
| n + 1 => go (x >>> 2) (pop + (x &&& 1)) n
go x 0 64
example (x : BitVec 64) : popcount ((x &&& (x - 1)) ^^^ x) ≤ 1 := by
simp only [popcount, popcount.go]
bv_decide
```
When the external solver fails to refute the SAT instance generated by `bv_decide`, it can report a counterexample:
```lean
/--
error: The prover found a counterexample, consider the following assignment:
x = 0xffffffffffffffff#64
-/
#guard_msgs in
example (x : BitVec 64) : x < x + 1 := by
bv_decide
```
See `Lean.Elab.Tactic.BVDecide` for a more detailed overview, and look in `tests/lean/run/bv_*` for examples.
[#5013](https://github.com/leanprover/lean4/pull/5013), [#5074](https://github.com/leanprover/lean4/pull/5074), [#5100](https://github.com/leanprover/lean4/pull/5100), [#5113](https://github.com/leanprover/lean4/pull/5113), [#5137](https://github.com/leanprover/lean4/pull/5137), [#5203](https://github.com/leanprover/lean4/pull/5203), [#5212](https://github.com/leanprover/lean4/pull/5212), [#5220](https://github.com/leanprover/lean4/pull/5220).
* `simp` tactic
* [#4988](https://github.com/leanprover/lean4/pull/4988) fixes a panic in the `reducePow` simproc.
* [#5071](https://github.com/leanprover/lean4/pull/5071) exposes the `index` option to the `dsimp` tactic, introduced to `simp` in [#4202](https://github.com/leanprover/lean4/pull/4202).
* [#5159](https://github.com/leanprover/lean4/pull/5159) fixes a panic at `Fin.isValue` simproc.
* [#5167](https://github.com/leanprover/lean4/pull/5167) and [#5175](https://github.com/leanprover/lean4/pull/5175) rename the `simpCtorEq` simproc to `reduceCtorEq` and makes it optional. (See breaking changes.)
* [#5187](https://github.com/leanprover/lean4/pull/5187) ensures `reduceCtorEq` is enabled in the `norm_cast` tactic.
* [#5073](https://github.com/leanprover/lean4/pull/5073) modifies the simp debug trace messages to tag with "dpre" and "dpost" instead of "pre" and "post" when in definitional rewrite mode. [#5054](https://github.com/leanprover/lean4/pull/5054) explains the `reduce` steps for `trace.Debug.Meta.Tactic.simp` trace messages.
* `ext` tactic
* [#4996](https://github.com/leanprover/lean4/pull/4996) reduces default maximum iteration depth from 1000000 to 100.
* `induction` tactic
* [#5117](https://github.com/leanprover/lean4/pull/5117) fixes a bug where `let` bindings in minor premises wouldn't be counted correctly.
* `omega` tactic
* [#5157](https://github.com/leanprover/lean4/pull/5157) fixes a panic.
* `conv` tactic
* [#5149](https://github.com/leanprover/lean4/pull/5149) improves `arg n` to handle subsingleton instance arguments.
* [#5044](https://github.com/leanprover/lean4/pull/5044) upstreams the `#time` command.
* [#5079](https://github.com/leanprover/lean4/pull/5079) makes `#check` and `#reduce` typecheck the elaborated terms.
* **Incrementality**
* [#4974](https://github.com/leanprover/lean4/pull/4974) fixes regression where we would not interrupt elaboration of previous document versions.
* [#5004](https://github.com/leanprover/lean4/pull/5004) fixes a performance regression.
* [#5001](https://github.com/leanprover/lean4/pull/5001) disables incremental body elaboration in presence of `where` clauses in declarations.
* [#5018](https://github.com/leanprover/lean4/pull/5018) enables infotrees on the command line for ilean generation.
* [#5040](https://github.com/leanprover/lean4/pull/5040) and [#5056](https://github.com/leanprover/lean4/pull/5056) improve performance of info trees.
* [#5090](https://github.com/leanprover/lean4/pull/5090) disables incrementality in the `case .. | ..` tactic.
* [#5312](https://github.com/leanprover/lean4/pull/5312) fixes a bug where changing whitespace after the module header could break subsequent commands.
* **Definitions**
* [#5016](https://github.com/leanprover/lean4/pull/5016) and [#5066](https://github.com/leanprover/lean4/pull/5066) add `clean_wf` tactic to clean up tactic state in `decreasing_by`. This can be disabled with `set_option debug.rawDecreasingByGoal false`.
* [#5055](https://github.com/leanprover/lean4/pull/5055) unifies equational theorems between structural and well-founded recursion.
* [#5041](https://github.com/leanprover/lean4/pull/5041) allows mutually recursive functions to use different parameter names among the “fixed parameter prefix”
* [#4154](https://github.com/leanprover/lean4/pull/4154) and [#5109](https://github.com/leanprover/lean4/pull/5109) add fine-grained equational lemmas for non-recursive functions. See breaking changes.
* [#5129](https://github.com/leanprover/lean4/pull/5129) unifies equation lemmas for recursive and non-recursive definitions. The `backward.eqns.deepRecursiveSplit` option can be set to `false` to get the old behavior. See breaking changes.
* [#5141](https://github.com/leanprover/lean4/pull/5141) adds `f.eq_unfold` lemmas. Now Lean produces the following zoo of rewrite rules:
```
Option.map.eq_1 : Option.map f none = none
Option.map.eq_2 : Option.map f (some x) = some (f x)
Option.map.eq_def : Option.map f p = match o with | none => none | (some x) => some (f x)
Option.map.eq_unfold : Option.map = fun f p => match o with | none => none | (some x) => some (f x)
```
The `f.eq_unfold` variant is especially useful to rewrite with `rw` under binders.
* [#5136](https://github.com/leanprover/lean4/pull/5136) fixes bugs in recursion over predicates.
* **Variable inclusion**
* [#5206](https://github.com/leanprover/lean4/pull/5206) documents that `include` currently only applies to theorems.
* **Elaboration**
* [#4926](https://github.com/leanprover/lean4/pull/4926) fixes a bug where autoparam errors were associated to an incorrect source position.
* [#4833](https://github.com/leanprover/lean4/pull/4833) fixes an issue where cdot anonymous functions (e.g. `(· + ·)`) would not handle ambiguous notation correctly. Numbers the parameters, making this example expand as `fun x1 x2 => x1 + x2` rather than `fun x x_1 => x + x_1`.
* [#5037](https://github.com/leanprover/lean4/pull/5037) improves strength of the tactic that proves array indexing is in bounds.
* [#5119](https://github.com/leanprover/lean4/pull/5119) fixes a bug in the tactic that proves indexing is in bounds where it could loop in the presence of mvars.
* [#5072](https://github.com/leanprover/lean4/pull/5072) makes the structure type clickable in "not a field of structure" errors for structure instance notation.
* [#4717](https://github.com/leanprover/lean4/pull/4717) fixes a bug where mutual `inductive` commands could create terms that the kernel rejects.
* [#5142](https://github.com/leanprover/lean4/pull/5142) fixes a bug where `variable` could fail when mixing binder updates and declarations.
* **Other fixes or improvements**
* [#5118](https://github.com/leanprover/lean4/pull/5118) changes the definition of the `syntheticHole` parser so that hovering over `_` in `?_` gives the docstring for synthetic holes.
* [#5173](https://github.com/leanprover/lean4/pull/5173) uses the emoji variant selector for ✅️,❌️,💥️ in messages, improving fonts selection.
* [#5183](https://github.com/leanprover/lean4/pull/5183) fixes a bug in `rename_i` where implementation detail hypotheses could be renamed.
### Language server, widgets, and IDE extensions
* [#4821](https://github.com/leanprover/lean4/pull/4821) resolves two language server bugs that especially affect Windows users. (1) Editing the header could result in the watchdog not correctly restarting the file worker, which would lead to the file seemingly being processed forever. (2) On an especially slow Windows machine, we found that starting the language server would sometimes not succeed at all. This PR also resolves an issue where we would not correctly emit messages that we received while the file worker is being restarted to the corresponding file worker after the restart.
* [#5006](https://github.com/leanprover/lean4/pull/5006) updates the user widget manual.
* [#5193](https://github.com/leanprover/lean4/pull/5193) updates the quickstart guide with the new display name for the Lean 4 extension ("Lean 4").
* [#5185](https://github.com/leanprover/lean4/pull/5185) fixes a bug where over time "import out of date" messages would accumulate.
* [#4900](https://github.com/leanprover/lean4/pull/4900) improves ilean loading performance by about a factor of two. Optimizes the JSON parser and the conversion from JSON to Lean data structures; see PR description for details.
* **Other fixes or improvements**
* [#5031](https://github.com/leanprover/lean4/pull/5031) localizes an instance in `Lsp.Diagnostics`.
### Pretty printing
* [#4976](https://github.com/leanprover/lean4/pull/4976) introduces `@[app_delab]`, a macro for creating delaborators for particular constants. The `@[app_delab ident]` syntax resolves `ident` to its constant name `name` and then expands to `@[delab app.name]`.
* [#4982](https://github.com/leanprover/lean4/pull/4982) fixes a bug where the pretty printer assumed structure projections were type correct (such terms can appear in type mismatch errors). Improves hoverability of `#print` output for structures.
* [#5218](https://github.com/leanprover/lean4/pull/5218) and [#5239](https://github.com/leanprover/lean4/pull/5239) add `pp.exprSizes` debugging option. When true, each pretty printed expression is prefixed with `[size a/b/c]`, where `a` is the size without sharing, `b` is the actual size, and `c` is the size with the maximum possible sharing.
### Library
* [#5020](https://github.com/leanprover/lean4/pull/5020) swaps the parameters to `Membership.mem`. A purpose of this change is to make set-like `CoeSort` coercions to refer to the eta-expanded function `fun x => Membership.mem s x`, which can reduce in many computations. Another is that having the `s` argument first leads to better discrimination tree keys. (See breaking changes.)
* `Array`
* [#4970](https://github.com/leanprover/lean4/pull/4970) adds `@[ext]` attribute to `Array.ext`.
* [#4957](https://github.com/leanprover/lean4/pull/4957) deprecates `Array.get_modify`.
* `List`
* [#4995](https://github.com/leanprover/lean4/pull/4995) upstreams `List.findIdx` lemmas.
* [#5029](https://github.com/leanprover/lean4/pull/5029), [#5048](https://github.com/leanprover/lean4/pull/5048) and [#5132](https://github.com/leanprover/lean4/pull/5132) add `List.Sublist` lemmas, some upstreamed. [#5077](https://github.com/leanprover/lean4/pull/5077) fixes implicitness in refl/rfl lemma binders. add `List.Sublist` theorems.
* [#5047](https://github.com/leanprover/lean4/pull/5047) upstreams `List.Pairwise` lemmas.
* [#5053](https://github.com/leanprover/lean4/pull/5053), [#5124](https://github.com/leanprover/lean4/pull/5124), and [#5161](https://github.com/leanprover/lean4/pull/5161) add `List.find?/findSome?/findIdx?` theorems.
* [#5039](https://github.com/leanprover/lean4/pull/5039) adds `List.foldlRecOn` and `List.foldrRecOn` recursion principles to prove things about `List.foldl` and `List.foldr`.
* [#5069](https://github.com/leanprover/lean4/pull/5069) upstreams `List.Perm`.
* [#5092](https://github.com/leanprover/lean4/pull/5092) and [#5107](https://github.com/leanprover/lean4/pull/5107) add `List.mergeSort` and a fast `@[csimp]` implementation.
* [#5103](https://github.com/leanprover/lean4/pull/5103) makes the simp lemmas for `List.subset` more aggressive.
* [#5106](https://github.com/leanprover/lean4/pull/5106) changes the statement of `List.getLast?_cons`.
* [#5123](https://github.com/leanprover/lean4/pull/5123) and [#5158](https://github.com/leanprover/lean4/pull/5158) add `List.range` and `List.iota` lemmas.
* [#5130](https://github.com/leanprover/lean4/pull/5130) adds `List.join` lemmas.
* [#5131](https://github.com/leanprover/lean4/pull/5131) adds `List.append` lemmas.
* [#5152](https://github.com/leanprover/lean4/pull/5152) adds `List.erase(|P|Idx)` lemmas.
* [#5127](https://github.com/leanprover/lean4/pull/5127) makes miscellaneous lemma updates.
* [#5153](https://github.com/leanprover/lean4/pull/5153) and [#5160](https://github.com/leanprover/lean4/pull/5160) add lemmas about `List.attach` and `List.pmap`.
* [#5164](https://github.com/leanprover/lean4/pull/5164), [#5177](https://github.com/leanprover/lean4/pull/5177), and [#5215](https://github.com/leanprover/lean4/pull/5215) add `List.find?` and `List.range'/range/iota` lemmas.
* [#5196](https://github.com/leanprover/lean4/pull/5196) adds `List.Pairwise_erase` and related lemmas.
* [#5151](https://github.com/leanprover/lean4/pull/5151) and [#5163](https://github.com/leanprover/lean4/pull/5163) improve confluence of `List` simp lemmas. [#5105](https://github.com/leanprover/lean4/pull/5105) and [#5102](https://github.com/leanprover/lean4/pull/5102) adjust `List` simp lemmas.
* [#5178](https://github.com/leanprover/lean4/pull/5178) removes `List.getLast_eq_iff_getLast_eq_some` as a simp lemma.
* [#5210](https://github.com/leanprover/lean4/pull/5210) reverses the meaning of `List.getElem_drop` and `List.getElem_drop'`.
* [#5214](https://github.com/leanprover/lean4/pull/5214) moves `@[csimp]` lemmas earlier where possible.
* `Nat` and `Int`
* [#5104](https://github.com/leanprover/lean4/pull/5104) adds `Nat.add_left_eq_self` and relatives.
* [#5146](https://github.com/leanprover/lean4/pull/5146) adds missing `Nat.and_xor_distrib_(left|right)`.
* [#5148](https://github.com/leanprover/lean4/pull/5148) and [#5190](https://github.com/leanprover/lean4/pull/5190) improve `Nat` and `Int` simp lemma confluence.
* [#5165](https://github.com/leanprover/lean4/pull/5165) adjusts `Int` simp lemmas.
* [#5166](https://github.com/leanprover/lean4/pull/5166) adds `Int` lemmas relating `neg` and `emod`/`mod`.
* [#5208](https://github.com/leanprover/lean4/pull/5208) reverses the direction of the `Int.toNat_sub` simp lemma.
* [#5209](https://github.com/leanprover/lean4/pull/5209) adds `Nat.bitwise` lemmas.
* [#5230](https://github.com/leanprover/lean4/pull/5230) corrects the docstrings for integer division and modulus.
* `Option`
* [#5128](https://github.com/leanprover/lean4/pull/5128) and [#5154](https://github.com/leanprover/lean4/pull/5154) add `Option` lemmas.
* `BitVec`
* [#4889](https://github.com/leanprover/lean4/pull/4889) adds `sshiftRight` bitblasting.
* [#4981](https://github.com/leanprover/lean4/pull/4981) adds `Std.Associative` and `Std.Commutative` instances for `BitVec.[and|or|xor]`.
* [#4913](https://github.com/leanprover/lean4/pull/4913) enables `missingDocs` error for `BitVec` modules.
* [#4930](https://github.com/leanprover/lean4/pull/4930) makes parameter names for `BitVec` more consistent.
* [#5098](https://github.com/leanprover/lean4/pull/5098) adds `BitVec.intMin`. Introduces `boolToPropSimps` simp set for converting from boolean to propositional expressions.
* [#5200](https://github.com/leanprover/lean4/pull/5200) and [#5217](https://github.com/leanprover/lean4/pull/5217) rename `BitVec.getLsb` to `BitVec.getLsbD`, etc., to bring naming in line with `List`/`Array`/etc.
* **Theorems:** [#4977](https://github.com/leanprover/lean4/pull/4977), [#4951](https://github.com/leanprover/lean4/pull/4951), [#4667](https://github.com/leanprover/lean4/pull/4667), [#5007](https://github.com/leanprover/lean4/pull/5007), [#4997](https://github.com/leanprover/lean4/pull/4997), [#5083](https://github.com/leanprover/lean4/pull/5083), [#5081](https://github.com/leanprover/lean4/pull/5081), [#4392](https://github.com/leanprover/lean4/pull/4392)
* `UInt`
* [#4514](https://github.com/leanprover/lean4/pull/4514) fixes naming convention for `UInt` lemmas.
* `Std.HashMap` and `Std.HashSet`
* [#4943](https://github.com/leanprover/lean4/pull/4943) deprecates variants of hash map query methods. (See breaking changes.)
* [#4917](https://github.com/leanprover/lean4/pull/4917) switches the library and Lean to `Std.HashMap` and `Std.HashSet` almost everywhere.
* [#4954](https://github.com/leanprover/lean4/pull/4954) deprecates `Lean.HashMap` and `Lean.HashSet`.
* [#5023](https://github.com/leanprover/lean4/pull/5023) cleans up lemma parameters.
* `Std.Sat` (for `bv_decide`)
* [#4933](https://github.com/leanprover/lean4/pull/4933) adds definitions of SAT and CNF.
* [#4953](https://github.com/leanprover/lean4/pull/4953) defines "and-inverter graphs" (AIGs) as described in section 3 of [Davis-Swords 2013](https://arxiv.org/pdf/1304.7861.pdf).
* **Parsec**
* [#4774](https://github.com/leanprover/lean4/pull/4774) generalizes the `Parsec` library, allowing parsing of iterable data beyond `String` such as `ByteArray`. (See breaking changes.)
* [#5115](https://github.com/leanprover/lean4/pull/5115) moves `Lean.Data.Parsec` to `Std.Internal.Parsec` for bootstrappng reasons.
* `Thunk`
* [#4969](https://github.com/leanprover/lean4/pull/4969) upstreams `Thunk.ext`.
* **IO**
* [#4973](https://github.com/leanprover/lean4/pull/4973) modifies `IO.FS.lines` to handle `\r\n` on all operating systems instead of just on Windows.
* [#5125](https://github.com/leanprover/lean4/pull/5125) adds `createTempFile` and `withTempFile` for creating temporary files that can only be read and written by the current user.
* **Other fixes or improvements**
* [#4945](https://github.com/leanprover/lean4/pull/4945) adds `Array`, `Bool` and `Prod` utilities from LeanSAT.
* [#4960](https://github.com/leanprover/lean4/pull/4960) adds `Relation.TransGen.trans`.
* [#5012](https://github.com/leanprover/lean4/pull/5012) states `WellFoundedRelation Nat` using `<`, not `Nat.lt`.
* [#5011](https://github.com/leanprover/lean4/pull/5011) uses `` instead of `Not (Eq ...)` in `Fin.ne_of_val_ne`.
* [#5197](https://github.com/leanprover/lean4/pull/5197) upstreams `Fin.le_antisymm`.
* [#5042](https://github.com/leanprover/lean4/pull/5042) reduces usage of `refine'`.
* [#5101](https://github.com/leanprover/lean4/pull/5101) adds about `if-then-else` and `Option`.
* [#5112](https://github.com/leanprover/lean4/pull/5112) adds basic instances for `ULift` and `PLift`.
* [#5133](https://github.com/leanprover/lean4/pull/5133) and [#5168](https://github.com/leanprover/lean4/pull/5168) make fixes from running the simpNF linter over Lean.
* [#5156](https://github.com/leanprover/lean4/pull/5156) removes a bad simp lemma in `omega` theory.
* [#5155](https://github.com/leanprover/lean4/pull/5155) improves confluence of `Bool` simp lemmas.
* [#5162](https://github.com/leanprover/lean4/pull/5162) improves confluence of `Function.comp` simp lemmas.
* [#5191](https://github.com/leanprover/lean4/pull/5191) improves confluence of `if-then-else` simp lemmas.
* [#5147](https://github.com/leanprover/lean4/pull/5147) adds `@[elab_as_elim]` to `Quot.rec`, `Nat.strongInductionOn` and `Nat.casesStrongInductionOn`, and also renames the latter two to `Nat.strongRecOn` and `Nat.casesStrongRecOn` (deprecated in [#5179](https://github.com/leanprover/lean4/pull/5179)).
* [#5180](https://github.com/leanprover/lean4/pull/5180) disables some simp lemmas with bad discrimination tree keys.
* [#5189](https://github.com/leanprover/lean4/pull/5189) cleans up internal simp lemmas that had leaked.
* [#5198](https://github.com/leanprover/lean4/pull/5198) cleans up `allowUnsafeReducibility`.
* [#5229](https://github.com/leanprover/lean4/pull/5229) removes unused lemmas from some `simp` tactics.
* [#5199](https://github.com/leanprover/lean4/pull/5199) removes >6 month deprecations.
### Lean internals
* **Performance**
* Some core algorithms have been rewritten in C++ for performance.
* [#4910](https://github.com/leanprover/lean4/pull/4910) and [#4912](https://github.com/leanprover/lean4/pull/4912) reimplement `instantiateLevelMVars`.
* [#4915](https://github.com/leanprover/lean4/pull/4915), [#4922](https://github.com/leanprover/lean4/pull/4922), and [#4931](https://github.com/leanprover/lean4/pull/4931) reimplement `instantiateExprMVars`, 30% faster on a benchmark.
* [#4934](https://github.com/leanprover/lean4/pull/4934) has optimizations for the kernel's `Expr` equality test.
* [#4990](https://github.com/leanprover/lean4/pull/4990) fixes bug in hashing for the kernel's `Expr` equality test.
* [#4935](https://github.com/leanprover/lean4/pull/4935) and [#4936](https://github.com/leanprover/lean4/pull/4936) skip some `PreDefinition` transformations if they are not needed.
* [#5225](https://github.com/leanprover/lean4/pull/5225) adds caching for visited exprs at `CheckAssignmentQuick` in `ExprDefEq`.
* [#5226](https://github.com/leanprover/lean4/pull/5226) maximizes term sharing at `instantiateMVarDeclMVars`, used by `runTactic`.
* **Diagnostics and profiling**
* [#4923](https://github.com/leanprover/lean4/pull/4923) adds profiling for `instantiateMVars` in `Lean.Elab.MutualDef`, which can be a bottleneck there.
* [#4924](https://github.com/leanprover/lean4/pull/4924) adds diagnostics for large theorems, controlled by the `diagnostics.threshold.proofSize` option.
* [#4897](https://github.com/leanprover/lean4/pull/4897) improves display of diagnostic results.
* **Other fixes or improvements**
* [#4921](https://github.com/leanprover/lean4/pull/4921) cleans up `Expr.betaRev`.
* [#4940](https://github.com/leanprover/lean4/pull/4940) fixes tests by not writing directly to stdout, which is unreliable now that elaboration and reporting are executed in separate threads.
* [#4955](https://github.com/leanprover/lean4/pull/4955) documents that `stderrAsMessages` is now the default on the command line as well.
* [#4647](https://github.com/leanprover/lean4/pull/4647) adjusts documentation for building on macOS.
* [#4987](https://github.com/leanprover/lean4/pull/4987) makes regular mvar assignments take precedence over delayed ones in `instantiateMVars`. Normally delayed assignment metavariables are never directly assigned, but on errors Lean assigns `sorry` to unassigned metavariables.
* [#4967](https://github.com/leanprover/lean4/pull/4967) adds linter name to errors when a linter crashes.
* [#5043](https://github.com/leanprover/lean4/pull/5043) cleans up command line snapshots logic.
* [#5067](https://github.com/leanprover/lean4/pull/5067) minimizes some imports.
* [#5068](https://github.com/leanprover/lean4/pull/5068) generalizes the monad for `addMatcherInfo`.
* [f71a1f](https://github.com/leanprover/lean4/commit/f71a1fb4ae958fccb3ad4d48786a8f47ced05c15) adds missing test for [#5126](https://github.com/leanprover/lean4/issues/5126).
* [#5201](https://github.com/leanprover/lean4/pull/5201) restores a test.
* [#3698](https://github.com/leanprover/lean4/pull/3698) fixes a bug where label attributes did not pass on the attribute kind.
* Typos: [#5080](https://github.com/leanprover/lean4/pull/5080), [#5150](https://github.com/leanprover/lean4/pull/5150), [#5202](https://github.com/leanprover/lean4/pull/5202)
### Compiler, runtime, and FFI
* [#3106](https://github.com/leanprover/lean4/pull/3106) moves frontend to new snapshot architecture. Note that `Frontend.processCommand` and `FrontendM` are no longer used by Lean core, but they will be preserved.
* [#4919](https://github.com/leanprover/lean4/pull/4919) adds missing include in runtime for `AUTO_THREAD_FINALIZATION` feature on Windows.
* [#4941](https://github.com/leanprover/lean4/pull/4941) adds more `LEAN_EXPORT`s for Windows.
* [#4911](https://github.com/leanprover/lean4/pull/4911) improves formatting of CLI help text for the frontend.
* [#4950](https://github.com/leanprover/lean4/pull/4950) improves file reading and writing.
* `readBinFile` and `readFile` now only require two system calls (`stat` + `read`) instead of one `read` per 1024 byte chunk.
* `Handle.getLine` and `Handle.putStr` no longer get tripped up by NUL characters.
* [#4971](https://github.com/leanprover/lean4/pull/4971) handles the SIGBUS signal when detecting stack overflows.
* [#5062](https://github.com/leanprover/lean4/pull/5062) avoids overwriting existing signal handlers, like in [rust-lang/rust#69685](https://github.com/rust-lang/rust/pull/69685).
* [#4860](https://github.com/leanprover/lean4/pull/4860) improves workarounds for building on Windows. Splits `libleanshared` on Windows to avoid symbol limit, removes the `LEAN_EXPORT` denylist workaround, adds missing `LEAN_EXPORT`s.
* [#4952](https://github.com/leanprover/lean4/pull/4952) output panics into Lean's redirected stderr, ensuring panics ARE visible as regular messages in the language server and properly ordered in relation to other messages on the command line.
* [#4963](https://github.com/leanprover/lean4/pull/4963) links LibUV.
### Lake
* [#5030](https://github.com/leanprover/lean4/pull/5030) removes dead code.
* [#4770](https://github.com/leanprover/lean4/pull/4770) adds additional fields to the package configuration which will be used by Reservoir. See the PR description for details.
### DevOps/CI
* [#4914](https://github.com/leanprover/lean4/pull/4914) and [#4937](https://github.com/leanprover/lean4/pull/4937) improve the release checklist.
* [#4925](https://github.com/leanprover/lean4/pull/4925) ignores stale leanpkg tests.
* [#5003](https://github.com/leanprover/lean4/pull/5003) upgrades `actions/cache` in CI.
* [#5010](https://github.com/leanprover/lean4/pull/5010) sets `save-always` in cache actions in CI.
* [#5008](https://github.com/leanprover/lean4/pull/5008) adds more libuv search patterns for the speedcenter.
* [#5009](https://github.com/leanprover/lean4/pull/5009) reduce number of runs in the speedcenter for "fast" benchmarks from 10 to 3.
* [#5014](https://github.com/leanprover/lean4/pull/5014) adjusts lakefile editing to use new `git` syntax in `pr-release` workflow.
* [#5025](https://github.com/leanprover/lean4/pull/5025) has `pr-release` workflow pass `--retry` to `curl`.
* [#5022](https://github.com/leanprover/lean4/pull/5022) builds MacOS Aarch64 release for PRs by default.
* [#5045](https://github.com/leanprover/lean4/pull/5045) adds libuv to the required packages heading in macos docs.
* [#5034](https://github.com/leanprover/lean4/pull/5034) fixes the install name of `libleanshared_1` on macOS.
* [#5051](https://github.com/leanprover/lean4/pull/5051) fixes Windows stage 0.
* [#5052](https://github.com/leanprover/lean4/pull/5052) fixes 32bit stage 0 builds in CI.
* [#5057](https://github.com/leanprover/lean4/pull/5057) avoids rebuilding `leanmanifest` in each build.
* [#5099](https://github.com/leanprover/lean4/pull/5099) makes `restart-on-label` workflow also filter by commit SHA.
* [#4325](https://github.com/leanprover/lean4/pull/4325) adds CaDiCaL.
### Breaking changes
* [LibUV](https://libuv.org/) is now required to build Lean. This change only affects developers who compile Lean themselves instead of obtaining toolchains via `elan`. We have updated the official build instructions with information on how to obtain LibUV on our supported platforms. ([#4963](https://github.com/leanprover/lean4/pull/4963))
* Recursive definitions with a `decreasing_by` clause that begins with `simp_wf` may break. Try removing `simp_wf` or replacing it with `simp`. ([#5016](https://github.com/leanprover/lean4/pull/5016))
* The behavior of `rw [f]` where `f` is a non-recursive function defined by pattern matching changed.
For example, preciously, `rw [Option.map]` would rewrite `Option.map f o` to `match o with … `. Now this rewrite fails because it will use the equational lemmas, and these require constructors just like for `List.map`.
Remedies:
* Split on `o` before rewriting.
* Use `rw [Option.map.eq_def]`, which rewrites any (saturated) application of `Option.map`.
* Use `set_option backward.eqns.nonrecursive false` when *defining* the function in question.
([#4154](https://github.com/leanprover/lean4/pull/4154))
* The unified handling of equation lemmas for recursive and non-recursive functions can break existing code, as there now can be extra equational lemmas:
* Explicit uses of `f.eq_2` might have to be adjusted if the numbering changed.
* Uses of `rw [f]` or `simp [f]` may no longer apply if they previously matched (and introduced a `match` statement), when the equational lemmas got more fine-grained.
In this case either case analysis on the parameters before rewriting helps, or setting the option `backward.eqns.deepRecursiveSplit false` while *defining* the function.
([#5129](https://github.com/leanprover/lean4/pull/5129), [#5207](https://github.com/leanprover/lean4/pull/5207))
* The `reduceCtorEq` simproc is now optional, and it might need to be included in lists of simp lemmas, like `simp only [reduceCtorEq]`. This simproc is responsible for reducing equalities of constructors. ([#5167](https://github.com/leanprover/lean4/pull/5167))
* `Nat.strongInductionOn` is now `Nat.strongRecOn` and `Nat.caseStrongInductionOn` to `Nat.caseStrongRecOn`. ([#5147](https://github.com/leanprover/lean4/pull/5147))
* The parameters to `Membership.mem` have been swapped, which affects all `Membership` instances. ([#5020](https://github.com/leanprover/lean4/pull/5020))
* The meanings of `List.getElem_drop` and `List.getElem_drop'` have been reversed and the first is now a simp lemma. ([#5210](https://github.com/leanprover/lean4/pull/5210))
* The `Parsec` library has moved from `Lean.Data.Parsec` to `Std.Internal.Parsec`. The `Parsec` type is now more general with a parameter for an iterable. Users parsing strings can migrate to `Parser` in the `Std.Internal.Parsec.String` namespace, which also includes string-focused parsing combinators. ([#4774](https://github.com/leanprover/lean4/pull/4774))
* The `Lean` module has switched from `Lean.HashMap` and `Lean.HashSet` to `Std.HashMap` and `Std.HashSet` ([#4943](https://github.com/leanprover/lean4/pull/4943)). `Lean.HashMap` and `Lean.HashSet` are now deprecated ([#4954](https://github.com/leanprover/lean4/pull/4954)) and will be removed in a future release. Users of `Lean` APIs that interact with hash maps, for example `Lean.Environment.const2ModIdx`, might encounter minor breakage due to the following changes from `Lean.HashMap` to `Std.HashMap`:
* query functions use the term `get` instead of `find`, ([#4943](https://github.com/leanprover/lean4/pull/4943))
* the notation `map[key]` no longer returns an optional value but instead expects a proof that the key is present in the map. The previous behavior is available via the `map[key]?` notation.

312
releases/v4.13.0.md Normal file
View File

@@ -0,0 +1,312 @@
v4.13.0
----------
**Full Changelog**: https://github.com/leanprover/lean4/compare/v4.12.0...v4.13.0
### Language features, tactics, and metaprograms
* `structure` command
* [#5511](https://github.com/leanprover/lean4/pull/5511) allows structure parents to be type synonyms.
* [#5531](https://github.com/leanprover/lean4/pull/5531) allows default values for structure fields to be noncomputable.
* `rfl` and `apply_rfl` tactics
* [#3714](https://github.com/leanprover/lean4/pull/3714), [#3718](https://github.com/leanprover/lean4/pull/3718) improve the `rfl` tactic and give better error messages.
* [#3772](https://github.com/leanprover/lean4/pull/3772) makes `rfl` no longer use kernel defeq for ground terms.
* [#5329](https://github.com/leanprover/lean4/pull/5329) tags `Iff.refl` with `@[refl]` (@Parcly-Taxel)
* [#5359](https://github.com/leanprover/lean4/pull/5359) ensures that the `rfl` tactic tries `Iff.rfl` (@Parcly-Taxel)
* `unfold` tactic
* [#4834](https://github.com/leanprover/lean4/pull/4834) let `unfold` do zeta-delta reduction of local definitions, incorporating functionality of the Mathlib `unfold_let` tactic.
* `omega` tactic
* [#5382](https://github.com/leanprover/lean4/pull/5382) fixes spurious error in [#5315](https://github.com/leanprover/lean4/issues/5315)
* [#5523](https://github.com/leanprover/lean4/pull/5523) supports `Int.toNat`
* `simp` tactic
* [#5479](https://github.com/leanprover/lean4/pull/5479) lets `simp` apply rules with higher-order patterns.
* `induction` tactic
* [#5494](https://github.com/leanprover/lean4/pull/5494) fixes `induction`s "pre-tactic" block to always be indented, avoiding unintended uses of it.
* `ac_nf` tactic
* [#5524](https://github.com/leanprover/lean4/pull/5524) adds `ac_nf`, a counterpart to `ac_rfl`, for normalizing expressions with respect to associativity and commutativity. Tests it with `BitVec` expressions.
* `bv_decide`
* [#5211](https://github.com/leanprover/lean4/pull/5211) makes `extractLsb'` the primitive `bv_decide` understands, rather than `extractLsb` (@alexkeizer)
* [#5365](https://github.com/leanprover/lean4/pull/5365) adds `bv_decide` diagnoses.
* [#5375](https://github.com/leanprover/lean4/pull/5375) adds `bv_decide` normalization rules for `ofBool (a.getLsbD i)` and `ofBool a[i]` (@alexkeizer)
* [#5423](https://github.com/leanprover/lean4/pull/5423) enhances the rewriting rules of `bv_decide`
* [#5433](https://github.com/leanprover/lean4/pull/5433) presents the `bv_decide` counterexample at the API
* [#5484](https://github.com/leanprover/lean4/pull/5484) handles `BitVec.ofNat` with `Nat` fvars in `bv_decide`
* [#5506](https://github.com/leanprover/lean4/pull/5506), [#5507](https://github.com/leanprover/lean4/pull/5507) add `bv_normalize` rules.
* [#5568](https://github.com/leanprover/lean4/pull/5568) generalize the `bv_normalize` pipeline to support more general preprocessing passes
* [#5573](https://github.com/leanprover/lean4/pull/5573) gets `bv_normalize` up-to-date with the current `BitVec` rewrites
* Cleanups: [#5408](https://github.com/leanprover/lean4/pull/5408), [#5493](https://github.com/leanprover/lean4/pull/5493), [#5578](https://github.com/leanprover/lean4/pull/5578)
* Elaboration improvements
* [#5266](https://github.com/leanprover/lean4/pull/5266) preserve order of overapplied arguments in `elab_as_elim` procedure.
* [#5510](https://github.com/leanprover/lean4/pull/5510) generalizes `elab_as_elim` to allow arbitrary motive applications.
* [#5283](https://github.com/leanprover/lean4/pull/5283), [#5512](https://github.com/leanprover/lean4/pull/5512) refine how named arguments suppress explicit arguments. Breaking change: some previously omitted explicit arguments may need explicit `_` arguments now.
* [#5376](https://github.com/leanprover/lean4/pull/5376) modifies projection instance binder info for instances, making parameters that are instance implicit in the type be implicit.
* [#5402](https://github.com/leanprover/lean4/pull/5402) localizes universe metavariable errors to `let` bindings and `fun` binders if possible. Makes "cannot synthesize metavariable" errors take precedence over unsolved universe level errors.
* [#5419](https://github.com/leanprover/lean4/pull/5419) must not reduce `ite` in the discriminant of `match`-expression when reducibility setting is `.reducible`
* [#5474](https://github.com/leanprover/lean4/pull/5474) have autoparams report parameter/field on failure
* [#5530](https://github.com/leanprover/lean4/pull/5530) makes automatic instance names about types with hygienic names be hygienic.
* Deriving handlers
* [#5432](https://github.com/leanprover/lean4/pull/5432) makes `Repr` deriving instance handle explicit type parameters
* Functional induction
* [#5364](https://github.com/leanprover/lean4/pull/5364) adds more equalities in context, more careful cleanup.
* Linters
* [#5335](https://github.com/leanprover/lean4/pull/5335) fixes the unused variables linter complaining about match/tactic combinations
* [#5337](https://github.com/leanprover/lean4/pull/5337) fixes the unused variables linter complaining about some wildcard patterns
* Other fixes
* [#4768](https://github.com/leanprover/lean4/pull/4768) fixes a parse error when `..` appears with a `.` on the next line
* Metaprogramming
* [#3090](https://github.com/leanprover/lean4/pull/3090) handles level parameters in `Meta.evalExpr` (@eric-wieser)
* [#5401](https://github.com/leanprover/lean4/pull/5401) instance for `Inhabited (TacticM α)` (@alexkeizer)
* [#5412](https://github.com/leanprover/lean4/pull/5412) expose Kernel.check for debugging purposes
* [#5556](https://github.com/leanprover/lean4/pull/5556) improves the "invalid projection" type inference error in `inferType`.
* [#5587](https://github.com/leanprover/lean4/pull/5587) allows `MVarId.assertHypotheses` to set `BinderInfo` and `LocalDeclKind`.
* [#5588](https://github.com/leanprover/lean4/pull/5588) adds `MVarId.tryClearMany'`, a variant of `MVarId.tryClearMany`.
### Language server, widgets, and IDE extensions
* [#5205](https://github.com/leanprover/lean4/pull/5205) decreases the latency of auto-completion in tactic blocks.
* [#5237](https://github.com/leanprover/lean4/pull/5237) fixes symbol occurrence highlighting in VS Code not highlighting occurrences when moving the text cursor into the identifier from the right.
* [#5257](https://github.com/leanprover/lean4/pull/5257) fixes several instances of incorrect auto-completions being reported.
* [#5299](https://github.com/leanprover/lean4/pull/5299) allows auto-completion to report completions for global identifiers when the elaborator fails to provide context-specific auto-completions.
* [#5312](https://github.com/leanprover/lean4/pull/5312) fixes the server breaking when changing whitespace after the module header.
* [#5322](https://github.com/leanprover/lean4/pull/5322) fixes several instances of auto-completion reporting non-existent namespaces.
* [#5428](https://github.com/leanprover/lean4/pull/5428) makes sure to always report some recent file range as progress when waiting for elaboration.
### Pretty printing
* [#4979](https://github.com/leanprover/lean4/pull/4979) make pretty printer escape identifiers that are tokens.
* [#5389](https://github.com/leanprover/lean4/pull/5389) makes formatter use the current token table.
* [#5513](https://github.com/leanprover/lean4/pull/5513) use breakable instead of unbreakable whitespace when formatting tokens.
### Library
* [#5222](https://github.com/leanprover/lean4/pull/5222) reduces allocations in `Json.compress`.
* [#5231](https://github.com/leanprover/lean4/pull/5231) upstreams `Zero` and `NeZero`
* [#5292](https://github.com/leanprover/lean4/pull/5292) refactors `Lean.Elab.Deriving.FromToJson` (@arthur-adjedj)
* [#5415](https://github.com/leanprover/lean4/pull/5415) implements `Repr Empty` (@TomasPuverle)
* [#5421](https://github.com/leanprover/lean4/pull/5421) implements `To/FromJSON Empty` (@TomasPuverle)
* Logic
* [#5263](https://github.com/leanprover/lean4/pull/5263) allows simplifying `dite_not`/`decide_not` with only `Decidable (¬p)`.
* [#5268](https://github.com/leanprover/lean4/pull/5268) fixes binders on `ite_eq_left_iff`
* [#5284](https://github.com/leanprover/lean4/pull/5284) turns off `Inhabited (Sum α β)` instances
* [#5355](https://github.com/leanprover/lean4/pull/5355) adds simp lemmas for `LawfulBEq`
* [#5374](https://github.com/leanprover/lean4/pull/5374) add `Nonempty` instances for products, allowing more `partial` functions to elaborate successfully
* [#5447](https://github.com/leanprover/lean4/pull/5447) updates Pi instance names
* [#5454](https://github.com/leanprover/lean4/pull/5454) makes some instance arguments implicit
* [#5456](https://github.com/leanprover/lean4/pull/5456) adds `heq_comm`
* [#5529](https://github.com/leanprover/lean4/pull/5529) moves `@[simp]` from `exists_prop'` to `exists_prop`
* `Bool`
* [#5228](https://github.com/leanprover/lean4/pull/5228) fills gaps in Bool lemmas
* [#5332](https://github.com/leanprover/lean4/pull/5332) adds notation `^^` for Bool.xor
* [#5351](https://github.com/leanprover/lean4/pull/5351) removes `_root_.and` (and or/not/xor) and instead exports/uses `Bool.and` (etc.).
* `BitVec`
* [#5240](https://github.com/leanprover/lean4/pull/5240) removes BitVec simps with complicated RHS
* [#5247](https://github.com/leanprover/lean4/pull/5247) `BitVec.getElem_zeroExtend`
* [#5248](https://github.com/leanprover/lean4/pull/5248) simp lemmas for BitVec, improving confluence
* [#5249](https://github.com/leanprover/lean4/pull/5249) removes `@[simp]` from some BitVec lemmas
* [#5252](https://github.com/leanprover/lean4/pull/5252) changes `BitVec.intMin/Max` from abbrev to def
* [#5278](https://github.com/leanprover/lean4/pull/5278) adds `BitVec.getElem_truncate` (@tobiasgrosser)
* [#5281](https://github.com/leanprover/lean4/pull/5281) adds udiv/umod bitblasting for `bv_decide` (@bollu)
* [#5297](https://github.com/leanprover/lean4/pull/5297) `BitVec` unsigned order theoretic results
* [#5313](https://github.com/leanprover/lean4/pull/5313) adds more basic BitVec ordering theory for UInt
* [#5314](https://github.com/leanprover/lean4/pull/5314) adds `toNat_sub_of_le` (@bollu)
* [#5357](https://github.com/leanprover/lean4/pull/5357) adds `BitVec.truncate` lemmas
* [#5358](https://github.com/leanprover/lean4/pull/5358) introduces `BitVec.setWidth` to unify zeroExtend and truncate (@tobiasgrosser)
* [#5361](https://github.com/leanprover/lean4/pull/5361) some BitVec GetElem lemmas
* [#5385](https://github.com/leanprover/lean4/pull/5385) adds `BitVec.ofBool_[and|or|xor]_ofBool` theorems (@tobiasgrosser)
* [#5404](https://github.com/leanprover/lean4/pull/5404) more of `BitVec.getElem_*` (@tobiasgrosser)
* [#5410](https://github.com/leanprover/lean4/pull/5410) BitVec analogues of `Nat.{mul_two, two_mul, mul_succ, succ_mul}` (@bollu)
* [#5411](https://github.com/leanprover/lean4/pull/5411) `BitVec.toNat_{add,sub,mul_of_lt}` for BitVector non-overflow reasoning (@bollu)
* [#5413](https://github.com/leanprover/lean4/pull/5413) adds `_self`, `_zero`, and `_allOnes` for `BitVec.[and|or|xor]` (@tobiasgrosser)
* [#5416](https://github.com/leanprover/lean4/pull/5416) adds LawCommIdentity + IdempotentOp for `BitVec.[and|or|xor]` (@tobiasgrosser)
* [#5418](https://github.com/leanprover/lean4/pull/5418) decidable quantifers for BitVec
* [#5450](https://github.com/leanprover/lean4/pull/5450) adds `BitVec.toInt_[intMin|neg|neg_of_ne_intMin]` (@tobiasgrosser)
* [#5459](https://github.com/leanprover/lean4/pull/5459) missing BitVec lemmas
* [#5469](https://github.com/leanprover/lean4/pull/5469) adds `BitVec.[not_not, allOnes_shiftLeft_or_shiftLeft, allOnes_shiftLeft_and_shiftLeft]` (@luisacicolini)
* [#5478](https://github.com/leanprover/lean4/pull/5478) adds `BitVec.(shiftLeft_add_distrib, shiftLeft_ushiftRight)` (@luisacicolini)
* [#5487](https://github.com/leanprover/lean4/pull/5487) adds `sdiv_eq`, `smod_eq` to allow `sdiv`/`smod` bitblasting (@bollu)
* [#5491](https://github.com/leanprover/lean4/pull/5491) adds `BitVec.toNat_[abs|sdiv|smod]` (@tobiasgrosser)
* [#5492](https://github.com/leanprover/lean4/pull/5492) `BitVec.(not_sshiftRight, not_sshiftRight_not, getMsb_not, msb_not)` (@luisacicolini)
* [#5499](https://github.com/leanprover/lean4/pull/5499) `BitVec.Lemmas` - drop non-terminal simps (@tobiasgrosser)
* [#5505](https://github.com/leanprover/lean4/pull/5505) unsimps `BitVec.divRec_succ'`
* [#5508](https://github.com/leanprover/lean4/pull/5508) adds `BitVec.getElem_[add|add_add_bool|mul|rotateLeft|rotateRight…` (@tobiasgrosser)
* [#5554](https://github.com/leanprover/lean4/pull/5554) adds `Bitvec.[add, sub, mul]_eq_xor` and `width_one_cases` (@luisacicolini)
* `List`
* [#5242](https://github.com/leanprover/lean4/pull/5242) improve naming for `List.mergeSort` lemmas
* [#5302](https://github.com/leanprover/lean4/pull/5302) provide `mergeSort` comparator autoParam
* [#5373](https://github.com/leanprover/lean4/pull/5373) fix name of `List.length_mergeSort`
* [#5377](https://github.com/leanprover/lean4/pull/5377) upstream `map_mergeSort`
* [#5378](https://github.com/leanprover/lean4/pull/5378) modify signature of lemmas about `mergeSort`
* [#5245](https://github.com/leanprover/lean4/pull/5245) avoid importing `List.Basic` without List.Impl
* [#5260](https://github.com/leanprover/lean4/pull/5260) review of List API
* [#5264](https://github.com/leanprover/lean4/pull/5264) review of List API
* [#5269](https://github.com/leanprover/lean4/pull/5269) remove HashMap's duplicated Pairwise and Sublist
* [#5271](https://github.com/leanprover/lean4/pull/5271) remove @[simp] from `List.head_mem` and similar
* [#5273](https://github.com/leanprover/lean4/pull/5273) lemmas about `List.attach`
* [#5275](https://github.com/leanprover/lean4/pull/5275) reverse direction of `List.tail_map`
* [#5277](https://github.com/leanprover/lean4/pull/5277) more `List.attach` lemmas
* [#5285](https://github.com/leanprover/lean4/pull/5285) `List.count` lemmas
* [#5287](https://github.com/leanprover/lean4/pull/5287) use boolean predicates in `List.filter`
* [#5289](https://github.com/leanprover/lean4/pull/5289) `List.mem_ite_nil_left` and analogues
* [#5293](https://github.com/leanprover/lean4/pull/5293) cleanup of `List.findIdx` / `List.take` lemmas
* [#5294](https://github.com/leanprover/lean4/pull/5294) switch primes on `List.getElem_take`
* [#5300](https://github.com/leanprover/lean4/pull/5300) more `List.findIdx` theorems
* [#5310](https://github.com/leanprover/lean4/pull/5310) fix `List.all/any` lemmas
* [#5311](https://github.com/leanprover/lean4/pull/5311) fix `List.countP` lemmas
* [#5316](https://github.com/leanprover/lean4/pull/5316) `List.tail` lemma
* [#5331](https://github.com/leanprover/lean4/pull/5331) fix implicitness of `List.getElem_mem`
* [#5350](https://github.com/leanprover/lean4/pull/5350) `List.replicate` lemmas
* [#5352](https://github.com/leanprover/lean4/pull/5352) `List.attachWith` lemmas
* [#5353](https://github.com/leanprover/lean4/pull/5353) `List.head_mem_head?`
* [#5360](https://github.com/leanprover/lean4/pull/5360) lemmas about `List.tail`
* [#5391](https://github.com/leanprover/lean4/pull/5391) review of `List.erase` / `List.find` lemmas
* [#5392](https://github.com/leanprover/lean4/pull/5392) `List.fold` / `attach` lemmas
* [#5393](https://github.com/leanprover/lean4/pull/5393) `List.fold` relators
* [#5394](https://github.com/leanprover/lean4/pull/5394) lemmas about `List.maximum?`
* [#5403](https://github.com/leanprover/lean4/pull/5403) theorems about `List.toArray`
* [#5405](https://github.com/leanprover/lean4/pull/5405) reverse direction of `List.set_map`
* [#5448](https://github.com/leanprover/lean4/pull/5448) add lemmas about `List.IsPrefix` (@Command-Master)
* [#5460](https://github.com/leanprover/lean4/pull/5460) missing `List.set_replicate_self`
* [#5518](https://github.com/leanprover/lean4/pull/5518) rename `List.maximum?` to `max?`
* [#5519](https://github.com/leanprover/lean4/pull/5519) upstream `List.fold` lemmas
* [#5520](https://github.com/leanprover/lean4/pull/5520) restore `@[simp]` on `List.getElem_mem` etc.
* [#5521](https://github.com/leanprover/lean4/pull/5521) List simp fixes
* [#5550](https://github.com/leanprover/lean4/pull/5550) `List.unattach` and simp lemmas
* [#5594](https://github.com/leanprover/lean4/pull/5594) induction-friendly `List.min?_cons`
* `Array`
* [#5246](https://github.com/leanprover/lean4/pull/5246) cleanup imports of Array.Lemmas
* [#5255](https://github.com/leanprover/lean4/pull/5255) split Init.Data.Array.Lemmas for better bootstrapping
* [#5288](https://github.com/leanprover/lean4/pull/5288) rename `Array.data` to `Array.toList`
* [#5303](https://github.com/leanprover/lean4/pull/5303) cleanup of `List.getElem_append` variants
* [#5304](https://github.com/leanprover/lean4/pull/5304) `Array.not_mem_empty`
* [#5400](https://github.com/leanprover/lean4/pull/5400) reorganization in Array/Basic
* [#5420](https://github.com/leanprover/lean4/pull/5420) make `Array` functions either semireducible or use structural recursion
* [#5422](https://github.com/leanprover/lean4/pull/5422) refactor `DecidableEq (Array α)`
* [#5452](https://github.com/leanprover/lean4/pull/5452) refactor of Array
* [#5458](https://github.com/leanprover/lean4/pull/5458) cleanup of Array docstrings after refactor
* [#5461](https://github.com/leanprover/lean4/pull/5461) restore `@[simp]` on `Array.swapAt!_def`
* [#5465](https://github.com/leanprover/lean4/pull/5465) improve Array GetElem lemmas
* [#5466](https://github.com/leanprover/lean4/pull/5466) `Array.foldX` lemmas
* [#5472](https://github.com/leanprover/lean4/pull/5472) @[simp] lemmas about `List.toArray`
* [#5485](https://github.com/leanprover/lean4/pull/5485) reverse simp direction for `toArray_concat`
* [#5514](https://github.com/leanprover/lean4/pull/5514) `Array.eraseReps`
* [#5515](https://github.com/leanprover/lean4/pull/5515) upstream `Array.qsortOrd`
* [#5516](https://github.com/leanprover/lean4/pull/5516) upstream `Subarray.empty`
* [#5526](https://github.com/leanprover/lean4/pull/5526) fix name of `Array.length_toList`
* [#5527](https://github.com/leanprover/lean4/pull/5527) reduce use of deprecated lemmas in Array
* [#5534](https://github.com/leanprover/lean4/pull/5534) cleanup of Array GetElem lemmas
* [#5536](https://github.com/leanprover/lean4/pull/5536) fix `Array.modify` lemmas
* [#5551](https://github.com/leanprover/lean4/pull/5551) upstream `Array.flatten` lemmas
* [#5552](https://github.com/leanprover/lean4/pull/5552) switch obvious cases of array "bang"`[]!` indexing to rely on hypothesis (@TomasPuverle)
* [#5577](https://github.com/leanprover/lean4/pull/5577) add missing simp to `Array.size_feraseIdx`
* [#5586](https://github.com/leanprover/lean4/pull/5586) `Array/Option.unattach`
* `Option`
* [#5272](https://github.com/leanprover/lean4/pull/5272) remove @[simp] from `Option.pmap/pbind` and add simp lemmas
* [#5307](https://github.com/leanprover/lean4/pull/5307) restoring Option simp confluence
* [#5354](https://github.com/leanprover/lean4/pull/5354) remove @[simp] from `Option.bind_map`
* [#5532](https://github.com/leanprover/lean4/pull/5532) `Option.attach`
* [#5539](https://github.com/leanprover/lean4/pull/5539) fix explicitness of `Option.mem_toList`
* `Nat`
* [#5241](https://github.com/leanprover/lean4/pull/5241) add @[simp] to `Nat.add_eq_zero_iff`
* [#5261](https://github.com/leanprover/lean4/pull/5261) Nat bitwise lemmas
* [#5262](https://github.com/leanprover/lean4/pull/5262) `Nat.testBit_add_one` should not be a global simp lemma
* [#5267](https://github.com/leanprover/lean4/pull/5267) protect some Nat bitwise theorems
* [#5305](https://github.com/leanprover/lean4/pull/5305) rename Nat bitwise lemmas
* [#5306](https://github.com/leanprover/lean4/pull/5306) add `Nat.self_sub_mod` lemma
* [#5503](https://github.com/leanprover/lean4/pull/5503) restore @[simp] to upstreamed `Nat.lt_off_iff`
* `Int`
* [#5301](https://github.com/leanprover/lean4/pull/5301) rename `Int.div/mod` to `Int.tdiv/tmod`
* [#5320](https://github.com/leanprover/lean4/pull/5320) add `ediv_nonneg_of_nonpos_of_nonpos` to DivModLemmas (@sakehl)
* `Fin`
* [#5250](https://github.com/leanprover/lean4/pull/5250) missing lemma about `Fin.ofNat'`
* [#5356](https://github.com/leanprover/lean4/pull/5356) `Fin.ofNat'` uses `NeZero`
* [#5379](https://github.com/leanprover/lean4/pull/5379) remove some @[simp]s from Fin lemmas
* [#5380](https://github.com/leanprover/lean4/pull/5380) missing Fin @[simp] lemmas
* `HashMap`
* [#5244](https://github.com/leanprover/lean4/pull/5244) (`DHashMap`|`HashMap`|`HashSet`).(`getKey?`|`getKey`|`getKey!`|`getKeyD`)
* [#5362](https://github.com/leanprover/lean4/pull/5362) remove the last use of `Lean.(HashSet|HashMap)`
* [#5369](https://github.com/leanprover/lean4/pull/5369) `HashSet.ofArray`
* [#5370](https://github.com/leanprover/lean4/pull/5370) `HashSet.partition`
* [#5581](https://github.com/leanprover/lean4/pull/5581) `Singleton`/`Insert`/`Union` instances for `HashMap`/`Set`
* [#5582](https://github.com/leanprover/lean4/pull/5582) `HashSet.all`/`any`
* [#5590](https://github.com/leanprover/lean4/pull/5590) adding `Insert`/`Singleton`/`Union` instances for `HashMap`/`Set.Raw`
* [#5591](https://github.com/leanprover/lean4/pull/5591) `HashSet.Raw.all/any`
* `Monads`
* [#5463](https://github.com/leanprover/lean4/pull/5463) upstream some monad lemmas
* [#5464](https://github.com/leanprover/lean4/pull/5464) adjust simp attributes on monad lemmas
* [#5522](https://github.com/leanprover/lean4/pull/5522) more monadic simp lemmas
* Simp lemma cleanup
* [#5251](https://github.com/leanprover/lean4/pull/5251) remove redundant simp annotations
* [#5253](https://github.com/leanprover/lean4/pull/5253) remove Int simp lemmas that can't fire
* [#5254](https://github.com/leanprover/lean4/pull/5254) variables appearing on both sides of an iff should be implicit
* [#5381](https://github.com/leanprover/lean4/pull/5381) cleaning up redundant simp lemmas
### Compiler, runtime, and FFI
* [#4685](https://github.com/leanprover/lean4/pull/4685) fixes a typo in the C `run_new_frontend` signature
* [#4729](https://github.com/leanprover/lean4/pull/4729) has IR checker suggest using `noncomputable`
* [#5143](https://github.com/leanprover/lean4/pull/5143) adds a shared library for Lake
* [#5437](https://github.com/leanprover/lean4/pull/5437) removes (syntactically) duplicate imports (@euprunin)
* [#5462](https://github.com/leanprover/lean4/pull/5462) updates `src/lake/lakefile.toml` to the adjusted Lake build process
* [#5541](https://github.com/leanprover/lean4/pull/5541) removes new shared libs before build to better support Windows
* [#5558](https://github.com/leanprover/lean4/pull/5558) make `lean.h` compile with MSVC (@kant2002)
* [#5564](https://github.com/leanprover/lean4/pull/5564) removes non-conforming size-0 arrays (@eric-wieser)
### Lake
* Reservoir build cache. Lake will now attempt to fetch a pre-built copy of the package from Reservoir before building it. This is only enabled for packages in the leanprover or leanprover-community organizations on versions indexed by Reservoir. Users can force Lake to build packages from the source by passing --no-cache on the CLI or by setting the LAKE_NO_CACHE environment variable to true. [#5486](https://github.com/leanprover/lean4/pull/5486), [#5572](https://github.com/leanprover/lean4/pull/5572), [#5583](https://github.com/leanprover/lean4/pull/5583), [#5600](https://github.com/leanprover/lean4/pull/5600), [#5641](https://github.com/leanprover/lean4/pull/5641), [#5642](https://github.com/leanprover/lean4/pull/5642).
* [#5504](https://github.com/leanprover/lean4/pull/5504) lake new and lake init now produce TOML configurations by default.
* [#5878](https://github.com/leanprover/lean4/pull/5878) fixes a serious issue where Lake would delete path dependencies when attempting to cleanup a dependency required with an incorrect name.
* **Breaking changes**
* [#5641](https://github.com/leanprover/lean4/pull/5641) A Lake build of target within a package will no longer build a package's dependencies package-level extra target dependencies. At the technical level, a package's extraDep facet no longer transitively builds its dependencies extraDep facets (which include their extraDepTargets).
### Documentation fixes
* [#3918](https://github.com/leanprover/lean4/pull/3918) `@[builtin_doc]` attribute (@digama0)
* [#4305](https://github.com/leanprover/lean4/pull/4305) explains the borrow syntax (@eric-wieser)
* [#5349](https://github.com/leanprover/lean4/pull/5349) adds documentation for `groupBy.loop` (@vihdzp)
* [#5473](https://github.com/leanprover/lean4/pull/5473) fixes typo in `BitVec.mul` docstring (@llllvvuu)
* [#5476](https://github.com/leanprover/lean4/pull/5476) fixes typos in `Lean.MetavarContext`
* [#5481](https://github.com/leanprover/lean4/pull/5481) removes mention of `Lean.withSeconds` (@alexkeizer)
* [#5497](https://github.com/leanprover/lean4/pull/5497) updates documentation and tests for `toUIntX` functions (@TomasPuverle)
* [#5087](https://github.com/leanprover/lean4/pull/5087) mentions that `inferType` does not ensure type correctness
* Many fixes to spelling across the doc-strings, (@euprunin): [#5425](https://github.com/leanprover/lean4/pull/5425) [#5426](https://github.com/leanprover/lean4/pull/5426) [#5427](https://github.com/leanprover/lean4/pull/5427) [#5430](https://github.com/leanprover/lean4/pull/5430) [#5431](https://github.com/leanprover/lean4/pull/5431) [#5434](https://github.com/leanprover/lean4/pull/5434) [#5435](https://github.com/leanprover/lean4/pull/5435) [#5436](https://github.com/leanprover/lean4/pull/5436) [#5438](https://github.com/leanprover/lean4/pull/5438) [#5439](https://github.com/leanprover/lean4/pull/5439) [#5440](https://github.com/leanprover/lean4/pull/5440) [#5599](https://github.com/leanprover/lean4/pull/5599)
### Changes to CI
* [#5343](https://github.com/leanprover/lean4/pull/5343) allows addition of `release-ci` label via comment (@thorimur)
* [#5344](https://github.com/leanprover/lean4/pull/5344) sets check level correctly during workflow (@thorimur)
* [#5444](https://github.com/leanprover/lean4/pull/5444) Mathlib's `lean-pr-testing-NNNN` branches should use Batteries' `lean-pr-testing-NNNN` branches
* [#5489](https://github.com/leanprover/lean4/pull/5489) commit `lake-manifest.json` when updating `lean-pr-testing` branches
* [#5490](https://github.com/leanprover/lean4/pull/5490) use separate secrets for commenting and branching in `pr-release.yml`

282
releases/v4.14.0.md Normal file
View File

@@ -0,0 +1,282 @@
v4.14.0
----------
**Full Changelog**: https://github.com/leanprover/lean4/compare/v4.13.0...v4.14.0
### Language features, tactics, and metaprograms
* `structure` and `inductive` commands
* [#5517](https://github.com/leanprover/lean4/pull/5517) improves universe level inference for the resulting type of an `inductive` or `structure.` Recall that a `Prop`-valued inductive type is a syntactic subsingleton if it has at most one constructor and all the arguments to the constructor are in `Prop`. Such types have large elimination, so they could be defined in `Type` or `Prop` without any trouble. The way inference has changed is that if a type is a syntactic subsingleton with exactly one constructor, and the constructor has at least one parameter/field, then the `inductive`/`structure` command will prefer creating a `Prop` instead of a `Type`. The upshot is that the `: Prop` in `structure S : Prop` is often no longer needed. (With @arthur-adjedj).
* [#5842](https://github.com/leanprover/lean4/pull/5842) and [#5783](https://github.com/leanprover/lean4/pull/5783) implement a feature where the `structure` command can now define recursive inductive types:
```lean
structure Tree where
n : Nat
children : Fin n → Tree
def Tree.size : Tree → Nat
| {n, children} => Id.run do
let mut s := 0
for h : i in [0 : n] do
s := s + (children ⟨i, h.2⟩).size
pure s
```
* [#5814](https://github.com/leanprover/lean4/pull/5814) fixes a bug where Mathlib's `Type*` elaborator could lead to incorrect universe parameters with the `inductive` command.
* [#3152](https://github.com/leanprover/lean4/pull/3152) and [#5844](https://github.com/leanprover/lean4/pull/5844) fix bugs in default value processing for structure instance notation (with @arthur-adjedj).
* [#5399](https://github.com/leanprover/lean4/pull/5399) promotes instance synthesis order calculation failure from a soft error to a hard error.
* [#5542](https://github.com/leanprover/lean4/pull/5542) deprecates `:=` variants of `inductive` and `structure` (see breaking changes).
* **Application elaboration improvements**
* [#5671](https://github.com/leanprover/lean4/pull/5671) makes `@[elab_as_elim]` require at least one discriminant, since otherwise there is no advantage to this alternative elaborator.
* [#5528](https://github.com/leanprover/lean4/pull/5528) enables field notation in explicit mode. The syntax `@x.f` elaborates as `@S.f` with `x` supplied to the appropriate parameter.
* [#5692](https://github.com/leanprover/lean4/pull/5692) modifies the dot notation resolution algorithm so that it can apply `CoeFun` instances. For example, Mathlib has `Multiset.card : Multiset α →+ Nat`, and now with `m : Multiset α`, the notation `m.card` resolves to `⇑Multiset.card m`.
* [#5658](https://github.com/leanprover/lean4/pull/5658) fixes a bug where 'don't know how to synthesize implicit argument' errors might have the incorrect local context when the eta arguments feature is activated.
* [#5933](https://github.com/leanprover/lean4/pull/5933) fixes a bug where `..` ellipses in patterns made use of optparams and autoparams.
* [#5770](https://github.com/leanprover/lean4/pull/5770) makes dot notation for structures resolve using *all* ancestors. Adds a *resolution order* for generalized field notation. This is the order of namespaces visited during resolution when trying to resolve names. The algorithm to compute a resolution order is the commonly used C3 linearization (used for example by Python), which when successful ensures that immediate parents' namespaces are considered before more distant ancestors' namespaces. By default we use a relaxed version of the algorithm that tolerates inconsistencies, but using `set_option structure.strictResolutionOrder true` makes inconsistent parent orderings into warnings.
* **Recursion and induction principles**
* [#5619](https://github.com/leanprover/lean4/pull/5619) fixes functional induction principle generation to avoid over-eta-expanding in the preprocessing step.
* [#5766](https://github.com/leanprover/lean4/pull/5766) fixes structural nested recursion so that it is not confused when a nested type appears first.
* [#5803](https://github.com/leanprover/lean4/pull/5803) fixes a bug in functional induction principle generation when there are `let` bindings.
* [#5904](https://github.com/leanprover/lean4/pull/5904) improves functional induction principle generation to unfold aux definitions more carefully.
* [#5850](https://github.com/leanprover/lean4/pull/5850) refactors code for `Predefinition.Structural`.
* **Error messages**
* [#5276](https://github.com/leanprover/lean4/pull/5276) fixes a bug in "type mismatch" errors that would structurally assign metavariables during the algorithm to expose differences.
* [#5919](https://github.com/leanprover/lean4/pull/5919) makes "type mismatch" errors add type ascriptions to expose differences for numeric literals.
* [#5922](https://github.com/leanprover/lean4/pull/5922) makes "type mismatch" errors expose differences in the bodies of functions and pi types.
* [#5888](https://github.com/leanprover/lean4/pull/5888) improves the error message for invalid induction alternative names in `match` expressions (@josojo).
* [#5719](https://github.com/leanprover/lean4/pull/5719) improves `calc` error messages.
* [#5627](https://github.com/leanprover/lean4/pull/5627) and [#5663](https://github.com/leanprover/lean4/pull/5663) improve the **`#eval` command** and introduce some new features.
* Now results can be pretty printed if there is a `ToExpr` instance, which means **hoverable output**. If `ToExpr` fails, it then tries looking for a `Repr` or `ToString` instance like before. Setting `set_option eval.pp false` disables making use of `ToExpr` instances.
* There is now **auto-derivation** of `Repr` instances, enabled with the `pp.derive.repr` option (default to **true**). For example:
```lean
inductive Baz
| a | b
#eval Baz.a
-- Baz.a
```
It simply does `deriving instance Repr for Baz` when there's no way to represent `Baz`.
* The option `eval.type` controls whether or not to include the type in the output. For now the default is false.
* Now expressions such as `#eval do return 2`, where monad is unknown, work. It tries unifying the monad with `CommandElabM`, `TermElabM`, or `IO`.
* The classes `Lean.Eval` and `Lean.MetaEval` have been removed. These each used to be responsible for adapting monads and printing results. Now the `MonadEval` class is responsible for adapting monads for evaluation (it is similar to `MonadLift`, but instances are allowed to use default data when initializing state), and representing results is handled through a separate process.
* Error messages about failed instance synthesis are now more precise. Once it detects that a `MonadEval` class applies, then the error message will be specific about missing `ToExpr`/`Repr`/`ToString` instances.
* Fixes bugs where evaluating `MetaM` and `CoreM` wouldn't collect log messages.
* Fixes a bug where `let rec` could not be used in `#eval`.
* `partial` definitions
* [#5780](https://github.com/leanprover/lean4/pull/5780) improves the error message when `partial` fails to prove a type is inhabited. Add delta deriving.
* [#5821](https://github.com/leanprover/lean4/pull/5821) gives `partial` inhabitation the ability to create local `Inhabited` instances from parameters.
* **New tactic configuration syntax.** The configuration syntax for all core tactics has been given an upgrade. Rather than `simp (config := { contextual := true, maxSteps := 22})`, one can now write `simp +contextual (maxSteps := 22)`. Tactic authors can migrate by switching from `(config)?` to `optConfig` in tactic syntaxes and potentially deleting `mkOptionalNode` in elaborators. [#5883](https://github.com/leanprover/lean4/pull/5883), [#5898](https://github.com/leanprover/lean4/pull/5898), [#5928](https://github.com/leanprover/lean4/pull/5928), and [#5932](https://github.com/leanprover/lean4/pull/5932). (Tactic authors, see breaking changes.)
* `simp` tactic
* [#5632](https://github.com/leanprover/lean4/pull/5632) fixes the simpproc for `Fin` literals to reduce more consistently.
* [#5648](https://github.com/leanprover/lean4/pull/5648) fixes a bug in `simpa ... using t` where metavariables in `t` were not properly accounted for, and also improves the type mismatch error.
* [#5838](https://github.com/leanprover/lean4/pull/5838) fixes the docstring of `simp!` to actually talk about `simp!`.
* [#5870](https://github.com/leanprover/lean4/pull/5870) adds support for `attribute [simp ←]` (note the reverse direction). This adds the reverse of a theorem as a global simp theorem.
* `decide` tactic
* [#5665](https://github.com/leanprover/lean4/pull/5665) adds `decide!` tactic for using kernel reduction (warning: this is renamed to `decide +kernel` in a future release).
* `bv_decide` tactic
* [#5714](https://github.com/leanprover/lean4/pull/5714) adds inequality regression tests (@alexkeizer).
* [#5608](https://github.com/leanprover/lean4/pull/5608) adds `bv_toNat` tag for `toNat_ofInt` (@bollu).
* [#5618](https://github.com/leanprover/lean4/pull/5618) adds support for `at` in `ac_nf` and uses it in `bv_normalize` (@tobiasgrosser).
* [#5628](https://github.com/leanprover/lean4/pull/5628) adds udiv support.
* [#5635](https://github.com/leanprover/lean4/pull/5635) adds auxiliary bitblasters for negation and subtraction.
* [#5637](https://github.com/leanprover/lean4/pull/5637) adds more `getLsbD` bitblaster theory.
* [#5652](https://github.com/leanprover/lean4/pull/5652) adds umod support.
* [#5653](https://github.com/leanprover/lean4/pull/5653) adds performance benchmark for modulo.
* [#5655](https://github.com/leanprover/lean4/pull/5655) reduces error on `bv_check` to warning.
* [#5670](https://github.com/leanprover/lean4/pull/5670) adds `~~~(-x)` support.
* [#5673](https://github.com/leanprover/lean4/pull/5673) disables `ac_nf` by default.
* [#5675](https://github.com/leanprover/lean4/pull/5675) fixes context tracking in `bv_decide` counter example.
* [#5676](https://github.com/leanprover/lean4/pull/5676) adds an error when the LRAT proof is invalid.
* [#5781](https://github.com/leanprover/lean4/pull/5781) introduces uninterpreted symbols everywhere.
* [#5823](https://github.com/leanprover/lean4/pull/5823) adds `BitVec.sdiv` support.
* [#5852](https://github.com/leanprover/lean4/pull/5852) adds `BitVec.ofBool` support.
* [#5855](https://github.com/leanprover/lean4/pull/5855) adds `if` support.
* [#5869](https://github.com/leanprover/lean4/pull/5869) adds support for all the SMTLIB BitVec divison/remainder operations.
* [#5886](https://github.com/leanprover/lean4/pull/5886) adds embedded constraint substitution.
* [#5918](https://github.com/leanprover/lean4/pull/5918) fixes loose mvars bug in `bv_normalize`.
* Documentation:
* [#5636](https://github.com/leanprover/lean4/pull/5636) adds remarks about multiplication.
* `conv` mode
* [#5861](https://github.com/leanprover/lean4/pull/5861) improves the `congr` conv tactic to handle "over-applied" functions.
* [#5894](https://github.com/leanprover/lean4/pull/5894) improves the `arg` conv tactic so that it can access more arguments and so that it can handle "over-applied" functions (it generates a specialized congruence lemma for the specific argument in question). Makes `arg 1` and `arg 2` apply to pi types in more situations. Adds negative indexing, for example `arg -2` is equivalent to the `lhs` tactic. Makes the `enter [...]` tactic show intermediate states like `rw`.
* **Other tactics**
* [#4846](https://github.com/leanprover/lean4/pull/4846) fixes a bug where `generalize ... at *` would apply to implementation details (@ymherklotz).
* [#5730](https://github.com/leanprover/lean4/pull/5730) upstreams the `classical` tactic combinator.
* [#5815](https://github.com/leanprover/lean4/pull/5815) improves the error message when trying to unfold a local hypothesis that is not a local definition.
* [#5862](https://github.com/leanprover/lean4/pull/5862) and [#5863](https://github.com/leanprover/lean4/pull/5863) change how `apply` and `simp` elaborate, making them not disable error recovery. This improves hovers and completions when the term has elaboration errors.
* `deriving` clauses
* [#5899](https://github.com/leanprover/lean4/pull/5899) adds declaration ranges for delta-derived instances.
* [#5265](https://github.com/leanprover/lean4/pull/5265) removes unused syntax in `deriving` clauses for providing arguments to deriving handlers (see breaking changes).
* [#5065](https://github.com/leanprover/lean4/pull/5065) upstreams and updates `#where`, a command that reports the current scope information.
* **Linters**
* [#5338](https://github.com/leanprover/lean4/pull/5338) makes the unused variables linter ignore variables defined in tactics by default now, avoiding performance bottlenecks.
* [#5644](https://github.com/leanprover/lean4/pull/5644) ensures that linters in general do not run on `#guard_msgs` itself.
* **Metaprogramming interface**
* [#5720](https://github.com/leanprover/lean4/pull/5720) adds `pushGoal`/`pushGoals` and `popGoal` for manipulating the goal state. These are an alternative to `replaceMainGoal` and `getMainGoal`, and with them you don't need to worry about making sure nothing clears assigned metavariables from the goal list between assigning the main goal and using `replaceMainGoal`. Modifies `closeMainGoalUsing`, which is like a `TacticM` version of `liftMetaTactic`. Now the callback is run in a context where the main goal is removed from the goal list, and the callback is free to modify the goal list. Furthermore, the `checkUnassigned` argument has been replaced with `checkNewUnassigned`, which checks whether the value assigned to the goal has any *new* metavariables, relative to the start of execution of the callback. Modifies `withCollectingNewGoalsFrom` to take the `parentTag` argument explicitly rather than indirectly via `getMainTag`. Modifies `elabTermWithHoles` to optionally take `parentTag?`.
* [#5563](https://github.com/leanprover/lean4/pull/5563) fixes `getFunInfo` and `inferType` to use `withAtLeastTransparency` rather than `withTransparency`.
* [#5679](https://github.com/leanprover/lean4/pull/5679) fixes `RecursorVal.getInduct` to return the name of major arguments type. This makes "structure eta" work for nested inductives.
* [#5681](https://github.com/leanprover/lean4/pull/5681) removes unused `mkRecursorInfoForKernelRec`.
* [#5686](https://github.com/leanprover/lean4/pull/5686) makes discrimination trees index the domains of foralls, for better performance of the simplify and type class search.
* [#5760](https://github.com/leanprover/lean4/pull/5760) adds `Lean.Expr.name?` recognizer for `Name` expressions.
* [#5800](https://github.com/leanprover/lean4/pull/5800) modifies `liftCommandElabM` to preserve more state, fixing an issue where using it would drop messages.
* [#5857](https://github.com/leanprover/lean4/pull/5857) makes it possible to use dot notation in `m!` strings, for example `m!"{.ofConstName n}"`.
* [#5841](https://github.com/leanprover/lean4/pull/5841) and [#5853](https://github.com/leanprover/lean4/pull/5853) record the complete list of `structure` parents in the `StructureInfo` environment extension.
* **Other fixes or improvements**
* [#5566](https://github.com/leanprover/lean4/pull/5566) fixes a bug introduced in [#4781](https://github.com/leanprover/lean4/pull/4781) where heartbeat exceptions were no longer being handled properly. Now such exceptions are tagged with `runtime.maxHeartbeats` (@eric-wieser).
* [#5708](https://github.com/leanprover/lean4/pull/5708) modifies the proof objects produced by the proof-by-reflection tactics `ac_nf0` and `simp_arith` so that the kernel is less prone to reducing expensive atoms.
* [#5768](https://github.com/leanprover/lean4/pull/5768) adds a `#version` command that prints Lean's version information.
* [#5822](https://github.com/leanprover/lean4/pull/5822) fixes elaborator algorithms to match kernel algorithms for primitive projections (`Expr.proj`).
* [#5811](https://github.com/leanprover/lean4/pull/5811) improves the docstring for the `rwa` tactic.
### Language server, widgets, and IDE extensions
* [#5224](https://github.com/leanprover/lean4/pull/5224) fixes `WorkspaceClientCapabilities` to make `applyEdit` optional, in accordance with the LSP specification (@pzread).
* [#5340](https://github.com/leanprover/lean4/pull/5340) fixes a server deadlock when shutting down the language server and a desync between client and language server after a file worker crash.
* [#5560](https://github.com/leanprover/lean4/pull/5560) makes `initialize` and `builtin_initialize` participate in the call hierarchy and other requests.
* [#5650](https://github.com/leanprover/lean4/pull/5650) makes references in attributes participate in the call hierarchy and other requests.
* [#5666](https://github.com/leanprover/lean4/pull/5666) add auto-completion in tactic blocks without having to type the first character of the tactic, and adds tactic completion docs to tactic auto-completion items.
* [#5677](https://github.com/leanprover/lean4/pull/5677) fixes several cases where goal states were not displayed in certain text cursor positions.
* [#5707](https://github.com/leanprover/lean4/pull/5707) indicates deprecations in auto-completion items.
* [#5736](https://github.com/leanprover/lean4/pull/5736), [#5752](https://github.com/leanprover/lean4/pull/5752), [#5763](https://github.com/leanprover/lean4/pull/5763), [#5802](https://github.com/leanprover/lean4/pull/5802), and [#5805](https://github.com/leanprover/lean4/pull/5805) fix various performance issues in the language server.
* [#5801](https://github.com/leanprover/lean4/pull/5801) distinguishes theorem auto-completions from non-theorem auto-completions.
### Pretty printing
* [#5640](https://github.com/leanprover/lean4/pull/5640) fixes a bug where goal states in messages might print newlines as spaces.
* [#5643](https://github.com/leanprover/lean4/pull/5643) adds option `pp.mvars.delayed` (default false), which when false causes delayed assignment metavariables to pretty print with what they are assigned to. Now `fun x : Nat => ?a` pretty prints as `fun x : Nat => ?a` rather than `fun x ↦ ?m.7 x`.
* [#5711](https://github.com/leanprover/lean4/pull/5711) adds options `pp.mvars.anonymous` and `pp.mvars.levels`, which when false respectively cause expression metavariables and level metavariables to pretty print as `?_`.
* [#5710](https://github.com/leanprover/lean4/pull/5710) adjusts the `` elaboration warning to mention `pp.maxSteps`.
* [#5759](https://github.com/leanprover/lean4/pull/5759) fixes the app unexpander for `sorryAx`.
* [#5827](https://github.com/leanprover/lean4/pull/5827) improves accuracy of binder names in the signature pretty printer (like in output of `#check`). Also fixes the issue where consecutive hygienic names pretty print without a space separating them, so we now have `(x✝ y✝ : Nat)` rather than `(x✝y✝ : Nat)`.
* [#5830](https://github.com/leanprover/lean4/pull/5830) makes sure all the core delaborators respond to `pp.explicit` when appropriate.
* [#5639](https://github.com/leanprover/lean4/pull/5639) makes sure name literals use escaping when pretty printing.
* [#5854](https://github.com/leanprover/lean4/pull/5854) adds delaborators for `<|>`, `<*>`, `>>`, `<*`, and `*>`.
### Library
* `Array`
* [#5687](https://github.com/leanprover/lean4/pull/5687) deprecates `Array.data`.
* [#5705](https://github.com/leanprover/lean4/pull/5705) uses a better default value for `Array.swapAt!`.
* [#5748](https://github.com/leanprover/lean4/pull/5748) moves `Array.mapIdx` lemmas to a new file.
* [#5749](https://github.com/leanprover/lean4/pull/5749) simplifies signature of `Array.mapIdx`.
* [#5758](https://github.com/leanprover/lean4/pull/5758) upstreams `Array.reduceOption`.
* [#5786](https://github.com/leanprover/lean4/pull/5786) adds simp lemmas for `Array.isEqv` and `BEq`.
* [#5796](https://github.com/leanprover/lean4/pull/5796) renames `Array.shrink` to `Array.take`, and relates it to `List.take`.
* [#5798](https://github.com/leanprover/lean4/pull/5798) upstreams `List.modify`, adds lemmas, relates to `Array.modify`.
* [#5799](https://github.com/leanprover/lean4/pull/5799) relates `Array.forIn` and `List.forIn`.
* [#5833](https://github.com/leanprover/lean4/pull/5833) adds `Array.forIn'`, and relates to `List`.
* [#5848](https://github.com/leanprover/lean4/pull/5848) fixes deprecations in `Init.Data.Array.Basic` to not recommend the deprecated constant.
* [#5895](https://github.com/leanprover/lean4/pull/5895) adds `LawfulBEq (Array α) ↔ LawfulBEq α`.
* [#5896](https://github.com/leanprover/lean4/pull/5896) moves `@[simp]` from `back_eq_back?` to `back_push`.
* [#5897](https://github.com/leanprover/lean4/pull/5897) renames `Array.back` to `back!`.
* `List`
* [#5605](https://github.com/leanprover/lean4/pull/5605) removes `List.redLength`.
* [#5696](https://github.com/leanprover/lean4/pull/5696) upstreams `List.mapIdx` and adds lemmas.
* [#5697](https://github.com/leanprover/lean4/pull/5697) upstreams `List.foldxM_map`.
* [#5701](https://github.com/leanprover/lean4/pull/5701) renames `List.join` to `List.flatten`.
* [#5703](https://github.com/leanprover/lean4/pull/5703) upstreams `List.sum`.
* [#5706](https://github.com/leanprover/lean4/pull/5706) marks `prefix_append_right_inj` as a simp lemma.
* [#5716](https://github.com/leanprover/lean4/pull/5716) fixes `List.drop_drop` addition order.
* [#5731](https://github.com/leanprover/lean4/pull/5731) renames `List.bind` and `Array.concatMap` to `flatMap`.
* [#5732](https://github.com/leanprover/lean4/pull/5732) renames `List.pure` to `List.singleton`.
* [#5742](https://github.com/leanprover/lean4/pull/5742) upstreams `ne_of_mem_of_not_mem`.
* [#5743](https://github.com/leanprover/lean4/pull/5743) upstreams `ne_of_apply_ne`.
* [#5816](https://github.com/leanprover/lean4/pull/5816) adds more `List.modify` lemmas.
* [#5879](https://github.com/leanprover/lean4/pull/5879) renames `List.groupBy` to `splitBy`.
* [#5913](https://github.com/leanprover/lean4/pull/5913) relates `for` loops over `List` with `foldlM`.
* `Nat`
* [#5694](https://github.com/leanprover/lean4/pull/5694) removes `instBEqNat`, which is redundant with `instBEqOfDecidableEq` but not defeq.
* [#5746](https://github.com/leanprover/lean4/pull/5746) deprecates `Nat.sum`.
* [#5785](https://github.com/leanprover/lean4/pull/5785) adds `Nat.forall_lt_succ` and variants.
* Fixed width integers
* [#5323](https://github.com/leanprover/lean4/pull/5323) redefine unsigned fixed width integers in terms of `BitVec`.
* [#5735](https://github.com/leanprover/lean4/pull/5735) adds `UIntX.[val_ofNat, toBitVec_ofNat]`.
* [#5790](https://github.com/leanprover/lean4/pull/5790) defines `Int8`.
* [#5901](https://github.com/leanprover/lean4/pull/5901) removes native code for `UInt8.modn`.
* `BitVec`
* [#5604](https://github.com/leanprover/lean4/pull/5604) completes `BitVec.[getMsbD|getLsbD|msb]` for shifts (@luisacicolini).
* [#5609](https://github.com/leanprover/lean4/pull/5609) adds lemmas for division when denominator is zero (@bollu).
* [#5620](https://github.com/leanprover/lean4/pull/5620) documents Bitblasting (@bollu)
* [#5623](https://github.com/leanprover/lean4/pull/5623) moves `BitVec.udiv/umod/sdiv/smod` after `add/sub/mul/lt` (@tobiasgrosser).
* [#5645](https://github.com/leanprover/lean4/pull/5645) defines `udiv` normal form to be `/`, resp. `umod` and `%` (@bollu).
* [#5646](https://github.com/leanprover/lean4/pull/5646) adds lemmas about arithmetic inequalities (@bollu).
* [#5680](https://github.com/leanprover/lean4/pull/5680) expands relationship with `toFin` (@tobiasgrosser).
* [#5691](https://github.com/leanprover/lean4/pull/5691) adds `BitVec.(getMSbD, msb)_(add, sub)` and `BitVec.getLsbD_sub` (@luisacicolini).
* [#5712](https://github.com/leanprover/lean4/pull/5712) adds `BitVec.[udiv|umod]_[zero|one|self]` (@tobiasgrosser).
* [#5718](https://github.com/leanprover/lean4/pull/5718) adds `BitVec.sdiv_[zero|one|self]` (@tobiasgrosser).
* [#5721](https://github.com/leanprover/lean4/pull/5721) adds `BitVec.(msb, getMsbD, getLsbD)_(neg, abs)` (@luisacicolini).
* [#5772](https://github.com/leanprover/lean4/pull/5772) adds `BitVec.toInt_sub`, simplifies `BitVec.toInt_neg` (@tobiasgrosser).
* [#5778](https://github.com/leanprover/lean4/pull/5778) prove that `intMin` the smallest signed bitvector (@alexkeizer).
* [#5851](https://github.com/leanprover/lean4/pull/5851) adds `(msb, getMsbD)_twoPow` (@luisacicolini).
* [#5858](https://github.com/leanprover/lean4/pull/5858) adds `BitVec.[zero_ushiftRight|zero_sshiftRight|zero_mul]` and cleans up BVDecide (@tobiasgrosser).
* [#5865](https://github.com/leanprover/lean4/pull/5865) adds `BitVec.(msb, getMsbD)_concat` (@luisacicolini).
* [#5881](https://github.com/leanprover/lean4/pull/5881) adds `Hashable (BitVec n)`
* `String`/`Char`
* [#5728](https://github.com/leanprover/lean4/pull/5728) upstreams `String.dropPrefix?`.
* [#5745](https://github.com/leanprover/lean4/pull/5745) changes `String.dropPrefix?` signature.
* [#5747](https://github.com/leanprover/lean4/pull/5747) adds `Hashable Char` instance
* `HashMap`
* [#5880](https://github.com/leanprover/lean4/pull/5880) adds interim implementation of `HashMap.modify`/`alter`
* **Other**
* [#5704](https://github.com/leanprover/lean4/pull/5704) removes `@[simp]` from `Option.isSome_eq_isSome`.
* [#5739](https://github.com/leanprover/lean4/pull/5739) upstreams material on `Prod`.
* [#5740](https://github.com/leanprover/lean4/pull/5740) moves `Antisymm` to `Std.Antisymm`.
* [#5741](https://github.com/leanprover/lean4/pull/5741) upstreams basic material on `Sum`.
* [#5756](https://github.com/leanprover/lean4/pull/5756) adds `Nat.log2_two_pow` (@spinylobster).
* [#5892](https://github.com/leanprover/lean4/pull/5892) removes duplicated `ForIn` instances.
* [#5900](https://github.com/leanprover/lean4/pull/5900) removes `@[simp]` from `Sum.forall` and `Sum.exists`.
* [#5812](https://github.com/leanprover/lean4/pull/5812) removes redundant `Decidable` assumptions (@FR-vdash-bot).
### Compiler, runtime, and FFI
* [#5685](https://github.com/leanprover/lean4/pull/5685) fixes help message flags, removes the `-f` flag and adds the `-g` flag (@James-Oswald).
* [#5930](https://github.com/leanprover/lean4/pull/5930) adds `--short-version` (`-V`) option to display short version (@juhp).
* [#5144](https://github.com/leanprover/lean4/pull/5144) switches all 64-bit platforms over to consistently using GMP for bignum arithmetic.
* [#5753](https://github.com/leanprover/lean4/pull/5753) raises the minimum supported Windows version to Windows 10 1903 (released May 2019).
### Lake
* [#5715](https://github.com/leanprover/lean4/pull/5715) changes `lake new math` to use `autoImplicit false` (@eric-wieser).
* [#5688](https://github.com/leanprover/lean4/pull/5688) makes `Lake` not create core aliases in the `Lake` namespace.
* [#5924](https://github.com/leanprover/lean4/pull/5924) adds a `text` option for `buildFile*` utilities.
* [#5789](https://github.com/leanprover/lean4/pull/5789) makes `lake init` not `git init` when inside git work tree (@haoxins).
* [#5684](https://github.com/leanprover/lean4/pull/5684) has Lake update a package's `lean-toolchain` file on `lake update` if it finds the package's direct dependencies use a newer compatible toolchain. To skip this step, use the `--keep-toolchain` CLI option. (See breaking changes.)
* [#6218](https://github.com/leanprover/lean4/pull/6218) makes Lake no longer automatically fetch GitHub cloud releases if the package build directory is already present (mirroring the behavior of the Reservoir cache). This prevents the cache from clobbering existing prebuilt artifacts. Users can still manually fetch the cache and clobber the build directory by running `lake build <pkg>:release`.
* [#6231](https://github.com/leanprover/lean4/pull/6231) improves the errors Lake produces when it fails to fetch a dependency from Reservoir. If the package is not indexed, it will produce a suggestion about how to require it from GitHub.
### Documentation
* [#5617](https://github.com/leanprover/lean4/pull/5617) fixes MSYS2 build instructions.
* [#5725](https://github.com/leanprover/lean4/pull/5725) points out that `OfScientific` is called with raw literals (@eric-wieser).
* [#5794](https://github.com/leanprover/lean4/pull/5794) adds a stub for application ellipsis notation (@eric-wieser).
### Breaking changes
* The syntax for providing arguments to deriving handlers has been removed, which was not used by any major Lean projects in the ecosystem. As a result, the `applyDerivingHandlers` now takes one fewer argument, `registerDerivingHandlerWithArgs` is now simply `registerDerivingHandler`, `DerivingHandler` no longer includes the unused parameter, and `DerivingHandlerNoArgs` has been deprecated. To migrate code, delete the unused `none` argument and use `registerDerivingHandler` and `DerivingHandler`. ([#5265](https://github.com/leanprover/lean4/pull/5265))
* The minimum supported Windows version has been raised to Windows 10 1903, released May 2019. ([#5753](https://github.com/leanprover/lean4/pull/5753))
* The `--lean` CLI option for `lake` was removed. Use the `LEAN` environment variable instead. ([#5684](https://github.com/leanprover/lean4/pull/5684))
* The `inductive ... :=`, `structure ... :=`, and `class ... :=` syntaxes have been deprecated in favor of the `... where` variants. The old syntax produces a warning, controlled by the `linter.deprecated` option. ([#5542](https://github.com/leanprover/lean4/pull/5542))
* The generated tactic configuration elaborators now land in `TacticM` to make use of the current recovery state. Commands that wish to elaborate configurations should now use `declare_command_config_elab` instead of `declare_config_elab` to get an elaborator landing in `CommandElabM`. Syntaxes should migrate to `optConfig` instead of `(config)?`, but the elaborators are reverse compatible. ([#5883](https://github.com/leanprover/lean4/pull/5883))

Some files were not shown because too many files have changed in this diff Show More