Lean 4.18.0 (2025-04-02)
For this release, 344 changes landed. In addition to the 166 feature additions and 38 fixes listed below there were 13 refactoring changes, 10 documentation improvements, 3 performance improvements, 4 improvements to the test suite and 109 other changes.
Highlights
Lean v4.18 release brings a number of exciting new features:
-
Inlay hints for auto implicits
The Language Server now uses inlay hints to show which variables are brought into scope implicitly, and where. The hint reveals its type upon hover, and double-clicking the hint will insert the variable binding explicitly.
See the description of #6768 for a screenshort.
Note that this feature is only visible when
set_option autoImplicit true, which is the default in plain Lean projects, but not in mathlib -
#6935 adds the tactic
expose_names. It creates a new goal whose local context has been "exposed" so that every local declaration has a clear, accessible name. If no local declarations require renaming, the original goal is returned unchanged./-- info: α : Sort u_1 a b : α h_1 : a = b h_2 : True h_3 : True ∨ False h : b = a ⊢ b = a -/ #guard_msgs (info) in example (a b : α) (h : a = b) (_ : True) (_ : True ∨ False) (h : b = a) : b = a := by expose_names trace_state rw [h]
This tactic intended for use in auto-generated tactic suggestions, and can also be useful during proof exploration. It is still best practice to name variables where they are brought into scope (
intro,caseetc.), and not useexpose_namesin a finished, polished proof. -
#7069 adds the
fun_inductionandfun_casestactics, which add convenience around using functional induction and functional cases principles.fun_induction foo x y z
elaborates
foo x y z, then looks upfoo.induct, and then essentially doesinduction z using foo.induct y
including and in particular figuring out which arguments are parameters, targets or dropped. This only works for non-mutual functions so far.
Likewise there is the
fun_casestactic usingfoo.fun_cases. -
#6744 extend the preprocessing of well-founded recursive definitions to bring assumptions like
h✝ : x ∈ xs, if a recursive call is in the argument of a higher-order function likeList.map, into scope automatically. In many cases this removes the need to use functions likeList.attach.This feature can be disabled with
set_option wf.preprocess false. -
#6634 adds support for changing the binder annotations of existing variables to and from strict-implicit and instance-implicit using the
variablecommand. -
#7100 modifies the
structuresyntax so that parents can be named, like instructure S extends toParent : P
Breaking change: The syntax is also modified so that the resultant type comes before the
extendsclause, for examplestructure S : Prop extends P. This is necessary to prevent a parsing ambiguity, but also this is the natural place for the resultant type. Implements RFC #7099. -
#7103 gives the
inductiontactic the ability to name hypotheses to use when generalizing targets, just like incases. For example,induction h : xs.lengthleads to goals with hypothesesh : xs.length = 0andh : xs.length = n + 1. Target handling is also slightly modified for multi-target induction principles: it used to be that if any target was not a free variable, all of the targets would be generalized (thus causing free variables to lose their connection to the local hypotheses they appear in); now only the non-free-variable targets are generalized. -
#6869 adds a
recommended_spellingcommand, which can be used for recording the recommended spelling of a notation (for example, that the recommended spelling of∧in identifiers isand). This information is then appended to the relevant docstrings for easy lookup. -
#6893 adds support for plugins to the frontend and server.
-
#7061 provides a basic API for a premise selection tool, which can be provided in downstream libraries. It does not implement premise selection itself!
And many more! Check out the Language section below.
Notably, a line of work has been carried out on the following (see the corresponding subsections in the Language section for the details):
-
the
try?tactic, which has been re-implemented usingevalAndSuggesttactic.try?now supports referencing inaccessible local names and can provide more complex suggestions, involvingexact?andfun_inductiontactics. New configuration options have been added:-only,+missing, andmax:=<num>, as well asmerge. -
bv_decidetactic. There are new features in preprocessing, added support for enum inductives,IntXandISize, and improved performance in LRAT trimming. -
normalization for linear integer arithmetic expressions has been implemented and connected to
simp +arith. #7043 deprecates the tacticssimp_arith,simp_arith!,simp_all_arithandsimp_all_arith!in favor ofsimp +arith.
Important Library updates include:
-
#6914 introduces ordered map data structures, namely
DTreeMap,TreeMap,TreeSetand their.Rawvariants, into the standard library. A collection of lemmas about the operations on these data structures has been added in the subsequent PRs. -
#7255 fixes the definition of
Min (Option α). This is a breaking change. This treatsnoneas the least element, somin none x = min x none = nonefor allx : Option α. Prior to nightly-2025-02-27, we instead hadmin none (some x) = min (some x) none = some x. Also adds basic lemmas relatingmin,max,≤and<onOption.
Significant development has been made in the verification APIs of BitVec
and fixed-width integer types (IntX), along with ongoing work to align
List/Array/Vector APIs. Several lemmas about Int.ediv/fdiv/tdiv have
been strengthened.
#6950 adds a style guide and a naming convention for the standard library.
This summary of highlights was contributed by Violetta Sim.
Language
-
#6634 adds support for changing the binder annotations of existing variables to and from strict-implicit and instance-implicit using the
variablecommand. -
#6744 extends the preprocessing of well-founded recursive definitions, see the highlights section for details.
-
#6823 adds a builtin tactic and a builtin attribute that are required for the tree map. The tactic,
as_aux_lemma, can generally be used to wrap the proof term generated by a tactic sequence into a separate auxiliary lemma in order to keep the proof term small. This can, in rare cases, be necessary if the proof term will appear multiple times in the encompassing term. The new attribute,Std.Internal.tree_tac, is internal and should not be used outside ofStd. -
#6853 adds support for anonymous equality proofs in
matchexpressions of the formmatch _ : e with .... -
#6869 adds a
recommended_spellingcommand; see the highlights section for details. -
#6891 modifies
rewrite/rwto abort rewriting if the elaborated lemma has any immediate elaboration errors (detected by presence of synthetic sorries). Rewriting still proceeds if there are elaboration issues arising from pending synthetic metavariables, like instance synthesis failures. The purpose of the change is to avoid obscure "tactic 'rewrite' failed, equality or iff proof expected ?m.5" errors when for example a lemma does not exist. -
#6893 adds support for plugins to the frontend and server.
-
#6935 adds the tactic
expose_names; see the highlights section for details. -
#6936 fixes the
#discr_tree_simp_keycommand, because it displays the keys for justlhsinlhs ≠ rhs, but it should belhs = rhs, since that is what simp indexes. -
#6939 adds error messages for
inductivedeclarations with conflicting constructor names andmutualdeclarations with conflicting names. -
#6947 adds the
binderNameHintgadget. It can be used in rewrite and simp rules to preserve a user-provided name where possible.The expression
binderNameHint v binder edefined to bee.If it is used on the right-hand side of an equation that is applied by a tactic like
rworsimp, andvis a local variable, andbinderis an expression that (after beta-reduction) is a binder (sofun w => …or∀ w, …), then it will renamevto the name used in the binder, and remove thebinderNameHint.A typical use of this gadget would be as follows; the gadget ensures that after rewriting, the local variable is still
name, and notx:theorem all_eq_not_any_not (l : List α) (p : α → Bool) : l.all p = !l.any fun x => binderNameHint x p (!p x) := sorry example (names : List String) : names.all (fun name => "Waldo".isPrefixOf name) = true := by rw [all_eq_not_any_not] -- ⊢ (!names.any fun name => !"Waldo".isPrefixOf name) = trueThis gadget is supported by
simp,dsimpandrwin the right-hand-side of an equation, but not in hypotheses or by other tactics. -
#6951 adds line breaks and indentations to simp's trace messages to make them easier to read (IMHO).
-
#6964 adds a convenience command
#info_trees in, which prints the info trees generated by the following command. It is useful for debugging or learning aboutInfoTree. -
#7039 improves the well-founded definition preprocessing to propagate
wfParamthrough let expressions. -
#7053 makes
simpheed thebinderNameHintalso in the assumptions of congruence rules. Fixes #7052. -
#7055 improves array and vector literal syntax by allowing trailing commas. For example,
#[1, 2, 3,]. -
#7061 provides a basic API for a premise selection tool; see the highlights section for details.
-
#7078 implements simprocs for
IntandNatdivides predicates. -
#7088 fixes the behavior of the indexed-access notation
xs[i]in cases where the proof ofi's validity is filled in during unification. -
#7090 strips
libprefixes and_sharedsuffixes from plugin names. It also moves most of the dynlib processing code to Lean to make such preprocessing more standard. -
#7100 modifies the
structuresyntax; see the highlights section for details. -
#7103 gives the
inductiontactic the ability to name hypotheses; see the highlights section for details. -
#7119 makes linter names clickable in the
trace.profileroutput. -
#7191 fixes the indentation of "Try this" suggestions in widget-less multiline messages, as they appear in
#guard_msgsoutputs. -
#7192 prevents
exact?andapply?from suggesting tactics that correspond to correct proofs but do not elaborate, and it allows these tactics to suggestexpose_nameswhen needed. -
#7200 allows the debug form of DiscrTree.Key to line-wrap.
-
#7213 adds
SetConsoleOutputCP(CP_UTF8)during runtime initialization to properly display Unicode on the Windows console. This effects both the Lean executable itself and user executables (including Lake). -
#7224 make
induction … usingandcases … usingcomplain if more targets were given than expected by that eliminator. -
#7294 fixes bugs in
Std.Internal.Rat.floorandStd.Internal.Rat.ceil.
Updates to the try? Tactic
-
#6961 adds the auxiliary tactic
evalAndSuggest. It will be used to refactortry?. -
#6965 re-implements the
try?tactic using the newevalAndSuggestinfrastructure. -
#6967 ensures
try?can suggest tactics that need to reference inaccessible local names. Example:/-- info: Try these: • · expose_names; induction as, bs_1 using app.induct <;> grind [= app] • · expose_names; induction as, bs_1 using app.induct <;> grind only [app] -/ #guard_msgs (info) in example : app (app as bs) cs = app as (app bs cs) := by have bs := 20 -- shadows `bs` in the target try?
-
#6979 adds support for more complex suggestions in
try?. Example:example (as : List α) (a : α) : concat as a = as ++ [a] := by try?
suggestion
Try this: · induction as, a using concat.induct · rfl · simp_all
-
#6980 improves the
try?tactic runtime validation and error messages. It also simplifies the implementation, and removes unnecessary code. -
#6981 adds new configuration options to
try?.-
try? -onlyomitssimp onlyandgrind onlysuggestions -
try? +missingenables partial solutions where some subgoals are "solved" usingsorry, and must be manually proved by the user. -
try? (max:=<num>)sets the maximum number of suggestions produced (default is 8).
-
-
#6991 improves how suggestions for the
<;>combinator are generated. -
#6994 adds the
Try.Config.mergeflag (trueby default) to thetry?tactic. When set totrue,try?compresses suggestions such as:· induction xs, ys using bla.induct · grind only [List.length_reverse] · grind only [bla]into:
induction xs, ys using bla.induct <;> grind only [List.length_reverse, bla]
-
#6995 implements support for
exact?in thetry?tactic. -
#7082 makes
try?usefun_inductioninstead ofinduction … using foo.induct. It uses the argument-free short-handfun_induction fooif that is unambiguous. Avoidsexpose_namesif not necessary by simply trying without first.
Functional Induction Tactic
-
#7069 adds the
fun_inductionandfun_casestactics, which add convenience around using functional induction and functional cases principles. -
#7101 implements
fun_induction foo, which is likefun_induction foo x y z, only that it picks the arguments to use from a unique suitable call tofooin the goal. -
#7127 follows up on #7103 which changes the generaliziation behavior of
induction, to keepfun_inductionin sync. Also fixes aSyntaxindexing off-by-one error.
bv_decide Tactic
-
#6741 implements two rules for bv_decide's preprocessor, lowering
|||to&&&in order to enable more term sharing + application of rules about&&&as well as rewrites of the form(a &&& b == -1#w) = (a == -1#w && b == -1#w)in order to preserve rewriting behavior that already existed before this lowering. -
#6924 adds the EQUAL_ITE rules from Bitwuzla to the preprocessor of bv_decide.
-
#6926 adds the BV_EQUAL_CONST_NOT rules from Bitwuzla to the preprocessor of bv_decide.
-
#6946 implements basic support for handling of enum inductives in
bv_decide. It now supports equality on enum inductive variables (or other uninterpreted atoms) and constants. -
#7009 ensures users get an error message saying which module to import when they try to use
bv_decide. -
#7019 properly spells out the trace nodes in bv_decide so they are visible with just
trace.Meta.Tactic.bvandtrace.Meta.Tactic.satinstead of always having to enable the profiler. -
#7021 adds theorems for interactions of extractLsb with
&&&,^^^,~~~andbifto bv_decide's preprocessor. -
#7029 adds simprocs to bv_decide's preprocessor that rewrite multiplication with powers of two to constant shifts.
-
#7033 improves presentation of counter examples for UIntX and enum inductives in bv_decide.
-
#7242 makes sure bv_decide can work with projections applied to
iteandcondin its structures pass. -
#7257 improves performance of LRAT trimming in bv_decide.
-
#7269 implements support for
IntXandISizeinbv_decide. -
#7275 adds all level 1 rewrites from Bitwuzla to the preprocessor of bv_decide.
Parallelizing Elaboration
-
#6770 enables code generation to proceed in parallel to further elaboration.
-
#6988 ensures interrupting the kernel does not lead to wrong, sticky error messages in the editor
-
#7047 removes the
saveandcheckpointtactics that have been superseded by incremental elaboration -
#7076 introduces the central parallelism API for ensuring that helper declarations can be generated lazily without duplicating work or creating conflicts across threads.
Linear Integer Normalization in simp +arith
-
#7000 adds helper theorems for justifying the linear integer normalizer.
-
#7002 implements the normalizer for linear integer arithmetic expressions. It is not connect to
simp +arithyet because of some spurious[simp]attributes. -
#7011 adds
simp +arithfor integers. It uses the newgrindnormalizer for linear integer arithmetic. We still need to implement support for dividing the coefficients by their GCD. It also fixes several bugs in the normalizer. -
#7015 makes sure
simp +arithnormalizes coefficients in linear integer polynomials. There is still one todo: tightening the bound of inequalities. -
#7030 adds completes the linear integer inequality normalizer for
grind. The missing normalization step replaces a linear inequality of the forma_1*x_1 + ... + a_n*x_n + b <= 0witha_1/k * x_1 + ... + a_n/k * x_n + ceil(b/k) <= 0wherek = gcd(a_1, ..., a_n).ceil(b/k)is implemented using the helpercdiv b k. -
#7040 ensures that terms such as
f (2*x + y)andf (y + x + x)have the same normal form when usingsimp +arith -
#7043 deprecates the tactics
simp_arith,simp_arith!,simp_all_arithandsimp_all_arith!. Users can just use the+arithoption.
grind Tactic
The grind tactic is still is experimental and still under development. Avoid using it in production projects
-
#6902 ensures
simpdiagnostic information in included in thegrinddiagnostic message. -
#6937 improves
grinderror and trace messages by cleaning up local declaration names. -
#6940 improves how the
grindtactic performs case splits onp <-> q. -
#7102 modifies
grindto run with thereducibletransparency setting. We do not wantgrindto unfold arbitrary terms during definitional equality tests. also fixes several issues introduced by this change. The most common problem was the lack of a hint in proofs, particularly in those constructed using proof by reflection. also introduces new sanity checks whenset_option grind.debug trueis used. -
#7231 implements functions for constructing disequality proofs in
grind.
Cutsat Procedure (Solver for Linear Integer Arithmetic Problems)
-
#7077 proves the helper theorems for justifying the "Div-Solve" rule in the cutsat procedure.
-
#7091 adds helper theorems for normalizing divisibility constraints. They are going to be used to implement the cutsat procedure in the
grindtactic. -
#7092 implements divisibility constraint normalization in
simp +arith. -
#7097 implements several modifications for the cutsat procedure in
grind.-
The maximal variable is now at the beginning of linear polynomials.
-
The old
LinearArith.Solverwas deleted, and the normalizer was moved toSimp. -
cutsat first files were created, and basic infrastructure for representing divisibility constraints was added.
-
-
#7122 implements the divisibility constraint solver for the cutsat procedure in the
grindtactic. -
#7124 adds the helper theorems for justifying the divisibility constraint solver in the cutsat procedure used by the
grindtactic. -
#7138 implements proof generation for the divisibility constraint solver in
grind. -
#7139 uses a
let-expression for storing the (shared) context in proofs produced by the cutsat procedure ingrind. -
#7152 implements the infrastructure for supporting integer inequality constraints in the cutsat procedure.
-
#7155 implements some infrastructure for the model search procedure in cutsat.
-
#7156 adds a helper theorem that will be used in divisibility constraint conflict resolution during model construction.
-
#7176 implements model construction for divisibility constraints in the cutsat procedure.
-
#7183 improves the cutsat model search procedure.
-
#7186 simplifies the proofs and data structures used by cutsat.
-
#7193 adds basic infrastructure for adding support for equalities in cutsat.
-
#7194 adds support theorems for solving equality in cutsat.
-
#7202 adds support for internalizing terms relevant to the cutsat module. This is required to implement equality propagation.
-
#7203 improves the support for equalities in cutsat. It also simplifies a few support theorems used to justify cutsat rules.
-
#7217 improves the support for equalities in cutsat.
-
#7220 implements the missing cases for equality propagation from the
grindcore to the cutsat module. -
#7234 implements dIsequality propagation from
grindcore module to cutsat. -
#7244 adds support for disequalities in the cutsat procedure used in
grind. -
#7248 implements simple equality propagation in cutsat
p <= 0 -> -p <= 0 -> p = 0 -
#7252 implements inequality refinement using disequalities. It minimizes the number of case splits cutsat will have to perform.
-
#7267 improves the cutsat search procedure. It adds support for find an approximate rational solution, checks disequalities, and adds stubs for all missing cases.
-
#7278 adds counterexamples for linear integer constraints in the
grindtactic. This feature is implemented in the cutsat procedure. -
#7279 adds support theorems for the Cooper-Dvd-Left conflict resolution rule used in the cutsat procedure. During model construction, when attempting to extend the model to a variable
x, cutsat may find a conflict that involves two inequalities (the lower and upper bounds forx) and a divisibility constraint:a * x + p ≤ 0 b * x + q ≤ 0 d ∣ c * x + s
-
#7284 implements non-choronological backtracking for the cutsat procedure. The procedure has two main kinds of case-splits: disequalities and Cooper resolvents. focus on the first kind.
-
#7290 adds support theorems for the Cooper-Left conflict resolution rule used in the cutsat procedure. During model construction,when attempting to extend the model to a variable
x, cutsat may find a conflict that involves two inequalities (the lower and upper bounds forx). This is a special case of Cooper-Dvd-Left when there is no divisibility constraint. -
#7292 adds support theorems for the Cooper-Dvd-Right conflict resolution rule used in the cutsat procedure. During model construction, when attempting to extend the model to a variable
x, cutsat may find a conflict that involves two inequalities (the lower and upper bounds forx) and a divisibility constraint. -
#7293 adds support theorems for the Cooper-Right conflict resolution rule used in the cutsat procedure. During model construction, when attempting to extend the model to a variable x, cutsat may find a conflict that involves two inequalities (the lower and upper bounds for x). This is a special case of Cooper-Dvd-Right when there is no divisibility constraint.
-
#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)
Library
-
#5498 makes
BitVec.getElemthe simp normal form in case a proof is available and changesextto returnx[i]+ a hypothesis that proves that we are in-bounds. This alignsBitVecfurther with the API conventions of the Lean standard datatypes. -
#6326 adds
BitVec.(getMsbD, msb)_replicate, replicate_onetheorems, corrects a non-terminalsimpinBitVec.getLsbD_replicateand simplifies the proof ofBitVec.getElem_replicateusing thecasestactic. -
#6628 adds SMT-LIB operators to detect overflow
BitVec.(uadd_overflow, sadd_overflow), according to the definitions here, and the theorems proving equivalence of such definitions with theBitVeclibrary functions (uaddOverflow_eq,saddOverflow_eq). Support theorems for these proofs areBitVec.toNat_mod_cancel_of_lt, BitVec.toInt_lt, BitVec.le_toInt, Int.bmod_neg_iff. The PR also includes a set of tests. -
#6792 adds theorems
BitVec.(getMsbD, msb)_(extractLsb', extractLsb), getMsbD_extractLsb'_eq_getLsbD. -
#6795 adds theorems
BitVec.(getElem_umod_of_lt, getElem_umod, getLsbD_umod, getMsbD_umod). For the defiition of these theorems we rely ondivRec, excluding the case whered=0#w, which is treated separately because there is no infrastructure to reason about this case withindivRec. In particular, our implementation follows the mathlib standard where division by 0 yields 0, while in SMTLIB this yieldsallOnes. -
#6830 improves some files separation and standardize error messages in UV modules
-
#6850 adds some lemmas about the new tree map. These lemmas are about the interactions of
empty,isEmpty,insert,contains. Some lemmas about the interaction ofcontainswith the others will follow in a later PR. -
#6866 adds missing
Hashableinstances forPUnitandPEmpty. -
#6914 introduces ordered map data structures, namely
DTreeMap,TreeMap,TreeSetand their.Rawvariants, into the standard library. There are still some operations missing that the hash map has. As of now, the operations are unverified, but the corresponding lemmas will follow in subsequent PRs. While the tree map has already been optimized, more micro-optimization will follow as soon as the new code generator is ready. -
#6922 adds
LawfulBEqinstances forArrayandVector. -
#6948 completes the alignment of
List/Array/Vectorslemmas forinsertIdx. -
#6954 verifies the
toListfunction for hash maps and dependent hash maps. -
#6958 improves the
PromiseAPI by considering how dropped promises can lead to never-finished tasks. -
#6966 adds an internal-use-only strict linter for the variable names of
List/Array/Vectorvariables, and begins cleaning up. -
#6982 improves some lemmas about monads and monadic operations on Array/Vector, using @Rob23oa's work in https://github.com/leanprover-community/batteries/pull/1109, and adding/generalizing some additional lemmas.
-
#7013 makes improvements to the simp set for List/Array/Vector/Option to improve confluence, in preparation for
simp_lc. -
#7017 renames the simp set
boolToPropSimpstobool_to_propandbv_toNattobitvec_to_nat. I'll be adding more similarly named simp sets. -
#7034 adds
wf_preprocesstheorems for{List,Array}.{foldlM,foldrM,mapM,filterMapM,flatMapM} -
#7036 adds some deprecated function aliases to the tree map in order to ease the transition from the
RBMapto the tree map. -
#7046 renames
UIntX.mktoUIntX.ofBitVecand adds deprecations. -
#7048 adds the functions
IntX.ofBitVec. -
#7050 renames the functions
UIntX.valtoUIntX.toFin. -
#7051 implements the methods
insertMany,ofList,ofArray,foldrandfoldrMon the tree map. -
#7056 adds the
UIntX.ofFinconversion functions. -
#7057 adds the function
UIntX.ofNatLT. This is supposed to be a replacement forUIntX.ofNatCoreandUIntX.ofNat', but for bootstrapping reasons we need this function to exist in stage0 before we can proceed with the renaming and deprecations, so this PR just adds the function. -
#7059 moves away from using
List.get/List.get?/List.get!andArray.get!, in favour of using theGetElemmediated getters. In particular it deprecatesList.get?,List.get!andArray.get?. Also addsArray.back, taking a proof, matchingList.getLast. -
#7062 introduces the functions
UIntX.toIntXas the public API to obtain theIntXthat is 2's complement equivalent to a givenUIntX. -
#7063 adds
ISize.toInt8,ISize.toInt16,Int8.toISize,Int16.toISize. -
#7064 renames
BitVec.ofNatLttoBitVec.ofNatLTand sets up deprecations for the old name. -
#7066 renames
IntX.toNattoIntX.toNatClampNeg(to reduce surprises) and sets up a deprecation. -
#7068 is a follow-up to #7057 and adds a builtin dsimproc for
UIntX.ofNatLTwhich it turns out we need in stage0 before we can get the deprecation ofUIntX.ofNatCorein favor ofUIntX.ofNatLToff the ground. -
#7070 implements the methods
min,max,minKey,maxKey,atIndex,getEntryLE,getKeyLEand consorts on the tree map. -
#7071 unifies the existing functions
UIntX.ofNatCoreandUIntX.ofNat'under a new name,UIntX.ofNatLT. -
#7079 introduces
Fin.toNatas an alias forFin.val. We add this function for discoverability and consistency reasons. The normal form for proofs remainsFin.val, and there is asimplemma rewritingFin.toNattoFin.val. -
#7080 adds the functions
UIntX.ofNatTruncate(the version forUInt32already exists). -
#7081 adds functions
IntX.ofIntLE,IntX.ofIntTruncate, which are analogous to the unsigned counterpartsUIntX.ofNatLTandUInt.ofNatTruncate. -
#7083 adds (value-based, not bitfield-based) conversion functions between
Float/Float32andIntX/UIntX. -
#7105 completes aligning
Array/Vector.extractlemmas with the lemmas forList.takeandList.drop. -
#7106 completes the alignment of
List/Array/Vector.finRangelemmas. -
#7109 implements the
getThenInsertIfNew?andpartitionfunctions on the tree map. -
#7114 implements the methods
valuesandvaluesArrayon the tree map. -
#7116 implements the
getKeyfunctions on the tree map. It also fixes the naming of theentryAtIdxfunction on the tree set, which should have been calledatIdx. -
#7118 implements the functions
modifyandalteron the tree map. -
#7128 adds
ReprandHashableinstances forIntX. -
#7131 adds
IntX.absfunctions. These are specified byBitVec.abs, so they mapIntX.minValuetoIntX.minValue, similar to Rust'si8::abs. In the future we might also have versions which take values inUIntXand/orNat. -
#7137 verifies the various fold and for variants for hashmaps.
-
#7151 fixes a memory leak in
IO.FS.createTempFile -
#7158 strengthens
Int.tdiv_eq_ediv, by dropping an unnecessary hypothesis, in preparation for further work onediv/tdiv/fdivlemmas. -
#7161 adds all missing tree map lemmas about the interactions of the functions
empty,isEmpty,contains,size,insert(IfNew)anderase. -
#7162 splits
Int.DivModLemmasinto aBootstrapandLemmasfile, where it is possible to useomegainLemmas. -
#7163 gives an unconditional theorem expressing
Int.tdivin terms ofInt.ediv, not just for non-negative arguments. -
#7165 provides tree map lemmas about the interaction of
containsThenInsert(IfNew)withcontainsandinsert(IfNew). -
#7167 provides tree map lemmas for the interaction of
get?with the other operations for which lemmas already exist. -
#7174 adds the first batch of lemmas about iterated conversions between finite types starting with something of type
UIntX. -
#7199 adds theorems comparing
Int.edivwithtdivandfdiv, for all signs of arguments. (Previously we just had the statements about the cases in which they agree.) -
#7201 adds
Array/Vector.left/rightpad. These will not receive any verification theorems; simp just unfolds them to an++operation. -
#7205 completes alignment of
List.getLast/List.getLast!/List.getLast?lemmas with the corresponding lemmas for Array and Vector. -
#7206 adds theorem
BitVec.toFin_abs, completing the API forBitVec.*_abs. -
#7207 provides lemmas for the tree map functions
get,get!andgetDin relation to the other operations for which lemmas already exist. -
#7208 aligns lemmas for
List.dropLast/Array.pop/Vector.pop. -
#7210 adds the remaining lemmas about iterated conversions between finite types starting with something of type
UIntX. -
#7214 adds a
ForIninstance for thePersistentHashSettype. -
#7221 provides lemmas about the tree map functions
getKey?,getKey,getKey!,getKeyDandinsertIfNewand their interaction with other functions for which lemmas already exist. -
#7222 removes the
simpattribute fromReflCmp.compare_selfbecause it matches arbitrary function applications. Instead, a newsimplemmaReflOrd.compare_selfis introduced, which only matches applications ofcompare. -
#7229 provides lemmas for the tree map function
getThenInsertIfNew?. -
#7235 adds
Array.replaceandVector.replace, proves the correspondences withList.replace, and reproduces the basic API. In order to do so, it fills in some gaps in theList.findXAPIs. -
#7237 provides proofs that the raw tree map operations are well-formed and refactors the file structure of the tree map, introducing new modules
Std.{DTreeMap,TreeMap,TreeSet}.Rawand splitttingAdditionalOperationsinto separate files for bundled and raw types. -
#7245 adds missing
@[specialize]annotations to thealterandmodifyfunctions inStd.Data.DHashMap.Internal.AssocList, which are used by the corresponding hash map functions. -
#7249 completes alignment of theorems about
List/Array/Vector.any/all. -
#7255 fixes the definition of
Min (Option α). This is a breaking change. This treatsnoneas the least element, somin none x = min x none = nonefor allx : Option α. Prior to nightly-2025-02-27, we instead hadmin none (some x) = min (some x) none = some x. Also adds basic lemmas relatingmin,max,≤and<onOption. -
#7259 contains theorems about
IntXthat are required forbv_decideand theIntXsimprocs. -
#7260 provides lemmas about the tree map functions
keysandtoListand their interactions with other functions for which lemmas already exist. Moreover, a bug infoldr(callingfoldlMinstead offoldrM) is fixed. -
#7266 begins the alignment of
Int.ediv/fdiv/tdivtheorems. -
#7268 implements
Lean.ToExprfor finite signed integers. -
#7271 changes the order of arguments of the folding function expected by the tree map's
foldrandfoldrMfunctions so that they are consistent with the API ofList. -
#7273 fixes the statement of a
UIntXconversion lemma. -
#7277 fixes a bug in Float32.ofInt, which previously returned a Float(64).
Compiler
-
#6928 makes extern decls evaluate as ⊤ rather than the default value of ⊥ in the LCNF elimDeadBranches analysis.
-
#6930 changes the name generation of specialized LCNF decls so they don't strip macro scopes. This avoids name collisions for specializations created in distinct macro scopes. Since the normal Name.append function checks for the presence of macro scopes, we need to use appendCore.
-
#6976 extends the behavior of the
syncflag forTask.map/bindetc. to encompass synchronous execution even when they first have to wait on completion of the first task, drastically lowering the overhead of such tasks. Thus the flag is now equivalent to e.g. .NET'sTaskContinuationOptions.ExecuteSynchronously. -
#7037 relaxes the minimum required glibc version for Lean and Lean executables to 2.26 on x86-64 Linux
-
#7041 marks several LCNF-specific environment extensions as having an asyncMode of .sync rather than the default of .mainOnly, so they work correctly even in async contexts.
-
#7086 makes the arity reduction pass in the new code generator match the old one when it comes to the behavior of decls with no used parameters. This is important, because otherwise we might create a top-level decl with no params that contains unreachable code, which would get evaluated unconditionally during initialization. This actually happens when initializing Init.Core built with the new code generator.
Pretty Printing
-
#7074 modifies the signature pretty printer to add hover information for parameters in binders. This makes the binders be consistent with the hovers in pi types.
Documentation
-
#6886 adds recommended spellings for many notations defined in Lean core, using the
recommended_spellingcommand from #6869. -
#6950 adds a style guide and a naming convention for the standard library.
-
#6962 improves the doc-string for
List.toArray. -
#6998 modifies the
Propdocstring to point out that every proposition is propositionally equal to eitherTrueorFalse. This will help point users toward seeing thatPropis likeBool. -
#7026 clarifies the styling of
doblocks, and enhanes the naming conventions with information about theextandmononame components as well as advice about primed names and naming of simp sets. -
#7111 extends the standard library style guide with guidance on universe variables, notations and Unicode usage, and structure definitions.
Server
-
#6329 enables the language server to present multiple disjoint line ranges as being worked on. Even before parallelism lands, we make use of this feature to show post-elaboration tasks such as kernel checking on the first line of a declaration to distinguish them from the final tactic step.
-
#6768 adds preliminary support for inlay hints, as well as support for inlay hints that denote the auto-implicits of a function. Hovering over an auto-implicit displays its type and double-clicking the auto-implicit inserts it into the text document.
Breaking Change: The semantic highlighting request handler is not a pure request handler anymore, but a stateful one. Notably, this means that clients that extend the semantic highlighting of the Lean language server with the
chainLspRequestHandlerfunction must now use thechainStatefulLspRequestHandlerfunction instead. -
#6887 fixes a bug where the goal state selection would sometimes select incomplete incremental snapshots on whitespace, leading to an incorrect "no goals" response. Fixes #6594, a regression that was originally introduced in 4.11.0 by #4727.
-
#6959 implements a number of refinements for the auto-implicit inlay hints implemented in #6768. Specifically:
-
In #6768, there was a bug where the inlay hint edit delay could accumulate on successive edits, which meant that it could sometimes take much longer for inlay hints to show up. implements the basic infrastructure for request cancellation and implements request cancellation for semantic tokens and inlay hints to resolve the issue. With this edit delay bug fixed, it made more sense to increase the edit delay slightly from 2000ms to 3000ms.
-
In #6768, we applied the edit delay to every single inlay hint request in order to reduce the amount of inlay hint flickering. This meant that the edit delay also had a significant effect on how far inlay hints would lag behind the file progress bar. adjusts the edit delay logic so that it only affects requests sent directly after a corresponding
didChangenotification. Once the edit delay is used up, all further semantic token requests are responded to without delay, so that the only latency that affects how far the inlay hints lag behind the progress bar is how often we emit refresh requests and how long VS Code takes to respond to them. -
For inlay hints, refresh requests are now emitted 500ms after a response to an inlay hint request, not 2000ms, which means that after the edit delay, inlay hints should only lag behind the progress bar by about up to 500ms. This is justifiable for inlay hints because the response should be much smaller than e.g. is the case for semantic tokens.
-
In #6768, 'Restart File' did not prompt a refresh, but it does now.
-
VS Code does not immediately remove old inlay hints from the document when they are applied. In #6768, this meant that inlay hints would linger around for a bit once applied. To mitigate this issue, this PR adjusts the inlay hint edit delay logic to identify edits sent from the client as being inlay hint applications, and sets the edit delay to 0ms for the inlay hint requests following it. This means that inlay hints are now applied immediately.
-
In #6768, hovering over single-letter auto-implicit inlay hints was a bit finicky because VS Code uses the regular cursor icon on inlay hints, not the thin text cursor icon, which means that it is easy to put the cursor in the wrong spot. We now add the separation character (
or{) preceding an auto-implicit to the hover range as well, which makes hovering over inlay hints much smoother.
-
-
#6978 fixes a bug where both the inlay hint change invalidation logic and the inlay hint edit delay logic were broken in untitled files. Thanks to @Julian for spotting this!
-
#7054 adds language server support for request cancellation to the following expensive requests: Code actions, auto-completion, document symbols, folding ranges and semantic highlighting. This means that when the client informs the language server that a request is stale (e.g. because it belongs to a previous state of the document), the language server will now prematurely cancel the computation of the response in order to reduce the CPU load for requests that will be discarded by the client anyways.
-
#7087 ensures that all tasks in the language server either use dedicated tasks or reuse an existing thread from the thread pool. This ensures that elaboration tasks cannot prevent language server tasks from being scheduled. This is especially important with parallelism right around the corner and elaboration becoming more likely to starve the language server of computation, which could drive up language server latencies significantly on machines with few cores.
-
#7112 adds a tooltip describing what the auto-implicit inlay hints denote, as well as auto-implicit inlay hints for instances.
-
#7134 significantly improves the performance of auto-completion by optimizing individual requests by a factor of ~2 and by giving language clients like VS Code the opportunity to reuse the state of previous completion requests, thus greatly reducing the latency for the auto-completion list to update when adding more characters to an identifier.
-
#7143 makes the server consistently not report newlines between trace nodes to the info view, enabling it to render them on dedicates lines without extraneous spacing between them in all circumstances.
-
#7149 adds a fast path to the inlay hint request that makes it re-use already computed inlay hints from previous requests instead of re-computing them. This is necessary because for some reason VS Code emits an inlay hint request for every line you scroll, so we need to be able to respond to these requests against the same document state quickly. Otherwise, every single scrolled line would result in a request that can take a few dozen ms to be responded to in long files, putting unnecessary pressure on the CPU. It also filters the result set by the inlay hints that have been requested.
-
#7153 changes the server to run
lake setup-fileon Lake configuration files (e.g.,lakefile.lean). -
#7175 fixes an
Elab.asyncregression where elaboration tasks are cancelled on document edit even though their result may be reused in the new document version, reporting an incomplete result.
Lake
-
#6829 changes the error message for Lake configuration failure to reflect that issues do not always arise from an invalid lakefile, but sometimes arise from other issues like network errors. The new error message encompasses all of these possibilities.
-
#6929 passes the shared library of the previous stage's Lake as a plugin to the next stage's Lake in the CMake build. This enables Lake to use its own builtin elaborators / initializers at build time.
-
#7001 adds support for plugins to Lake. Precompiled modules are now loaded as plugins rather than via
--load-dynlib. -
#7024 documents how to use Elan's
+option withlake new|init. It also provides an more informative error message if a+option leaks into Lake (e.g., if a user provides the option to a Lake run without Elan). -
#7157 changes
lake setup-fileto now use Lake as a plugin for files which import Lake (or one of its submodules). Thus, the server will now load Lake as a plugin when editing a Lake configuration written in Lean. This further enables the use of builtin language extensions in Lake. -
#7171 changes the Lake DSL to use builtin elaborators, macros, and initializers.
-
#7182 makes
lake setup-filesucceed on an invalid Lean configuration file. -
#7209 fixes broken Lake tests on Windows' new MSYS2. As of MSYS2 0.0.20250221,
OSTYPEis now reported ascygwininstead ofmsys, which must be accounted for in a few Lake tests. -
#7211 changes the job monitor to perform run job computation itself as a separate job. Now progress will be reported eagerly, even before all outstanding jobs have been discovered. Thus, the total job number reported can now grow while jobs are still being computed (e.g., the
Yin[X/Y[may increase). -
#7233 uses the Lake plugin when Lake is built with Lake via
USE_LAKE. -
#7291 changes the Lake job monitor to display the last (i.e., newest) running/unfinished job rather than the first. This avoids the monitor focusing too long on any one job (e.g., "Running job computation").
-
#7399 reverts the new builtin initializers, elaborators, and macros in Lake back to non-builtin.
-
#7608 removes the use of the Lake plugin in the Lake build and in configuration files.
Other
-
#7129 optimizes the performance of the unused variables linter in the case of a definition with a huge
Exprrepresentation -
#7173 introduces a trace node for each deriving handlers invocation for the benefit of
trace.profiler -
#7184 adds support for LEAN_BACKTRACE on macOS. This previously only worked with glibc, but it can not be enabled for all Unix-like systems, since e.g. Musl does not support it.
-
#7190 makes the stage2 Leanc build use the stage2 oleans rather than stage1 oleans. This was happening because Leanc's own OLEAN_OUT is at the build root rather than the lib/lean subdirectory, so when the build added this OLEAN_OUT to LEAN_PATH no oleans were found there and the search fell back to the stage1 installation location.