Lean 4.19.0 (2025-05-01)
For this release, 420 changes landed. In addition to the 164 feature additions and 78 fixes listed below there were 13 refactoring changes, 29 documentation improvements, 31 performance improvements, 9 improvements to the test suite and 94 other changes.
Highlights
Lean v4.19.0 introduces a number of features, bug fixes, performance gains, library developments, along with quality-of-life improvements across documentation, the language server, and Lake.
New Decorations in VS Code
Visual feedback in VS Code has been improved, with the extension now featuring:
-
Gutter decorations for errors and warnings. These make the full range of errors/warnings clear, which is especially useful when the corresponding squigglies are small.
-
End-of-line markers for 'unsolved goals'. These are displayed at the line where 'unsolved goals' error ends and indicate where the proof needs to be continued.
-
'Goals accomplished!' message. When a theorem or a
Prop-typedexamplecontains no errors orsorrys anymore, two blue checkmarks appear next to the start of the declaration as a gutter decoration. Additionally, a 'Goals accomplished!' message appears under 'Messages' in the InfoView.
Gutter decorations for errors and warnings are available for all Lean 4 versions. Decorations for 'unsolved goals' and 'goals accomplished' rely on server-side support, which is added in this version via #7366.
All of these features can be disabled, and 'Goals accomplished!' icon can be configured in VS Code extension settings. See leanprover/vscode-lean4#585 for the details.
Parallel Elaboration
-
#7084 enables the elaboration of theorem bodies, i.e. proofs, to happen in parallel to each other as well as to other elaboration tasks.
Language Features
-
#5182 makes functions defined by well-founded recursion use an
opaquewell-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 change rendersunsealineffective for such definitions. To avoid the opaque proof, annotate the function definition with@[semireducible]. -
#7166 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
def app (as : List α) (bs : List α) : List α := match as with | [] => bs | a::as => a :: app as bs
produced
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 bsand now you get
app.induct.{u_1} {α : Type u_1} (motive : List α → Prop) (case1 : motive []) (case2 : ∀ (a : α) (as : List α), motive as → motive (a :: as)) (as : List α) : motive asbecause
bsis 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_inductionmakes proof tactics robust against this change.See the PR description for the rules for when a parameter is considered fixed.
Note that in a definition like
def app : List α → List α → List α | [], bs => bs | a::as, bs => a :: app as bs
the
bsis not considered fixed, as it goes through the matcher machinery. -
#7431 changes the syntax of location modifiers for tactics like
simpandrw(e.g.,simp at h ⊢) to allow the turnstile⊢to appear anywhere in the sequence of locations. -
#7457 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.infoStatemay need to callInfoState.substituteLazyon it manually to fill all holes.
Updates to structures and classes
-
#7302 changes how fields are elaborated in the
structure/classcommands 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). See the PR description for further details. -
#7640 implements the main logic for inheriting and overriding autoParam fields in the
structure/classcommands, 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. -
#7717 changes how
{...}/wherenotation ("structure instance notation") elaborates. The notation now tries to simulate a flat representation as much as possible, without exposing the details of subobjects. This is a breaking change, see the PR description for further details and mitigation strategies. -
#7742 adds a feature to
structure/classwhere binders without types on a field definition are interpreted as overriding the type's parameters binder kinds in that field's projection function. See the PR description for further details.
Library Updates
-
Developments in the async machinery;
-
Standardization of the integer division API;
-
Conversions between finite types;
-
API expansion of
BitVecand tree maps; -
Proofs of Bitwuzla rewrite rules;
-
Improvements to
List/Array/Vector, as well asHashMapandInt/Nat.
See the Library section below for details.
Other Highlights
-
Documentation has been significantly expanded. See the Documentation section below for details.
-
#7185 refactors Lake's build internals to enable the introduction of targets and facets beyond packages, modules, and libraries. Facets, build keys, build info, and CLI commands have been generalized to arbitrary target types.
Language
-
#5182 makes functions defined by well-founded recursion use an
opaquewell-founded proof by default; see highlights section for details. -
#5998 lets
omegaalways 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%. -
#6325 ensures that environments can be loaded, repeatedly, without executing arbitrary code
-
#7075 ensures that names suggested by tactics like
simp?are not shadowed by auxiliary declarations in the local context and that names oflet recandwheredeclarations are correctly resolved in tactic blocks. -
#7166 extends the notion of “fixed parameter” of a recursive function also to parameters that come after varying function; see highlights section for details.
-
#7256 introduces the
assert!variantdebug_assert!that is activated when compiled withbuildTypedebug. -
#7304 fixes an issue where nested
let recdeclarations withinmatchexpressions or tactic blocks failed to compile if they were nested within, and recursively called, alet recthat referenced a variable bound by a containing declaration. -
#7324 changes the internal construction of well-founded recursion, to not change the type of
fix’s induction hypothesis in non-defeq ways. -
#7333 allows aux decls (like generated by
match) to be generated by decreasing_by tactics. -
#7335 modifies
elabTerminationByHintsin 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. -
#7353 changes
abstractNestedProofsso that it also visits the subterms in the head of an application. -
#7362 allows simp dischargers to add aux decls to the environment. This enables tactics like
native_decideto be used here, and unblocks improvements to omega in #5998. -
#7387 uses
-implicitDefEqProofsinbv_omegato ensure it is not affected by the change in #7386. -
#7397 ensures that
Poly.mul p 0always returnsPoly.num 0. -
#7409 allows the use of
dsimpduring preprocessing of well-founded definitions. This fixes regressions when usingif-then-elsewithout 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) -
#7431 changes the syntax of location modifiers for tactics like
simpandrw(e.g.,simp at h ⊢) to allow the turnstile⊢to appear anywhere in the sequence of locations. -
#7509 disables the
implicitDefEqProofssimp option in the preprocessor ofbv_decidein order to account for regressions caused by #7387. -
#7511 fixes two bugs in
simp +ariththat were preventing specific subterms from being normalized. -
#7515 fixes another bug in
simp +arith. This bug was affectinggrind. See new test for an example. -
#7551 changes
isNatCmpto ignore optional arguments annotations, when checking for<-like comparison between elements ofNat. That previously causedguessLexto fail when checking termination of a function, whose signature involved an optional argument of the typeNat. -
#7560 ensures that we use the same ordering to normalize linear
Intterms and relations. This change affectssimp +arithandgrindnormalizer. -
#7622 fixes
fun_inductionwhen used on structurally recursive functions where there are targets occurring before fixed parameters. -
#7630 fixes a performance issue in the
whnfCoreprocedure. -
#7728 fixes an issue in
abstractNestedProofs. We should abstract proofs occurring in the inferred proposition too.
Structures
-
#7302 changes how fields are elaborated in the
structure/classcommands 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 atStructName.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_ctorconstructor 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
Magmatest 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.
-
-
#7314 changes elaboration of
structureparents so that each must be fully elaborated before the next one is processed. -
#7640 implements the main logic for inheriting and overriding autoParam fields in the
structure/classcommands, 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. -
#7652 gives
#printfor structures the ability to show the default values and auto-param tactics for fields. -
#7717 changes how
{...}/wherenotation ("structure instance notation") elaborates. The notation now tries to simulate a flat representation as much as possible, without exposing the details of subobjects. Features:-
When fields are elaborated, their expected types now have a couple reductions applied. For all projections and constructors associated to the structure and its parents, projections of constructors are reduced and constructors of projections are eta reduced, and also implementation detail local variables are zeta reduced in propositions (so tactic proofs should never see them anymore). Furthermore, field values are beta reduced automatically in successive field types. The example in mathlib4#12129 now shows a goal of
0 = 0rather than{ toFun := fun x => x }.toFun 0 = 0. -
All parents can now be used as field names, not just the subobject parents. These are like additional sources but with three constraints: every field of the value must be used, the fields must not overlap with other provided fields, and every field of the specified parent must be provided for. Similar to sources, the values are hoisted to
lets if they are not already variables, to avoid multiple evaluation. They are implementation detail local variables, so they get unfolded for successive fields. -
All class parents are now used to fill in missing fields, not just the subobject parents. Closes #6046. Rules: (1) only those parents whose fields are a subset of the remaining fields are considered, (2) parents are considered only before any fields are elaborated, and (3) only those parents whose type can be computed are considered (this can happen if a parent depends on another parent, which is possible since #7302).
-
Default values and autoparams now respect the resolution order completely: each field has at most one default value definition that can provide for it. The algorithm that tries to unstick default values by walking up the subobject hierarchy has been removed. If there are applications of default value priorities, we might consider it in a future release.
-
The resulting constructors are now fully packed. This is implemented by doing structure eta reduction of the elaborated expressions.
-
"Magic field definitions" (as reported on Zulip) have been eliminated. This was where fields were being solved for by unification, tricking the default value system into thinking they had actually been provided. Now the default value system keeps track of which fields it has actually solved for, and which fields the user did not provide. Explicit structure fields (the default kind) without any explicit value definition will result in an error. If it was solved for by unification, the error message will include the inferred value, like "field 'f' must be explicitly provided, its synthesized value is v"
-
When the notation is used in patterns, it now no longer inserts fields using class parents, and it no longer applies autoparams or default values. The motivation is that one expects patterns to match only the given fields. This is still imperfect, since fields might be solved for indirectly.
-
Elaboration now attempts error recovery. Extraneous fields log errors and are ignored, missing fields are filled with
sorry.
-
-
#7742 adds a feature to
structure/classwhere binders without types on a field definition are interpreted as overriding the type's parameters binder kinds in that field's projection function. The rules are (1) only a prefix of the binders are interpreted this way, (2) multi-identifier binders are allowed but they must all be for parameters, (3) only parameters that appear in the declaration itself (not fromvariables) can be overridden and (4) the updates will be applied after parameter binder kind inference is done. Binder updates are not allowed in default value redefinitions. Example application: In the following,(R p)causes theRandpparameters to be explicit, where normally they would be implicit.class CharP (R : Type u) [AddMonoidWithOne R] (p : Nat) : Prop where cast_eq_zero_iff (R p) : ∀ x : Nat, (x : R) = 0 ↔ p ∣ x #guard_msgs in #check CharP.cast_eq_zero_iff /- info: CharP.cast_eq_zero_iff.{u} (R : Type u) {inst✝ : AddMonoidWithOne R} (p : Nat) [self : CharP R p] (x : Nat) : ↑x = 0 ↔ p ∣ x -/ -
#7746 adds declaration ranges to structure fields that were copied from parents that aren't represented as subobjects, supporting "go to definition". The declaration range is the parent in the
extendsclause.
Parallel Elaboration
-
#7084 enables the elaboration of theorem bodies, i.e. proofs, to happen in parallel to each other as well as to other elaboration tasks.
-
#7247 makes generation of
matchequations and splitters compatible with parallelism. -
#7261 ensures all equation, unfold, induction, and partial fixpoint theorem generators in core are compatible with parallelism.
-
#7348 ensures all equation and unfold theorem generators in core are compatible with parallelism.
-
#7457 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.
-
#8101 fixes a parallelism regression where linters that e.g. check for errors in the command would no longer find such messages.
bv_decide
-
#7298 adds rewrites to bv_decide's preprocessing that concern combinations of if-then-else and operation such as multiplication or negation.
-
#7309 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.
-
#7329 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.
-
#7347 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.
-
#7381 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.
-
#7390 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.
-
#7407 adds rules for
-1#w * a = -aanda * -1#w = -ato bv_normalize as seen in Bitwuzla's BV_MUL_SPECIAL_CONST. -
#7417 adds support for enum inductive matches with default branches to bv_decide.
-
#7429 adds the BV_EXTRACT_FULL preprocessing rule from Bitwuzla to bv_decide.
-
#7436 adds simprocs that turn left and right shifts by constants into extracts to bv_decide.
-
#7438 adds the EQUAL_CONST_BV_ADD and BV_AND_CONST rules to bv_decide's preprocessor.
-
#7441 adds the BV_CONCAT_CONST, BV_CONCAT_EXTRACT and ELIM_ZERO_EXTEND rule from Bitwuzla to bv_decide.
-
#7477 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.
-
#7480 adds the necessary rewrites for the Bitwuzla rules BV_ULT_SPECIAL_CONST, BV_SIGN_EXTEND_ELIM, TODO.
-
#7486 adds the BitVec.add_neg_mul rule introduced in #7481 to bv_decide's preprocessor.
-
#7491 achieves a speed up in bv_decide's LRAT checker by improving its input validation.
-
#7521 adds the equivalent of
Array.emptyWithCapacityto the AIG framework and applies it tobv_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 aRefVec. -
#7527 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.
-
#7615 adds the ADD part of bitwuzlas BV_EXTRACT_ADD_MUL rule to bv_decide's preprocessor.
-
#7617 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.
-
#7636 makes sure that the expression level cache in bv_decide is maintained across the entire bitblaster instead of just locally per BitVec expression.
-
#7644 adds a cache to the reflection procedure of bv_decide.
-
#7649 changes the AIG representation of constants from
const (b : Bool)to a single constructorfalse. Since #7381Refcontains aninvertflag meaning the constanttruecan be represented as aReftofalsewithinvertset, so no expressivity is lost. -
#7655 adds the preprocessing rule for extraction over multiplication to bv_decide.
-
#7663 uses computed fields to store the hash code and pointer equality to increase performance of comparison and hashmap lookups on the core data structure used by the bitblaster.
-
#7670 improves the caching computation of the atoms assignment in bv_decide's reflection procedure.
-
#7698 adds more sharing and caching procedures to bv_decide's reflection step.
-
#7720 compresses the AIG representation by storing the inverter bit in the lowest bit of the gate descriptor instead of as a separate
Bool. -
#7727 avoids some unnecessary allocations in the CNF to dimacs conversion
-
#7733 ensures that in the AIG the constant circuit node is always stored at the first spot. This allows us to skip performing a cache lookup when we require a constant node.
Grind
-
#7355 fixes a bug in the
markNestedProofspreprocessor used in thegrindtactic. -
#7392 fixes an issue in the
grindtactic when case splitting on if-then-else expressions. -
#7510 ensures that
grindcan be used as a more powerfulcontradictiontactic, sparing the user from having to typeexfalso; grindorintros; exfalso; grind. -
#7512 adds missing normalization rules for
Natdiv and mod to thegrindtactic. -
#7514 adds more missing normalization rules for
divandmodtogrind. -
#7532 fixes the procedure for putting new facts into the
grind"to-do" list. It ensures the new facts are preprocessed. also removes some of the clutter in theNat.subsupport. -
#7540 adds
[grind cases eager]attribute toSubtype. See new test. -
#7553 removes a bad normalization rule in
grind, and adds a missing dsimproc. -
#7641 implements basic model-based theory combination in
grind.grindcan now solve examples such asexample (f : Int → Int) (x : Int) : 0 ≤ x → x ≠ 0 → x ≤ 1 → f x = 2 → f 1 = 2 := by grind -
#7712 ensures
grindalways abstract its own proofs into an auxiliary definition/theorem. This is similar to #5998 but forgrind -
#7714 fixes an assertion violation in the
grindmodel-based theory combination module. -
#7723 adds the configuration options
zetaandzetaDeltaingrind. Both are set totrueby default. -
#7724 adds
dite_eq_itenormalization rule togrind. This rule is important to adjust mismatches between a definition and its function induction principle. -
#7726 fixes the
markNestedProofsprocedure used ingrind. It was missing the case where the type of a nested proof may contain other nested proofs. -
#7760 ensures
grindis using the default transparency setting when computing auxiliary congruence lemmas. -
#7765 improves how
grindnormalizes dependent implications during introduction. Previously,grindwould introduce a hypothesish : pfor a goal of the form.. ⊢ (h : p) → q h, and then normalize and assert a non-dependent copy ofp. As a result, the local context would contain bothh : pand a separateh' : p', wherep'is the normal form ofp. Moreover,qwould still depend on the originalh. -
#7776 improves the equality proof discharger used by the E-matching procedure in
grind. -
#7777 fixes the introduction procedure used in
grind. It was not registering local instances that are also propositions. See new test. -
#7778 adds missing propagation rules for
LawfulBEq Atogrind. They are needed in a context where the instanceDecidableEq Ais not available. See new test. -
#7781 adds a new propagation rule for
Booldisequalities togrind. It now propagatesx = true(x = false) from the disequalityx = false(x = true). It ensures we don't have to perform case analysis onxto learn this fact. See tests.
CutSat
-
#7312 implements proof term generation for
cooper_dvd_leftand its variants in the cutsat procedure for linear integer arithmetic. -
#7315 implements the Cooper conflict resolution in cutsat. We still need to implement the backtracking and disequality case.
-
#7339 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
omegafails to solve: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 -
#7351 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:
example (x : Int) : 100 ≤ x → x ≤ 10000 → 20000 ∣ 3*x → False := by grind
-
#7357 adds support for
/and%to the cutsat procedure. -
#7369 uses
let-declarations for each polynomial occurring in a proof term generated by the cutsat procedure. -
#7370 simplifies the proof term due to the Cooper's conflict resolution in cutsat.
-
#7373 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.
-
#7394 adds infrastructure necessary for supporting
Natin the cutsat procedure. It also makes thegrindmore robust. -
#7396 fixes a bug in the cutsat model construction. It was searching for a solution in the wrong direction.
-
#7401 improves the cutsat model search procedure by tightening inequalities using divisibility constraints.
-
#7494 implements support for
Natinequalities in the cutsat procedure. -
#7495 implements support for
Natdivisibility constraints in the cutsat procedure. -
#7501 implements support for
Natequalities and disequalities in the cutsat procedure. -
#7502 implements support for
Natdiv and mod in the cutsat procedure. -
#7503 implements support for
Nat.subin cutsat -
#7536 implements support for
¬ d ∣ pin the cutsat procedure. -
#7537 implements support for
Int.natAbsandInt.toNatin the cutsat procedure. -
#7538 fixes a bug in the cutsat model construction. It was not resetting the decision stack at the end of the search.
-
#7561 fixes the support for nonlinear
Natterms in cutsat. For example, cutsat was failing in the following exampleexample (i j k l : Nat) : i / j + k + l - k = i / j + l := by grind
because we were not adding the fact that
i / jis non negative when we inject theNatexpression intoInt. -
#7579 improves the counterexamples produced by the cutsat procedure, and adds proper support for
Nat. Before this PR, the assignment for an natural variablexwould be represented asNatCast.natCast x.
Library
-
#6496 adds short-circuit support to bv_decide to accelerate multiplications with shared coefficients. In particular,
a * x = b * xcan be extended toa = b v (a * x = b * x). The latter is faster ifa = bis true, asa = bmay be evaluated without considering the multiplication circuit. On the other hand, we require the multiplication circuit, asa * x = b * x -> a = bis not always true due to two's complement wrapping. -
#7141 generalizes
condto allow the motive to be inSort u, not justType u. -
#7289 adds
getKey_beq,getKey_congrand variants to the hashmap api. -
#7319 continues alignment of lemmas about
Int.ediv/fdiv/tdiv, including adding notes about "missing" lemmas that do not apply in one case. Also lemmas aboutemod/fmod/tmod. There's still more to do. -
#7338 adds @[simp] to
Int.neg_inj. -
#7341 adds an equivalence relation to the hash map with several lemmas for it.
-
#7356 adds lemmas reducing monadic operations with
pureto the non-monadic counterparts. -
#7358 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
tdivandfdivthat are missing, but as they would have quite awkward statements I'm hoping that for now no one is going to miss them. -
#7378 adds lemmas about
Intthat will be required in #7368. -
#7380 moves
DHashMap.Raw.foldRev(M)intoDHashMap.Raw.Internal. -
#7406 makes the instance for
Subsingleton (Squash α)work forα : Sort u. -
#7418 renames several hash map lemmas (
get->getElem) and usesm[k]?instead ofget? m k(and also forget!andget). -
#7432 adds a consequence of
Nat.add_divusing a divisibility hypothesis. -
#7433 makes
simpable to simplify basicforloops in monads other thanId. -
#7435 reviews the
NatandIntAPI, making the interfaces more consistent. -
#7445 renames
Array.mkEmptytoemptyWithCapacity. (Similarly forByteArrayandFloatArray.) -
#7446 prefers using
∅instead of.emptyfunctions. We may later rename.emptyfunctions to avoid the naming clash withEmptyCollection, and to better express semantics of functions which take an optional capacity argument. -
#7451 renames the member
insert_emptyc_eqof theLawfulSingletontypeclass toinsert_empty_eqto conform to the recommended spelling of∅asempty. -
#7466 further cleans up simp lemmas for
Int. -
#7516 changes the order of arguments for
List.modifyandList.insertIdx, making them consistent withArray. -
#7522 splits off the required theory about
Nat,FinandBitVecfrom #7484. -
#7529 upstreams
bind_congrfrom Mathlib and proves that the minimum of a sorted list is its head and weakens the antisymmetry condition ofmin?_eq_some_iff. Instead of requiring anStd.Antisymminstance,min?_eq_some_iffnow 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 fromStd.Antisymm, so existing usages of the theorem will most likely continue to work. -
#7541 corrects names of a number of lemmas, where the incorrect name was identified automatically by a tool written by @Rob23oba.
-
#7554 adds SMT-LIB operators to detect overflow
BitVec.negOverflow, according to the SMTLIB standard, and the theorem proving equivalence of such definition with theBitVeclibrary functions (negOverflow_eq). -
#7558 changes the definition of
Nat.divandNat.modto use a structurally recursive, fuel-based implementation rather than well-founded recursion. This leads to more predicable reduction behavior in the kernel. -
#7565 adds
BitVec.toInt_sdivplus a lot of related bitvector theory around divisions. -
#7614 marks
Nat.divandNat.modCoreasirreducible, to recover the behavior from from before #7558. -
#7672 reviews the implicitness of arguments across List/Array/Vector, generally trying to make arguments implicit where possible, although sometimes correcting propositional arguments which were incorrectly implicit to explicit.
-
#7687 provides
Inhabited,Ord(if missing),TransOrd,LawfulEqOrdandLawfulBEqOrdinstances for various types, namelyBool,String,Nat,Int,UIntX,Option,Prodand date/time types. It also adds a few related theorems, especially about how theOrdinstance forIntrelates toLEandLT. -
#7692 upstreams a small number of ordering lemmas for
Finfrom mathlib. -
#7700 provides
Ord-related instances such asTransOrdforIntX,Ordering,BitVec,Array,ListandVector. -
#7704 adds lemmas about the modulo operation defined on signed bounded integers.
-
#7706 performs various cleanup tasks on
Init/Data/UInt/*andInit/Data/SInt/*. -
#7729 replaces
assert!withassertBEqto fix issues where asserts didn't trigger thectestdue to being in a separate task. This was caused by panics not being caught in tasks, while IO errors were handled by theAsyncTaskif we use theblockfunction on them. -
#7756 adds lemmas about
Nat.gcd(some of which are currently present in mathlib).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
getElemvariants instead ofget.
Async
-
#6683 introduces TCP socket support using the LibUV library, enabling asynchronous I/O operations with it.
-
#7571 fixes #7478 by modifying
numberspecifiers fromatLeast sizetoflexible sizefor parsing. This change allows:-
1 repetition to accept 1 or more characters
-
More than 1 repetition to require exactly that many characters
-
-
#7574 introduces UDP socket support using the LibUV library, enabling asynchronous I/O operations with it.
-
#7578 introduces a function called
interfaceAddressesthat retrieves an array of system’s network interfaces. -
#7584 introduces a structure called
FormatConfig, which provides additional configuration options forGenericFormat, such as whether leap seconds should be allowed during parsing. By default, this option is set tofalse. -
#7751 adds
Std.BaseMutex.tryLockandStd.Mutex.tryAtomicallyas well as unit tests for our locking and condition variable primitives. -
#7755 adds
Std.RecursiveMutexas a recursive/reentrant equivalent toStd.Mutex. -
#7771 adds a barrier primitive as
Std.Barrier.
Finite Types
-
#7228 adds simprocs to reduce expressions involving
IntX. -
#7274 adds lemmas about iterated conversions between finite types, starting with something of type
IntX. -
#7340 adds lemmas for iterated conversions between finite types which start with
Nat/Int/Fin/BitVecand then go throughUIntX. -
#7368 adds lemmas for iterated conversions between finite types, starting with something of type
Nat/Int/Fin/BitVecand going throughIntX. -
#7414 adds the remaining lemmas about iterated conversions of finite type that go through signed or unsigned bounded integers.
-
#7484 adds some lemmas about operations defined on
UIntX -
#7487 adds the instance
Neg UInt8. -
#7592 adds theory about signed finite integers relating operations and conversion functions.
-
#7598 adds miscellaneous results about
NatandBitVecthat will be required forIntXtheory (#7592). -
#7685 contains additional material about
BitVecandIntspun off from #7592. -
#7694 contains additional material on
BitVec,IntandNat, split off from #7592.
Tree Map
-
#7270 provides lemmas about the tree map functions
foldlM,foldl,foldrMandfoldrand their interactions with other functions for which lemmas already exist. Additionally, it generalizes thefold*/keyslemmas to arbitrary tree maps, which were previously stated only for theDTreeMap α Unitcase. -
#7331 provides lemmas about the tree map function
insertManyand its interaction with other functions for which lemmas already exist. Most lemmas aboutofList, which is related toinsertMany, are not included. -
#7360 provides lemmas about the tree map function
ofListand interactions with other functions for which lemmas already exist. -
#7367 provides lemmas for the tree map functions
alterandmodifyand their interactions with other functions for which lemmas already exist.BREAKING CHANGE: The signature of
size_alterwas corrected for all four hash map types. Instead of relying on the boolean operationscontainsand&&in the if statements, we now use theProp-based operationsMembershipandAnd. -
#7412 provides lemmas about the tree map that have been introduced to the hash map in #7289.
-
#7419 provides lemmas about the tree map function
modifyand its interactions with other functions for which lemmas already exist. -
#7437 provides (some but not all) lemmas about the tree map function
minKey?. -
#7556 provides lemmas about the tree map function
minKey?and its interaction with other functions for which lemmas already exist. -
#7600 provides lemmas about the tree map function
minKey!and its interactions with other functions for which lemmas already exist. -
#7626 provides lemmas for the tree map function
minKeyDand its interations with other functions for which lemmas already exist. -
#7657 provides lemmas for the tree map function
maxKey?and its interations with other functions for which lemmas already exist. -
#7660 provides lemmas for the tree map function
minKeyand its interations with other functions for which lemmas already exist. -
#7664 fixes a bug in the definition of the tree map functions
maxKeyandmaxEntry. Moreover, it provides lemmas for this function and its interactions with other function for which lemmas already exist. -
#7674 add missing lemmas about the tree map:
minKey*variants return the head ofkeys,keysandtoListare ordered andgetKey* t.minKey?equals the minimum. -
#7675 provides lemmas about the tree map function
maxKeyDand its interactions with other functions for which lemmas already exist. -
#7686 provides lemmas for the tree map function
maxKey!and its interactions with other functions for which lemmas already exist. -
#7695 removes simp lemmas about the tree map with a metavariable in the head of the discrimination pattern.
-
#7697 is a follow-up to #7695, which removed
simpattributes from tree map lemmas with bad discrimination patterns. In this PR, we introduce someOrd-based lemmas that are more simp-friendly.
BitVec API
-
#7104 adds
BitVec.[toNat|toFin|toInt]_[sshiftRight|sshiftRight']plus variants withof_msb_*. While at it, we also addtoInt_zero_lengthandtoInt_of_zero_length. In support of our main theorem we addtoInt_shiftRight_ltandle_toInt_shiftRight, which make the main theorem automatically derivable via omega. -
#7225 contains
BitVec.(toInt, toFin)_twoPowtheorems, completing the API forBitVec.*_twoPow. It also expands thetoNat_twoPowAPI withtoNat_twoPow_of_le,toNat_twoPow_of_lt, as well astoNat_twoPow_eq_ifand movesmsb_twoPowup, as it is used in thetoInt_msbproof. -
#7415 adds a few lemmas about the interactions of
BitVecwithFinandNat. -
#7420 generalizes
BitVec.toInt_[lt|le]'to not require0 < w. -
#7465 adds the theorem:
theorem lt_allOnes_iff {x : BitVec w} : x < allOnes w ↔ x ≠ allOnes wto simplify comparisons against
-1#w. This is a corollary of the existing lemma:theorem allOnes_le_iff {x : BitVec w} : allOnes w ≤ x ↔ x = allOnes w -
#7599 adds SMT-LIB operators to detect overflow
BitVec.(usubOverflow, ssubOverflow), according to the SMTLIB standard, and the theorems proving equivalence of such definition with theBitVeclibrary functionsBittVec.(usubOverflow_eq, ssubOverflow_eq). -
#7604 adds bitvector theorems that to push negation into other operations, following Hacker's Delight: Ch2.1.
-
#7605 adds theorems
BitVec.[(toInt, toFin)_(extractLsb, extractLsb')], completing the API forBitVec.(extractLsb, extractLsb'). -
#7616 introduces
BitVec.(toInt, toFin)_rotate(Left, Right), completing the API forBitVec.rotate(Left, Right) -
#7658 introduces
BitVec.(toFin_signExtend_of_le, toFin_signExtend), completing the API forBitVec.signExtend. -
#7661 adds theorems
BitVec.[(toFin, toInt)_setWidth', msb_setWidth'_of_lt, toNat_lt_twoPow_of_le, toInt_setWidth'_of_lt], completing the API forBitVec.setWidth'. -
#7699 adds the
BitVec.toInt_sremlemma, relatingBitVec.sremwithInt.tmod.
Bitwuzla Rewrite Rules
-
#7424 proves Bitwuzla's rule
BV_ZERO_EXTEND_ELIM: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 -
#7426 adds the Bitwuzla rewrite rule
BV_EXTRACT_FULL, which is useful for the bitblaster to simplifyextractLsb'based expressions. -
#7427 implements the bitwuzla rule
BV_CONCAT_EXTRACT. This will be used by the bitblaster to simplify adjacentextracts into a singleextract. -
#7454 implements the bitwuzla rule BV_SIGN_EXTEND_ELIM, which rewrites a
signExtend xas anappendof the appropriate sign bits, followed by the bits ofx. -
#7461 introduces a bitvector associativity/commutativity normalization on bitvector terms of the form
(a * b) = (c * d)fora, b, c, dbitvectors. This mirrors Bitwuzla'sPassNormalize::process'sPassNormalize::normalize_eq_add_mul. -
#7481 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:theorem neg_add_mul_eq_mul_not {x y : BitVec w} : - (x + x * y) = (x * ~~~ y) -
#7482 implements the BV_EXTRACT_CONCAT 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_CONCATtheorems: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 -
#7493 implements the Bitwuzla rewrite rule NORM_BV_ADD_MUL, and the associated lemmas to allow for expedient rewriting:
theorem neg_add_mul_eq_mul_not {x y : BitVec w} : - (x + x * y) = x * ~~~ y -
#7508 shows that negation commutes with left shift, which is the Bitwuzla rewrite NORM_BV_SHL_NEG.
-
#7594 implements the Bitwuzla rewrites BV_EXTRACT_ADD_MUL, which witness that the high bits at
i >= lendo not affect the bits of the product uptolen. -
#7595 implements the addition rewrite from the Bitwuzla rewrite BV_EXTRACT_ADD_MUL, which witness that the high bits at
i >= lendo not affect the bits of the sum uptolen: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 -
#7757 adds the Bitwuzla rewrite
NORM_BV_ADD_CONCATfor symbolic simplification of add-of-append.
Compiler
-
#7398 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.
-
#7710 improves memory use of Lean, especially for longer-running server processes, by up to 60%
Pretty Printing
-
#7589 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.defaultsto true forces such fields to be pretty printed anyway.
Documentation
-
#7198 makes the docstrings in the
Charnamespace follow the documentation conventions. -
#7204 adds docstrings for the
Idmonad. -
#7246 updates existing docstrings for Bool and adds the missing ones.
-
#7288 fixes the doc of
List.removeAll -
#7365 updates docstrings and adds some that are missing.
-
#7452 makes the style of all
Listdocstrings that appear in the language reference consistent. -
#7476 adds missing docstrings for
IOand related code and makes the style of the existing docstrings consistent. -
#7492 adds missing
Arraydocstrings and makes their style consistent. -
#7506 adds missing
Stringdocstrings and makes the existing ones consistent in style. -
#7523 adds missing docstrings and makes docstring style consistent for
SystemandSystem.FilePath. -
#7528 makes the docstrings for
Thunkconsistent with the style of the others. -
#7534 adds missing
Syntax-related docstrings and makes the existing ones consistent in style with the others. -
#7535 revises the docstring for
funext, making it more concise and adding a reference to the manual for more details. -
#7548 adds missing monad transformer docstrings and makes their style consistent.
-
#7552 adds missing
Natdocstrings and makes their style consistent. -
#7564 updates the docstrings for
ULiftandPLift, making their style consistent with the others. -
#7568 adds missing
Intdocstrings and makes the style of all of them consistent. -
#7602 adds missing docstrings for fixed-width integer operations and makes their style consistent.
-
#7607 adds docstrings for
String.dropandString.dropRight. -
#7613 adds a variety of docstrings for names that appear in the manual.
-
#7635 adds missing docstrings for
Substringand makes the style ofSubstringdocstrings consistent. -
#7642 reviews the docstrings for
FloatandFloat32, adding missing ones and making their format consistent. -
#7645 adds missing docstrings and makes docstring style consistent for
ForM,ForIn,ForIn',ForInStep,IntCast, andNatCast. -
#7711 adds the last few missing docstrings that appear in the manual.
-
#7713 makes the BitVec docstrings match each other and the rest of the API in style.
Server
-
#7178 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.
-
#7223 implements parallel watchdog request processing so that requests that are processed by the watchdog cannot block the main thread of the watchdog anymore.
-
#7240 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.
-
#7343 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.
-
#7344 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.
-
#7346 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.
-
#7366 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
theoremorProp-typedexamplehas no errors orsorrys. The Lean 4 VS Code extension companion PR is at leanprover/vscode-lean4#585. -
#7376 ensures
weakoptions do not have to be repeated in both LakeleanOptionsandmoreServerOptions. -
#7882 fixes a regression where elaboration of a previous document version is not cancelled on changes to the document.
Lake
-
#7185 refactors Lake's build internals to enable the introduction of targets and facets beyond packages, modules, and libraries. Facets, build keys, build info, and CLI commands have been generalized to arbitrary target types.
-
#7393 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. -
#7399 reverts the new builtin initializers, elaborators, and macros in Lake back to non-builtin.
-
#7504 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. -
#7543 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.
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. -
#7576 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.
-
#7586 changes the
static.exportfacet for Lean libraries to produce thin static libraries. -
#7608 removes the use of the Lake plugin in the Lake build and in configuration files.
-
#7667 changes Lake to log messages from a Lean configuration the same way it logs message from a Lean build. This, for instance, removes redundant severity captions.
-
#7703 adds
input_fileandinput_diras new target types. It also adds theneedsconfiguration option for Lean libraries and executables. This option generalizesextraDepTargets(which will be deprecated in the future), providing much richer support for declaring dependencies across package and target type boundaries. -
#7716 adds the
moreLinkObjsandmoreLinkLibsoptions for Lean packages, libraries, and executables. These serves as functional replacements forextern_liband provided additional flexibility.Breaking change:
precompileModulesnow only loads modules of the current library individually. Modules of other libraries are loaded together via that library's shared library. -
#7732 deprecates
extraDepTargetsand fixes a bug caused by the configuration refactor. -
#7758 removes the
-lstdcppextra link argument from the FFI example. It is not actually necessary. -
#7763 corrects build key fetches to produce jobs with the proper data kinds and fixes a failed coercion from key literals to targets.
Other
-
#7326 updates the release notes script to better indent PR descriptions.
-
#7453 adds "(kernel)" to the message for the kernel-level application type mismatch error.
-
#7769 fixes a number of bugs in the release automation scripts, adds a script to merge tags into remote
stablebranches, and makes the mainrelease_checklist.pyscript give suggestions to call themerge_remote.pyandrelease_steps.pyscripts when needed.