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 α := 匹配为 | [] =>废话 | a::as => a :: app 作为 bs
produced
app.induct.{u_1} {α : Type u_1}(动机:列表α→列表α→Prop)(情况1:∀(bs:列表α),动机[] bs) (case2 : ∀ (bs : 列表 α) (a : α) (as : 列表 α),动机为 bs → 动机 (a :: as) bs) (as bs : 列表 α) : 动机为 bsand now you get
app.induct.{u_1} {α : Type u_1}(动机:列表α→Prop)(案例1:动机[]) (case2 : ∀ (a : α) (as : List α),动机 as → motive (a :: as)) (as : List α) : 动机 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 α | [],废话=>废话 | 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 /- 信息: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 := 由 磨 -
#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 → 假 := 通过 磨 -
#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 磨
-
#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 theLawfulSingletontype class 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 predictable 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 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 interactions with other functions for which lemmas already exist. -
#7657 provides lemmas for the tree map function
maxKey?and its interactions with other functions for which lemmas already exist. -
#7660 provides lemmas for the tree map function
minKeyand its interactions 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' 起始长度 (xhi ++ xlo) = 如果 hstart : 开始 < w 那么 如果 hlen : 开始 + len < w 然后 extractLsb' start len xlo 否则 (((extractLsb' (start - w) (len - (w - start)) xhi) ++ extractLsb' start (w - start) xlo)).cast (by omega) 否则 extractLsb'(开始 - w)len xhi -
#7493 实现 Bitwuzla 重写规则 NORM_BV_ADD_MUL, 以及相关的引理以方便重写:
theorem neg_add_mul_eq_mul_not {x y : BitVec w} : - (x + x * y) = x * ~~~ y -
#7508 显示求反与左移进行交换,即 比特乌兹拉重写 NORM_BV_SHL_NEG。
-
#7594 实现 Bitwuzla 重写 BV_EXTRACT_ADD_MUL, 这见证了
i >= len的高位不影响 该产品最高可达len。 -
#7595 实现 Bitwuzla 重写的加法重写 BV_EXTRACT_ADD_MUL, 这见证了
i >= len的高位不影响 总计len: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 为符号添加 Bitwuzla 重写
NORM_BV_ADD_CONCAT简化add-of-append。
编译器
漂亮的印刷
-
#7589 更改了打印机的结构实例符号,以便 如果字段的值定义等于默认值,则字段被省略 字段的值(最高可达可降低的透明度)。设置
pp.structureInstances.defaults为 true 迫使此类字段变得漂亮 无论如何打印。
文档
-
#7198 使
Char命名空间中的文档字符串遵循 文档约定。 -
#7204 添加
Idmonad 的文档字符串。 -
#7246 更新 Bool 的现有文档字符串并添加缺失的文档字符串。
-
#7288 修复了
List.removeAll的文档 -
#7365 更新文档字符串并添加一些缺失的内容。
-
#7452 使出现在 语言参考一致。
-
#7476 添加
IO缺失的文档字符串和相关代码,并使 与现有文档字符串的风格一致。 -
#7492 添加缺失的
Array文档字符串并使其风格 一致。 -
#7506 添加缺失的
String文档字符串并生成现有文档字符串 风格一致。 -
#7523 添加缺失的文档字符串并使文档字符串样式保持一致
System和System.FilePath。 -
#7528 使
Thunk的文档字符串与 其他人。 -
#7534 添加缺失的
Syntax相关文档字符串并使现有的 与其他风格一致的。 -
#7535 修改了
funext的文档字符串,使其更加简洁和 添加对手册的参考以获取更多详细信息。 -
#7548 添加缺失的 monad 转换器文档字符串并使其风格 一致。
-
#7552 添加了缺失的
Nat文档字符串并使其风格保持一致。 -
#7564 更新了
ULift和PLift的文档字符串,使其 风格与其他一致。 -
#7568 添加缺失的
Int文档字符串并制作所有文档字符串的样式 一致。 -
#7602 添加 固定位宽整数 操作缺少的文档字符串 使他们的风格保持一致。
-
#7607 添加
String.drop和String.dropRight的文档字符串。 -
#7613 为出现在 手册。
-
#7635 为
Substring添加缺失的文档字符串,并使样式为Substring文档字符串一致。 -
#7642 查看
Float和Float32的文档字符串,添加缺失的内容 并使其格式一致。 -
#7645 添加缺失的文档字符串并使文档字符串样式保持一致
ForM、ForIn、ForIn'、ForInStep、IntCast和NatCast。 -
#7711 添加了手册中最后几个缺失的文档字符串。
-
#7713 使 BitVec 文档字符串彼此匹配以及其余部分匹配 API 时尚。
服务器
-
#7178 修复了语言服务器中的竞争条件 有时会导致它丢弃请求并且永远不会响应它们 编辑文件的标题。这反过来可能会导致语义 突出显示以停止在 VS Code 中运行,因为 VS Code 将停止 当先前的请求被丢弃时发出请求,也会导致 InfoView 出现缺陷。它还会导致导入自动完成 感觉有点奇怪,因为这些请求有时会被放弃。这个 自语言服务器首次出现以来,竞争条件就一直存在于语言服务器中 2020 年版本。
-
#7223 实现并行看门狗请求处理,以便请求 看门狗处理的数据不能阻塞主线程 看门狗了。
-
#7240 添加了用于链接到语言中的部分的规范语法 参考以及文档字符串中示例的格式根据 文档字符串风格指南。
-
#7343 缓解了在 VS Code 中插入嵌入提示的问题 双击会将镶嵌提示插入到错误的位置右侧 编辑后。
-
#7344 将自动隐式嵌入提示工具提示合并为一个 工具提示。这解决了 VS Code 中的一个问题,即 VS Code 无法 移动时更新相邻镶嵌提示部分中工具提示的悬停 鼠标。
-
#7346 修复了语言服务器遇到嵌入的问题 删除仍处于打开状态的文件时提示断言冲突 语言服务器。
-
#7366 添加了对专用“未解决的目标”的服务器端支持,并且 “目标完成”诊断将在以下方面得到特别支持 Lean 4 VS 代码扩展。特殊的“未解决的目标”诊断是 改编自“未解决的目标”错误诊断,而“目标” 当
theorem或Prop类型时,发出已完成的诊断example没有错误或sorry。 Lean 4 VS 代码扩展 同伴 PR 位于leanprover/vscode-lean4#585。 -
#7376 确保
weak选项不必在两个 Lake 中重复leanOptions和moreServerOptions。 -
#7882 修复了先前文档的精化的回归 版本不会因文档更改而取消。
Lake
-
#7185 重构了 Lake 的构建内部结构,以引入 包、模块和库之外的目标和方面。刻面, 构建密钥、构建信息和 CLI 命令已概括为 任意目标类型。
-
#7393 添加了对 Lake 配置字段的自动完成支持 Lean DSL 位于现有字段后的缩进空格处。 目前仍然无法在没有任何字段的情况下自动完成 支持。
重大更改: 非标准花括号配置语法现在使用分号
;而不是逗号,作为分隔符。缩进仍然可以用作分隔符的替代方案。 -
#7399 恢复新的内置初始化器、详细说明器和宏 Lake 回非内置。
-
#7504 增强了 Lake 配置数据结构声明 (例如,
PackageConfig、LeanLibConfig)以生成其他元数据 用于自动生成 Lean 和 TOML 编码器和 通过元程序解码器。 -
#7543 统一动态目标的配置声明, 外部库、Lean 库和 Lean 可执行文件集成到单个文件中 数据类型存储在包内的统一映射中。
重大更改: 用户不能再定义具有相同名称但不同类型的多个目标(例如,Lean 可执行文件和 Lean 库均名为
foo)。这不会影响大多数用户,因为 Lake DSL 已经阻止了这种情况。 -
#7576 将 Lake 更改为在以下情况下在 Windows 上生成和使用响应文件: 构建可执行文件和库(静态和共享)。这样做是为了 避免可能超过 Windows 命令行长度限制。
-
#7586 更改 Lean 库的
static.export方面以生成 瘦静态库。 -
#7608 删除了 Lake 构建和中 Lake 插件的使用 配置文件。
-
#7667 将 Lake 更改为记录来自 Lean 配置的消息 它记录来自 Lean 版本的消息的方式。例如,这会删除 冗余的严重性标题。
-
#7703 添加
input_file和input_dir作为新的目标类型。它还 添加了 Lean 库的needs配置选项 可执行文件。此选项概括了extraDepTargets(这将是 将来已弃用),为声明提供更丰富的支持 跨包和目标类型边界的依赖关系。 -
#7716 为 Lean 添加
moreLinkObjs和moreLinkLibs选项 包、库和可执行文件。这些用作功能性extern_lib的替代品并提供额外的灵活性。重大更改:
precompileModules现在仅单独加载当前库的模块。其他库的模块通过该库的共享库一起加载。 -
#7732 弃用
extraDepTargets并修复了由 配置重构。 -
#7758 从 FFI 示例中删除
-lstdcpp额外链接参数。 实际上没有必要。 -
#7763 更正构建密钥获取以生成具有正确数据的作业 类型并修复从关键文字到目标的失败强制。