Lean 4.24.0-rc1 (2025-09-15)
For this release, 377 changes landed. In addition to the 105 feature additions and 75 fixes listed below there were 25 refactoring changes, 9 documentation improvements, 21 performance improvements, 4 improvements to the test suite and 138 other changes.
Language
-
#8891 improves the error message produced when passing (automatically redundant) local hypotheses to
grind. -
#9651 modifies the generation of induction and partial correctness lemmas for
mutualblocks defined viapartial_fixpoint. Additionally, the generation of lattice-theoretic induction principles of functions viamutualblocks is modified for consistency withpartial_fixpoint. -
#9674 cleans up
optParam/autoParam/etc. annotations before elaborating definition bodies, theorem bodies,funbodies, andletfunction bodies. Bothvariables and binders in declaration headers are supported. -
#9918 prevents
rcasesandobtainfrom creating absurdly long case tag names when taking single constructor types (likeExists) apart. Fixes #6550 -
#9923 adds a guard for a delaborator that is causing panics in doc-gen4. This is a band-aid solution for now, and @sgraf812 will take a look when they're back from leave.
-
#9926 guards the
Std.Tactic.Do.MGoalEntailsdelaborator by a check ensuring that there are at least 3 arguments present, preventing potential panics. -
#9927 implements extended
induction-inspired syntax formvcgen, allowing optionalusing invariantsandwithsections. -
#9930 reverts the way
grind cutsatembedsNat.subintoInt. It fixes a regression reported by David Renshaw on Zulip. -
#9938 removes a duplicate
mpure_introtactic definition. -
#9939 expands
mvcgen using invariants | $n => $ttomvcgen; case inv<$n> => exact $tto avoid MVar instantiation mishaps observable in the test case for #9581. -
#9942 modifies
introto create tactic info localized to each hypothesis, making it possible to see howintroworks variable-by-variable. Additionally:-
The tactic supports
intro rflto introduce an equality and immediately substitute it, likerintro rfl(recall: therflpattern is like doingintro h; subst h). Therintrotactic can also now supportHEqinrflpatterns ifeq_of_heqapplies. -
In
intro (h : t), elaboration oftis interleaved with unification with the type ofh, which prevents default instances from causing unification to fail. -
Tactics that change types of hypotheses (including
intro (h : t),delta,dsimp) now update the local instance cache.
-
-
#9945 optimizes the proof terms produced by
grind cutsat. It removes unused entries from the context objects when generating the final proof, significantly reducing the amount of junk in the resulting terms. Example:/-- trace: [grind.debug.proof] fun h h_1 h_2 h_3 h_4 h_5 h_6 h_7 h_8 => let ctx := RArray.leaf (f 2); let p_1 := Poly.add 1 0 (Poly.num 0); let p_2 := Poly.add (-1) 0 (Poly.num 1); let p_3 := Poly.num 1; le_unsat ctx p_3 (eagerReduce (Eq.refl true)) (le_combine ctx p_2 p_1 p_3 (eagerReduce (Eq.refl true)) h_8 h_1) -/ #guard_msgs in -- Context should contain only `f 2` open Lean Int Linear in set_option trace.grind.debug.proof true in example (f : Nat → Int) : f 1 <= 0 → f 2 <= 0 → f 3 <= 0 → f 4 <= 0 → f 5 <= 0 → f 6 <= 0 → f 7 <= 0 → f 8 <= 0 → -1 * f 2 + 1 <= 0 → False := by grind -
#9946 optimizes the proof terms produced by
grind ring. It is similar to #9945, but for the ring module ingrind. It removes unused entries from the context objects when generating the final proof, significantly reducing the amount of junk in the resulting terms. Example:/-- trace: [grind.debug.proof] fun h h_1 h_2 h_3 => Classical.byContradiction fun h_4 => let ctx := RArray.branch 1 (RArray.leaf x) (RArray.leaf x⁻¹); let e_1 := (Expr.var 0).mul (Expr.var 1); let e_2 := Expr.num 0; let e_3 := Expr.num 1; let e_4 := (Expr.var 0).pow 2; let m_1 := Mon.mult (Power.mk 1 1) Mon.unit; let m_2 := Mon.mult (Power.mk 0 1) Mon.unit; let p_1 := Poly.num (-1); let p_2 := Poly.add (-1) (Mon.mult (Power.mk 0 1) Mon.unit) (Poly.num 0); let p_3 := Poly.add 1 (Mon.mult (Power.mk 0 2) Mon.unit) (Poly.num 0); let p_4 := Poly.add 1 (Mon.mult (Power.mk 0 1) (Mon.mult (Power.mk 1 1) Mon.unit)) (Poly.num (-1)); let p_5 := Poly.add 1 (Mon.mult (Power.mk 0 1) Mon.unit) (Poly.num 0); one_eq_zero_unsat ctx p_1 (eagerReduce (Eq.refl true)) (Stepwise.simp ctx 1 p_4 (-1) m_1 p_5 p_1 (eagerReduce (Eq.refl true)) (Stepwise.core ctx e_1 e_3 p_4 (eagerReduce (Eq.refl true)) (diseq0_to_eq x h_4)) (Stepwise.mul ctx p_2 (-1) p_5 (eagerReduce (Eq.refl true)) (Stepwise.superpose ctx 1 m_2 p_4 (-1) m_1 p_3 p_2 (eagerReduce (Eq.refl true)) (Stepwise.core ctx e_1 e_3 p_4 (eagerReduce (Eq.refl true)) (diseq0_to_eq x h_4)) (Stepwise.core ctx e_4 e_2 p_3 (eagerReduce (Eq.refl true)) h)))) -/ #guard_msgs in -- Context should contains only `x` and its inverse. set_option trace.grind.debug.proof true in set_option pp.structureInstances false in open Lean Grind CommRing in example [Field α] (x y z w : α) : x^2 = 0 → y^2 = 0 → z^3 = 0 → w^2 = 0 → x = 0 := by grind -
#9947 optimizes the proof terms produced by
grind linarith. It is similar to #9945, but for thelinarithmodule ingrind. It removes unused entries from the context objects when generating the final proof, significantly reducing the amount of junk in the resulting terms. -
#9951 generates
.ctorIdxfunctions for all inductive types, not just enumeration types. This can be a building block for other constructions (BEq,noConfusion) that are size-efficient even for large inductives. -
#9952 adds “non-branching case statements”: For each inductive constructor
T.conthis adds a functionT.con.withthat is similarT.casesOn, but has only one arm (the one forcon), and an additionalt.toCtorIdx = 12assumption. -
#9954 removes the option
grind +ringNull. It provided an alternative proof term construction for thegrind ringmodule, but it was less effective than the default proof construction mode and had effectively become dead code. also optimizes semiring normalization proof terms using the infrastructure added in #9946. Remark: After updating stage0, we can remove several background theorems from theInit/Grindfolder. -
#9958 ensures that equations in the
grind cutsatmodule are maintained in solved form. That is, given an equationa*x + p = 0used to eliminatex, the linear polynomialpmust not contain other eliminated variables. Before this PR, equations were maintained in triangular form. We are going to use the solved form to linearize nonlinear terms. -
#9968 modifies macros, which implement non-atomic definitions and
$cmd1 in $cmd2syntax. These macros involve implicit scopes, introduced throughsectionandnamespacecommands. Since sections or namespaces are designed to delimit local attributes, this has led to unintuitive behaviour when applying local attributes to definitions appearing in the above-mentioned contexts. This has been causing the following examples to fail:axiom A : Prop
-
#9974 registers a parser alias for
Lean.Parser.Command.visibility. This avoids having to importLean.Parser.Commandin simple command macros that use visibilities. -
#9980 fixes a bug in the dynamic variable reordering function used in
grind cutsat. -
#9989 changes the new extended syntax for
mvcgentomvcgen invariants ... with .... -
#9995 almost completely rewrites the inductive predicate recursion algorithm; in particular
IndPredBelowto function more consistently. Historically, thebrecOngeneration throughIndPredBelowhas been very error-prone -- this should be fixed now since the new algorithm is very direct and doesn't rely on tactics or meta-variables at all. Additionally, the new structural recursion procedure for inductive predicates shares more code with regular structural recursion and thus allows for mutual and nested recursion in the same way it was possible with regular structural recursion. For example, the following works now:mutual
-
#9996 improves support for nonlinear monomials in
grind cutsat. For example, given a monomiala * b, ifcutsatdiscovers thata = 2, it now propagates thata * b = 2 * b. Recall that nonlinear monomials likea * bare treated as variables incutsat, a procedure designed for linear integer arithmetic. -
#10007 lets #print print
privatebeforeprotected, matching the syntax. -
#10008 fixes a bug in
#evalwhere clicking on the evaluated expression could show errors in the Infoview. This was caused by#evalnot saving the temporary environment that is used when elaborating the expression. -
#10010 improves support for nonlinear
/and%ingrind cutsat. For example, givena / b, ifcutsatdiscovers thatb = 2, it now propagates thata / b = b / 2. is similar to #9996, but for/and%. Example:example (a b c d : Nat) : b > 1 → d = 1 → b ≤ d + 1 → a % b = 1 → a = 2 * c → False := by grind -
#10020 fixes a missing case for PR #10010.
-
#10021 make some minor changes to the grind annotation analysis script, including sorting results and handling errors. Still need to add an external UI.
-
#10022 improves support for
Fin ningrind cutsatwhennis not a numeral. For example, the following goals can now be solved automatically:example (p d : Nat) (n : Fin (p + 1)) : 2 ≤ p → p ≤ d + 1 → d = 1 → n = 0 ∨ n = 1 ∨ n = 2 := by grind -
#10034 changes the "declaration uses 'sorry'" error to pretty print an actual
sorryexpression in the message. The effect is that thesorryis hoverable and, if it's labeled, you can "go to definition" to see where it came from. -
#10038 ensures
grinderror messages use{.ofConstName declName}when referencing declaration names. -
#10060 allows for more fine-grained control over what derived instances have exposed definitions under the module system: handlers should not expose their implementation unless either the deriving item or a surrounding section is marked with
@[expose]. Built-in handlers to be updated after a stage 0 update. -
#10069 adds helper theorems to support
NatModuleingrind linarith. -
#10071 improves support for
a^ningrind cutsat. For example, ifcutsatdiscovers thataandbare equal to numerals, it now propagates the equality. is similar to #9996, buta^b. Example:example (n : Nat) : n = 2 → 2 ^ (n+1) = 8 := by grind
-
#10085 adds a parser alias for the
rawIdentparser, so that it can be used insyntaxdeclarations inInit. -
#10093 adds background theorems for a new solver to be implemented in
grindthat will support associative and commutative operators. -
#10095 modifies the
grindalgebra typeclasses to useSMul x yinstead ofHMul x y y. -
#10105 adds support for detecting associative operators in
grind. The new AC module also detects whether the operator is commutative, idempotent, and whether it has a neutral element. The information is cached. -
#10113 deprecates
.toCtorIdxfor the more naturally named.ctorIdx(and updates the standard library). -
#10120 fixes an issue where private definitions recursively invoked using generalized field notation (dot notation) would give an "invalid field" errors. It also fixes an issue where "invalid field notation" errors would pretty print the name of the declaration with a
_privateprefix. -
#10125 allows
#guard_msgsto report the relative positions of logged messages with the config option(positions := true). -
#10129 replaces the interim order typeclasses used by
Grindwith the new publicly available classes inStd. -
#10134 makes the generation of functional induction principles more robust when the user
let-binds a variable that is thenmatch'ed on. Fixes #10132. -
#10135 lets the
ctorIdxdefinition for single constructor inductives avoid the pointless.casesOn, and usesmacro_inlineto avoid compiling the function and wasting symbols. -
#10141 reverts the
macro_inlinepart of #10135. -
#10144 changes the construction of a
CompleteLatticeinstance on predicates (maps introProp) inside ofcoinductive_fixpoint/inductive_fixpointmachinery. -
#10146 implements the basic infrastructure for the new procedure handling AC operators in grind. It already supports normalizing disequalities. Future PRs will add support for simplification using equalities, and computing critical pairs. Examples:
example {α : Sort u} (op : α → α → α) [Std.Associative op] (a b c : α) : op a (op b c) = op (op a b) c := by grind only -
#10151 ensures
where finallytactics can access private data under the module system even when the corresponding holes are in the public scope as long as all of them are of proposition types. -
#10152 introduces an alternative construction for
DecidableEqinstances that avoids the quadratic overhead of the default construction. -
#10166 reviews the expected-to-fail-right-now tests for
grind, moving some (now passing) tests to the main test suite, updating some tests, and adding some tests about normalisation of exponents. -
#10177 fixes a bug in the
grindpreprocessor exposed by #10160. -
#10179 fixes
grindinstance normalization procedure. Some modules in grind use builtin instances defined directly in core (e.g.,cutsat), while others synthesize them usingsynthInstance(e.g.,ring). This inconsistency is problematic, as it may introduce mismatches and result in two different representations for the same term. fixes the issue. -
#10183 lets match equations be proved by
rflif possible, instead of explicitly unfolding the LHS first. May lead to smaller proofs. -
#10185 documents all
grindattribute modifiers (e.g.,=,usr,ext, etc). -
#10186 adds supports for simplifying disequalities in the
grind acmodule. -
#10189 implements the proof terms for the new
grind acmodule. Examples:example {α : Sort u} (op : α → α → α) [Std.Associative op] (a b c d : α) : op a (op b b) = op c d → op c (op d c) = op (op a b) (op b c) := by grind only -
#10205 adds superposition for associative and commutative operators in
grind ac. Examples:example (a b c d e f g h : Nat) : max a b = max c d → max b e = max d f → max b g = max d h → max (max f d) (max c g) = max (max e (max d (max b (max c e)))) h := by grind -cutsat only -
#10206 adds superposition for associative (but non-commutative) operators in
grind ac. Examples:example {α} (op : α → α → α) [Std.Associative op] (a b c d : α) : op a b = c → op b a = d → op (op c a) (op b c) = op (op a d) (op d b) := by grind -
#10208 adds the extra critical pairs to ensure the
grind acprocedure is complete when the operator is AC and idempotent. Example:example {α : Sort u} (op : α → α → α) [Std.Associative op] [Std.Commutative op] [Std.IdempotentOp op] (a b c d : α) : op a (op b b) = op d c → op (op b a) (op b c) = op c (op d c) := by grind only -
#10221 adds the extra critical pairs to ensure the
grind acprocedure is complete when the operator is associative and idempotent, but not commutative. Example:example {α : Sort u} (op : α → α → α) [Std.Associative op] [Std.IdempotentOp op] (a b c d e f x y w : α) : op d (op x c) = op a b → op e (op f (op y w)) = op a (op b c) → op d (op x c) = op e (op f (op y w)) := by grind only -
#10223 implements equality propagation from the new AC module into the
grindcore. Examples:example {α β : Sort u} (f : α → β) (op : α → α → α) [Std.Associative op] [Std.Commutative op] (a b c d : α) : op a (op b b) = op d c → f (op (op b a) (op b c)) = f (op c (op d c)) := by grind only -
#10230 adds
MonoBindfor more monad transformers. This allows usingpartial_fixpointfor more complicated monads based onOptionandEIO. Example:abbrev M := ReaderT String (StateT String.Pos Option)
-
#10237 fixes a missing case in the
grindcanonicalizer. Some types may include terms or propositions that are internalized later in thegrindstate. -
#10239 fixes the E-matching procedure for theorems that contain universe parameters not referenced by any regular parameter. This kind of theorem seldom happens in practice, but we do have instances in the standard library. Example:
@[simp, grind =] theorem Std.Do.SPred.down_pure {φ : Prop} : (⌜φ⌝ : SPred []).down = φ := rfl -
#10241 adds some test cases for
grindworking withFin. There are many still failing tests intests/lean/grind/grind_fin.leanwhich I'm intending to triage and work on. -
#10245 changes the implementation of a function
unfoldPredRelused in (co)inductive predicate machinery, that unfolds pointwise order on predicates to quantifications and implications. Previous implementation relied onwithDeclsDNDthat could not deal with types which depend on each other. This caused the following example to fail:inductive infSeq_functor1.{u} {α : Type u} (r : α → α → Prop) (call : {α : Type u} → (r : α → α → Prop) → α → Prop) : α → Prop where | step : r a b → infSeq_functor1 r call b → infSeq_functor1 r call a -
#10265 fixes a panic in
grind ringexposed by #10242.grind ringshould not assume that all normalizations have been applied, because some subterms cannot be rewritten bysimpdue to typing constraints. Moreover,grindusespreprocessLightin a few places, and it skips the simplifier/normalizer. -
#10267 implements the infrastructure for supporting
NatModuleingrind linarithand uses it to handle disequalities. Another PR will add support for equalities and inequalities. Example:open Lean Grind variable (M : Type) [NatModule M] [AddRightCancel M]
-
#10269 changes the string interpolation procedure to omit redundant empty parts. For example
s!"{1}{2}"previously elaborated totoString "" ++ toString 1 ++ toString "" ++ toString 2 ++ toString ""and now elaborates totoString 1 ++ toString 2. -
#10271 changes the naming of the internal functions in deriving instances like BEq to use accessible names. This is necessary to reasonably easily prove things about these functions. For example after
deriving BEqfor a typeT, the implementation ofinstBEqTis ininstBEqT.beq. -
#10273 tries to do the right thing about the visibility of the same-ctor-match-construct.
-
#10274 changes the implementation of the linear
DecidableEqimplementation to usematch decEqrather thanif h :to compare the constructor tags. Otherwise, the “smart unfolding” machinery will not letrfldecide that different constructors are different. -
#10277 adds the missing instances
IsPartialOrder,IsLinearPreorderandIsLinearOrderforOfNatModule.Q α. -
#10278 adds support for
NatModuleequalities and inequalities ingrind linarith. Examples:open Lean Grind Std
-
#10280 adds the auxiliary theorem
Lean.Grind.Linarith.eq_normNfor normalizingNatModuleequations when the instanceAddRightCancelis not available. -
#10281 implements
NatModulenormalization when theAddRightCancelinstance is not available. Note that in this case, the embedding intoIntModuleis not injective. Therefore, we use a custom normalizer, similar to theCommSemiringnormalizer used in thegrind ringmodule. Example:open Lean Grind example [NatModule α] (a b c : α) : 2•a + 2•(b + 2•c) + 3•a = 4•a + c + 2•b + 3•c + a := by grind -
#10282 improves the counterexamples produced by
grind linarithforNatModules.grindnow hides occurrences of the auxiliary functionGrind.IntModule.OfNatModule.toQ. -
#10283 implements diagnostic information for the
grind acmodule. It now displays the basis, normalized disequalities, and additional properties detected for each associative operator. -
#10290 adds infrastructure for registering new
grindsolvers.grindalready includes many solvers, and this PR is the first step toward modularizing the design and supporting user-defined solvers. -
#10294 completes the
grindsolver extension design and ports thegrind acsolver to the new framework. Future PRs will document the API and port the remaining solvers. An additional benefit of the new design is faster build times. -
#10296 fixes a bug in an auxiliary function used to construct proof terms in
grind cutsat. -
#10300 offers an alternative
noConfusionconstruction for the off-diagonal use (i.e. for different constructors), based on comparing the.ctorIdx. This should lead to faster type checking, as the kernel only has to reduce.ctorIdxtwice, instead of the complicatenoConfusionTypeconstruction. -
#10301 exposes ctorIdx and per-constructor eliminators. Fixes #10299.
-
#10306 fixes a few bugs in the
rwtactic: it could "steal" goals because they appear in the type of the rewrite, it did not do an occurs check, and new proof goals would not be synthetic opaque. also lets therfltactic assign synthetic opaque metavariables so that it is equivalent toexact rfl. -
#10307 upstreams the Verso parser and adds preliminary support for Verso in docstrings. This will allow the compiler to check examples and cross-references in documentation.
-
#10309 modifies the
simpatactic so that insimpa ... using ethere is tactic info on the rangesimpa ... usingthat shows the simplified goal. -
#10313 adds missing
grindnormalization rules fornatCastandintCastExamples:open Lean.Grind variable (R : Type) (a b : R)
-
#10314 skips model based theory combination on instances.
-
#10315 adds
T.ctor.noConfusiondeclarations, which are specializations ofT.noConfusionto equalities betweenT.ctor. The point is to avoid reducing theT.noConfusionTypeconstruction every time we useinjectionor a similar tactic. -
#10316 shares common functionality relate to equalities between same constructors, and when these are type-correct. In particular it uses the more complete logic from
mkInjectivityThmalso in other places, such asCasesOnSameCtorand the deriving code forBEq,DecidableEq,Ord, for more consistency and better error messages. -
#10321 ensures that the auxiliary temporary metavariable IDs created by the E-matching module used in
grindare not affected by what has been executed before invokinggrind. The goal is to increasegrind’s robustness. -
#10322 introduces limited functionality frontends
cutsatandgrobnerforgrind. We disable theorem instantiation (and case splitting forgrobner), and turn off all other solvers. Both still allowgrindconfiguration options, so for example one can usecutsat +ring(orgrobner +cutsat) to solve problems that require both. -
#10323 fixes the
grindcanonicalizer forOfNat.ofNatapplications. Example:example {C : Type} (h : Fin 2 → C) : -- `0` in the first `OfNat.ofNat` is not a raw literal h (@OfNat.ofNat (Fin (1 + 1)) 0 Fin.instOfNat) = h 0 := by grind -
#10324 disables an unused instance that causes expensive typeclass searches.
-
#10325 implements model-based theory combination for types
Awhich implement theToIntinterface. Examples:example {C : Type} (h : Fin 4 → C) (x : Fin 4) : 3 ≤ x → x ≤ 3 → h x = h (-1) := by grind -
#10326 fixes a performance issue in
grind linarith. It was creating unnecessaryNatModule/IntModulestructures for commutative rings without an order. This kind of type should be handled bygrind ringonly. -
#10331 implements
mkNoConfusionImpin Lean rather than in C. This reduces our reliance on C, and may bring performance benefits from not reducingnoConfusionTypeduring elaboration time (it still gets reduced by the kernel when type-checking). -
#10332 ensures that the infotree recognizes
Classical.propDecidableas an instance, when below aclassicaltactic. -
#10335 fixes the nested proof term detection in
grind. It must check whether the gadgetGrind.nestedProofis over-applied. -
#10342 implements a new E-matching pattern inference procedure that is faithful to the behavior documented in the reference manual regarding minimal indexable subexpressions. The old inference procedure was failing to enforce this condition. For example, the manual documents
[grind ->]as follows -
#10373 adds a
pp.unicodeoption and aunicode("→", "->")syntax description alias for the lower-levelunicodeSymbol "→" "->"parser. The syntax is added to thenotationcommand as well. Whenpp.unicodeis true (the default) then the first form is used when pretty printing, and otherwise the second ASCII form is used. A variant,unicode("→", "->", preserveForPP)causes the->form to be preferred; delaborators can insert→directly into the syntax, which will be pretty printed as-is; this allows notations likefunto use custom options such aspp.unicode.funto opt into the unicode form when pretty printing.
Library
-
#7858 implements the fast circuit for overflow detection in unsigned multiplication used by Bitwuzla and proposed in: https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=987767
-
#9127 makes
saveModuleDatathrow an IO.Error instead of panicking, if given something that cannot be serialized. This doesn't really matter for saving modules, but is handy when writing tools to save auxiliary date in olean files via Batteries'pickle. -
#9560 fixes the
forInfunction, that previously caused the resulting Promise to be dropped without a value when an exception was thrown inside of it. It also corrects the parameter order of thebackgroundfunction. -
#9599 adds the type
Std.Internal.Parsec.Error, which contains the constructors.eof(useful for checking if parsing failed due to not having enough input and then retrying when more input arrives that is useful in the HTTP server) and.other, which describes other errors. It also adds documentation to many functions, along with some new functions to theByteArrayParsec, such aspeekWhen?,octDigit,takeWhile,takeUntil,skipWhile, andskipUntil. -
#9632 adds lemmas for the
TreeMapoperationsfilter,mapandfilterMap. These lemmas existed already for hash maps and are simply ported over from there. -
#9685 verifies
toArrayand related functions for hashmaps. -
#9797 provides the means to quickly provide all the order instances associated with some high-level order structure (preorder, partial order, linear preorder, linear order). This can be done via the factory functions
PreorderPackage.ofLE,PartialOrderPackage.ofLE,LinearPreorderPackage.ofLEandLinearOrderPackage.ofLE. -
#9908 makes
IsPreorder,IsPartialOrder,IsLinearPreorderandIsLinearOrderextendBEqandOrdas appropriate, adds theLawfulOrderBEqandLawfulOrderOrdtypeclasses relatingBEqandOrdtoLE, and adds many lemmas and instances. -
#9916 provides factories that derive order typeclasses in bulk, given an
Ordinstance. If present, existing instances are preferred over those derived fromOrd. It is possible to specify any instance manually if desired. -
#9924 fixes examples in the documentation for
PostCond. -
#9931 implements
Std.Do.Triple.mp, enabling users to compose two specifications for the same program. -
#9949 allows most of the
List.lookuplemmas to be used whenLawfulBEq αis not available. -
#9957 upstreams the definition of Rat from Batteries, for use in our planned interval arithmetic tactic.
-
#9967 removes local
Triplenotation from SpecLemmas.lean to work around a bug that breaks the stage2 build. -
#9979 replaces
Std.Internal.Ratwith the new publicRatupstreamed from Batteries. -
#9987 improves the tactic for proving that elements of a
Nat-basedPRangeare in-bounds by relying on theomegatactic. -
#9993 defines the dyadic rationals, showing they are an ordered ring embedding into the rationals. We will use this for future interval arithmetic tactics.
-
#9999 reduces the number of
Nat.Bitwisegrind annotations we have the deal with distributivity. The new smaller set encouragesgrindto rewrite into DNF. The old behaviour just resulted in saturating up to the instantiation limits. -
#10000 removes a
grindannotation that fired on allOption.maps, causing an avalanche of instantiations. -
#10005 shortens the work necessary to make a type compatible with the polymorphic range notation. In the concrete case of
Nat, it reduces the required lines of code from 150 to 70. -
#10015 exposes the bodies of
Name.append,Name.appendCore, andName.hasMacroScopes. This enables proof by reflection of the concatenation of name literals when using the module system. -
#10018 derives
BEqandHashableforLean.Import. Lake already did this later, but it now done when definingImport. -
#10019 adds
@[expose]toLean.ParserState.setPos. This makes it possible to prove in-boundedness for a state produced bysetPosfor functions likenext'andget'without needing toimport all. -
#10024 adds useful declarations to the
LawfulOrderMin/MaxandLawfulOrderLeftLeaningMin/MaxAPI. In particular, it introduces.leftLeaningOfLEfactories forMinandMax. It also renamesLawfulOrderMin/Max.of_leto .of_le_min_iffand.of_max_le_iff` and introduces a second variant with different arguments. -
#10045 implements the necessary typeclasses so that range notation works for integers. For example,
((-2)...3).toList = [-2, -1, 0, 1, 2] : List Int. -
#10049 adds some background material needed for introducing the dyadic rationals in #9993.
-
#10050 fixes some naming issues in Data/Rat/Lemmas, and upstreams the eliminator
numDenCasesOnand its relatives. -
#10059 improves the names of definitions and lemmas in the polymorphic range API. It also introduces a recommended spelling. For example, a left-closed, right-open range is spelled
Rcoin analogy with Mathlib'sIcointervals. -
#10075 contains lemmas about
Int(minor amendments for BitVec and Nat) that are being used in preparing the dyadics. This is all work of @Rob23oba, which I'm pulling out of #9993 early to keep that one manageable. -
#10077 upstreams lemmas about
RatfromMathlib.Data.Rat.DefsandMathlib.Algebra.Order.Ring.Unbundled.Rat, specifically enough to getLean.Grind.Field RatandLean.Grind.OrderedRing Rat. In addition to the lemmas, instances forInv Rat,Pow Rat NatandPow Rat Inthave been upstreamed. -
#10107 adds the
Lean.Grind.AddCommGroupinstance forRat. -
#10138 adds lemmas about the
Dyadic.roundUpandDyadic.roundDownoperations. -
#10159 adds
nodup_keyslemmas as corollaries of existingdistinct_keysto allMapvariants. -
#10162 removes
grind →annotations that fire too often, unhelpfully. It would be nice forgrindto instantiate these lemmas, but only if they already seexs ++ ysand#[]in the same equivalence class, not just as soon as it seesxs ++ ys. -
#10163 removes some (hopefully) unnecessary
grindannotations that cause instantiation explosions. -
#10173 removes the
extends MonadfromMonadAwaitandMonadAsyncto avoid underdetermined instances. -
#10182 adds lemmas about
Nat.foldandNat.foldRevon sums, to match the existing theorems aboutdfoldanddfoldRev. -
#10194 adds the inverse of a dyadic rational, at a given precision, and characterising lemmas. Also cleans up various parts of the
Int.DivModandRatAPIs, and proves some characterising lemmas aboutRat.toDyadic. -
#10216 fixes #10193.
-
#10224 generalizes the monadic operations for
HashMap,TreeMap, andHashSetto work form : Type u → Type v. -
#10227 adds
@[grind]annotations (nearly all@[grind =]annotations parallel to existing@[simp]s) forReaderT,StateT,ExceptT. -
#10244 adds more lemmas about the
toListandtoArrayfunctions on ranges and iterators. It also renamesArray.mem_toArrayintoList.mem_toArray. -
#10247 adds missing the lemmas
ofList_eq_insertMany_empty,get?_eq_some_iff,getElem?_eq_some_iffandgetKey?_eq_some_iffto all container types. -
#10250 fixes a bug in the
LinearOrderPackage.ofOrdfactory. If there is aLawfulEqOrdinstance available, it should automatically use it instead of requiring the user to provide theeq_of_compareargument to the factory. The PR also solves a hygiene-related problem making the factories fail whenStdis not open. -
#10303 adds range support to
BitVecand theUInt*types. This means that it is now possible to write, for example,for i in (1 : UInt8)...5 do, in order to loop over the values 1, 2, 3 and 4 of typeUInt8. -
#10341 moves the definitions and basic facts about
Function.InjectiveandFunction.Surjectiveup from Mathlib. We can do a better job of arguing via injectivity ingrindif these are available.
Compiler
-
#9631 makes
IO.RealWorldopaque. It also adds a new compiler -onlylcRealWorldconstant to represent this type within the compiler. By default, an opaque type definition is treated likelcAny, whereas we want a more efficient representation. At the moment, this isn't a big difference, but in the future we would like to completely eraseIO.RealWorldat runtime. -
#9922 changes
internalizeCodeto replace all substitutions with non-param-bound fvars inExprs (which are all types) withlcAny, preserving the invariant that there are no such dependencies. The violation of this invariant across files caused test failures in a pending PR, but it is difficult to write a direct test for it. In the future, we should probably change the LCNF checker to detect this. -
#9972 fixes an issue when running Mathlib's
FintypeCatas code, where an erased type former is passed to a polymorphic function. We were lowering the arrow type toobject, which conflicts with the runtime representation of an erased value as a tagged scalar. -
#9977 adds support for compilation of
casesOnrecursors of subsingleton predicates. -
#10023 adds support for correctly handling computations on fields in
casesOnfor inductive predicates that support large elimination. In any such predicate, the only relevant fields allowed are those that are also used as an index, in which case we can find the supplied index and use that term instead. -
#10032 changes the handling of overapplied constructors when lowering LCNF to IR from a (slightly implicit) assertion failure to producing
unreachable. Transformations on inlined unreachable code can produce constructor applications with additional arguments. -
#10040 changes the
toMonopass to replace decls with their_redArgequivalent, which has the consequence of not considering arguments deemed useless by thereduceAritypass for the purposes of thenoncomputablecheck. -
#10070 fixes the compilation of
noConfusionby repairing an oversight made when porting this code from the old compiler. The old compiler only repeatedly expanded the major for each non-Propfield of the inductive under consideration, mirroring the construction ofnoConfusionitself, whereas the new compiler erroneously counted all fields. -
#10133 fixes compatibility of Lean-generated executables with Unicode file system paths on Windows
-
#10214 fixes #10213.
-
#10256 corrects a mistake in
toIRwhere it could over-apply a function that has an IR decl but no mono decl. -
#10355 changes
toLCNFto convert.projfor builtin types to use projection functions instead.
Pretty Printing
-
#10122 adds support for pretty printing using generalized field notation (dot notation) for private definitions on public types. It also modifies dot notation elaboration to resolve names after removing the private prefix, which enables using dot notation for private definitions on private imported types.
-
#10373 adds a
pp.unicodeoption and aunicode("→", "->")syntax description alias for the lower-levelunicodeSymbol "→" "->"parser. The syntax is added to thenotationcommand as well. Whenpp.unicodeis true (the default) then the first form is used when pretty printing, and otherwise the second ASCII form is used. A variant,unicode("→", "->", preserveForPP)causes the->form to be preferred; delaborators can insert→directly into the syntax, which will be pretty printed as-is; this allows notations likefunto use custom options such aspp.unicode.funto opt into the unicode form when pretty printing. -
#10374 adds the options
pp.piBinderNamesandpp.piBinderNames.hygienic. Enablingpp.piBinderNamescauses non-dependent pi binder names to be pretty printed, rather than be omitted. Whenpp.piBinderNames.hygienicis false (the default) then only non-hygienic such biner names are pretty printed. Settingpp.allenablespp.piBinderNamesif it is not otherwise explicitly set.
Documentation
-
#9956 adds additional information to the
letandhavetactic docstrings about opaqueness, when to use each, and associated tactics.
Server
-
#9966 adjusts the "try this" widget to be rendered as a widget message under 'Messages', not a separate widget under a 'Suggestions' section. The main benefit of this is that the message of the widget is not duplicated between 'Messages' and 'Suggestions'.
-
#10047 ensures that hovering over
matchdisplays the type of the match. -
#10052 fixes a bug that caused the Lean server process tree to survive the closing of VS Code.
-
#10249 speeds up auto-completion by a factor of ~3.5x through various performance improvements in the language server. On one machine, with
import Mathlib, completingiused to take 3200ms and now instead yields a result in 920ms.
Lake
Other
-
#10043 allows Lean's parser to run with a final position prior to the end of the string, so it can be invoked on a sub-region of the input.
-
#10217 ensures
@[init]declarations such as frominitializeare run in the order they were declared on import. -
#10262 adds a new option
maxErrorsthat limits the number of errors printed from a singleleanrun, defaulting to 100. Processing is aborted when the limit is reached, but this is tracked only on a per-command level.