Lean 4.24.0 (2025-10-14)
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.
Highlights
Lean 4.24.0 release brings continued improvements to the module system and the verification framework,
strengthens the grind tactic, and advances the standard library.
The release also introduces more efficient constructions of DecidableEq instances and noConfusion (#10152 and #10300),
optimizing compilation.
As an example for our continuous improvements to performance:
-
#10249 speeds up auto-completion by a factor of ~3.5x through various performance improvements in the language server.
As always, there are plenty of bug fixes and new features, some of which are listed below:
"Try this" suggestions are rendered under 'Messages'
-
#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'.
invariants and with sections in mvcgen
-
#9927 implements extended
induction-inspired syntax formvcgen, allowing optionalinvariantsandwithsections.The example below gives the proof that
nodupcorrectly checks for duplicates in a list.import Std.Tactic.Do import Std open Std Do def nodup (l : List Int) : Bool := Id.run do 让 mut 看到:HashSet Int := ∅ 为 x 在 l 做 如果 x ∈ 可见则 返回错误 看到 := 看到.插入 x 返回真 theorem nodup_correct (h : nodup l = r) : r = true ↔ l.Nodup := by 在 h 处展开节点 应用Id.of_wp_run_eq h;清除h 生成器 不变量 · 不变.withEarlyReturn (onReturn := 有趣的 ret 看到 => ⌜ret = false ∧ Øl.Nodup⌝) (onContinue := 有趣的 xs 看到 => ⌜(∀ x, x ∈ saw ↔ x ∈ xs.prefix) ∧ xs.prefix.Nodup⌝) 与研磨
Library: Dyadic rationals
-
#9993 defines the dyadic rationals, showing they are an ordered ring embedding into the rationals.
Grind AC solver
grind can reason about associative, commutative, idempotent, and/or unital operations
(#10105, #10146, etc..):
example (a b c : Nat) : max a (max b c) = max (max b 0) (max a c) := by
仅研磨
example {α} (as bs cs : List α) : as ++ (bs ++ cs) = ((as ++ []) ++ bs) ++ (cs ++ []) := by
仅研磨
example {α : Sort u} (op : α → α → α) (u : α) [Std.Associative op] [Std.Commutative op] [Std.IdempotentOp op] [Std.LawfulIdentity op u] (a b c : α)
: op (op a a) (op b c) = op (op (op b a) (op (op u b) b)) c := by
仅研磨
Metaprogramming notes
-
#10306 fixes a few bugs in the
rwtactic.Metaprogramming API: Instead of
Lean.MVarId.rewritepreferLean.Elab.Tactic.elabRewritefor elaborating rewrite theorems and applying rewrites to expressions.
Breaking changes
-
#9749 refactors the Lake codebase to use the new module system throughout. Every module in
Lakeis now amodule.Breaking change: Since the module system encourages a
private-by-default design, the Lake API has switched from its previouspublic-by-default approach. As such, many definitions that were previously public are now private. The newly private definitions are not expected to have had significant user use, nonetheless, important use cases could be missed. If a key API is now inaccessible but seems like it should be public, users are encouraged to report this as an issue on GitHub.
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:/-- 跟踪:[grind.debug.proof] fun h h_1 h_2 h_3 h_4 h_5 h_6 h_7 h_8 => 让 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); 让 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 磨 -
#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:/-- 跟踪:[grind.debug.proof] fun h h_1 h_2 h_3 => Classical.by矛盾乐趣 h_4 => 让 ctx := RArray.branch 1 (RArray.leaf x) (RArray.leaf x⁻¹); 让 e_1 := (Expr.var 0).mul (Expr.var 1); 让 e_2 := Expr.num 0; 让 e_3 := Expr.num 1; 让 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; 让 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 := 通过 磨 -
#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, 通过section和namespace命令引入。自从 sections or namespaces are designed to delimit local attributes, this 将本地属性应用于时会导致不直观的行为 上述上下文中出现的定义。这已经是 导致以下示例失败: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:相互的
-
#9996 改进了
grind cutsat中对非线性单项式的支持。对于 例如,给定单项式a * b,如果cutsat发现a = 2, 它现在传播a * b = 2 * b。 回想一下,像a * b这样的非线性单项式被视为变量cutsat,专为线性整数运算设计的程序。 -
#10007 让 #print 在
protected之前打印private,匹配 语法。 -
#10008 修复了
#eval中单击评估的错误 表达式可能会在信息视图中显示错误。这是由#eval引起的 不保存在详细说明时使用的临时环境 表达。 -
#10010 改进了
grind cutsat中对非线性/和%的支持。 例如,给定a / b,如果cutsat发现b = 2,它现在 传播a / b = b / 2。与#9996类似,但是对于/和%。例子:example (a b c d : Nat) : b > 1 → d = 1 → b ≤ d + 1 → a % b = 1 → a = 2 * c → False := by grind -
#10020 修复了 PR #10010 的缺失情况。
-
#10021 对grind注释分析脚本进行一些小改动, 包括排序结果和处理错误。还需要添加一个 外部用户界面。
-
#10022 改进了当
n不是grind cutsat时对Fin n的支持 数字。例如,现在可以解决以下目标 自动: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. It is similar to #9996, but fora^b. Example:example (n : Nat) : n = 2 → 2 ^ (n+1) = 8 := by 磨
-
#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 type classes 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" error. 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 type classes 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 仅研磨 -
#10151 确保
where finally策略可以访问以下私有数据 模块系统即使相应的漏洞是公开的 范围只要它们都是命题类型。 -
#10152 引入了
DecidableEq的替代结构 避免默认的二次开销的实例 建设。 -
#10166 审查了
grind的预期现在会失败的测试,移动 一些(现在正在传递)测试到主测试套件,更新一些测试, 并添加一些关于指数标准化的测试。 -
#10177 修复了 #10160 暴露的
grind预处理器中的错误。 -
#10179 修复了
grind实例规范化过程。 grind 中的一些模块使用直接在核心中定义的内置实例 (例如,cutsat),而其他人则使用synthInstance合成它们 (例如,ring)。这种不一致是有问题的,因为它可能会引入 不匹配并导致同一内容有两种不同的表示 术语。解决了这个问题。 -
#10183 如果可能的话,让匹配方程由
rfl证明,而不是 首先明确展开 LHS。可能会导致较小的证明。 -
#10185 记录所有
grind属性修饰符(例如=、usr、ext等)。 -
#10186 添加了对简化
grind ac中不等式的支持 模块。 -
#10189 实现新
grind ac模块的证明条款。 示例: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) : 最大 a b = 最大 c d → 最大 b e = 最大 d f → 最大 b g = 最大 d h → max (max f d) (max c g) = max (max e (max d (max b (max c e)))) h := by 仅限磨切 -
#10206 添加关联叠加(但不可交换)
grind ac中的操作员。示例: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 dc → op (op b a) (op b c) = op c (op dc) := by 仅研磨 -
#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 : α) : 运算 d (运算 x c) = 运算 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 仅研磨 -
#10223 实现从新 AC 模块到
grind核心。示例: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 修复了
grind规范化器中缺失的情况。某些类型 可能包括稍后内化的术语或命题grind状态。 -
#10239 修复了包含以下定理的电子匹配过程 任何常规参数均未引用的 Universe 参数。这种 定理在实践中很少发生,但我们确实有实例 标准库。例子:
@[simp, grind =] theorem Std.Do.SPred.down_pure {φ : Prop} : (⌜φ⌝ : SPred []).down = φ := rfl -
#10241 添加了一些
grind与Fin配合使用的测试用例。有tests/lean/grind/grind_fin.lean中的许多测试仍然失败,我是 打算分类并继续工作。 -
#10245 更改了函数
unfoldPredRel的实现 (co)归纳谓词机制,展开点顺序 谓词的量化和含义。之前的实施 依赖于withDeclsDND,无法处理依赖于的类型 彼此。这导致以下示例失败: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 更改字符串插值过程以省略冗余 空零件。例如
s!"{1}{2}"之前详细精化了toString "" ++ toString 1 ++ toString "" ++ toString 2 ++ toString ""现在 详细说明toString 1 ++ toString 2。 -
#10271 更改派生中内部函数的命名 像 BEq 这样的实例使用可访问的名称。这是必要的 相当容易地证明有关这些功能的事情。例如之后
deriving BEq对于类型T,instBEqT的实现位于instBEqT.beq。 -
#10273 尝试对 相同的构造函数匹配构造。
-
#10274 更改了线性
DecidableEq的实现 实现使用match decEq而不是if h :来比较 构造函数标签。否则,“智能展开”机械将无法 让rfl决定不同的构造函数是不同的。 -
#10277 添加缺失的实例
IsPartialOrder、IsLinearPreorderOfNatModule.Q α为IsLinearOrder。 -
#10278 添加了对
NatModule等式和不等式的支持grind linarith。示例: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 := 通过 磨 -
#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 跳过实例上基于模型的理论组合。
-
#10315 添加
T.ctor.noConfusion声明,它们是T.noConfusion的特化到T.ctor之间的等式。的 要点是避免减少T.noConfusionType构造 这次我们使用injection或类似的策略。 -
#10316 共享与相同对象之间的相等性相关的通用功能 构造函数,以及它们的类型是否正确。特别是它使用
mkInjectivityThm中更完整的逻辑也在其他地方,例如 作为CasesOnSameCtor以及BEq、DecidableEq的派生代码,Ord,以获得更高的一致性和更好的错误消息。 -
#10321 确保由
grind中使用的电子匹配模块不受已发生的影响 在调用grind之前执行。目标是增加grind的 鲁棒性。 -
#10322 引入了功能有限的前端
cutsat和grobner为grind。我们禁用定理实例化(和案例 拆分grobner),并关闭所有其他解算器。两者都还 允许grind配置选项,因此例如可以使用cutsat +ring(orgrobner +cutsat) 来解决同时需要两者的问题。 -
#10323 修复了
OfNat.ofNat应用程序的grind规范化器。 示例: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 禁用导致昂贵类型类的未使用实例 搜索。
-
#10325 为
A类型实现基于模型的理论组合,其中 实现ToInt接口。示例: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 data 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 theLawfulOrderBEqandLawfulOrderOrdtype classes relatingBEqandOrdtoLE, and adds many lemmas and instances. -
#9916 provides factories that derive order type classes 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 type classes 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.