Lean 4.11.0 (2024-09-02)
Language features, tactics, and metaprograms
-
The variable inclusion mechanism has been changed. Like before, when a definition mentions a variable, Lean will add it as an argument of the definition, but now in theorem bodies, variables are not included based on usage in order to ensure that changes to the proof cannot change the statement of the overall theorem. Instead, variables are only available to the proof if they have been mentioned in the theorem header or in an
includecommand or are instance implicit and depend only on such variables. Theomitcommand can be used to omit included variables.See breaking changes below.
-
Recursive definitions
-
Structural recursion can now be explicitly requested using
termination_by structural x
in analogy to the existing
termination_by xsyntax that causes well-founded recursion to be used. #4542 -
#4672 fixes a bug that could lead to ill-typed terms.
-
The
termination_by?syntax no longer forces the use of well-founded recursion, and when structural recursion is inferred, it will print the result using thetermination_by structuralsyntax. -
Mutual structural recursion is now supported. This feature supports both mutual recursion over a non-mutual data type, as well as recursion over mutual or nested data types:
mutual def Even : Nat → Prop | 0 => True | n+1 => Odd n def Odd : Nat → Prop | 0 => False | n+1 => Even n end mutual inductive A | other : B → A | empty inductive B | other : A → B | empty end mutual def A.size : A → Nat | .other b => b.size + 1 | .empty => 0 def B.size : B → Nat | .other a => a.size + 1 | .empty => 0 end inductive Tree where | node : List Tree → Tree mutual def Tree.size : Tree → Nat | node ts => Tree.list_size ts def Tree.list_size : List Tree → Nat | [] => 0 | t::ts => Tree.size t + Tree.list_size ts end
Functional induction principles are generated for these functions as well (
A.size.induct,A.size.mutual_induct).Nested structural recursion is still not supported.
PRs: #4639, #4715, #4642, #4656, #4684, #4715, #4728, #4575, #4731, #4658, #4734, #4738, #4718, #4733, #4787, #4788, #4789, #4807, #4772
-
#4809 makes unnecessary
termination_byclauses cause warnings, not errors. -
#4831 improves handling of nested structural recursion through non-recursive types.
-
#4839 improves support for structural recursive over inductive predicates when there are reflexive arguments.
-
-
simptactic-
#4784 sets configuration
Simp.Config.implicitDefEqProofstotrueby default.
-
-
omegatactic -
decidetactic-
#4711 switches from using default transparency to at least default transparency when reducing the
Decidableinstance. -
#4674 adds detailed feedback on
decidetactic failure. It tells you whichDecidableinstances it unfolded, if it get stuck onEq.recit gives a hint about avoiding tactics when definingDecidableinstances, and if it gets stuck onClassical.choiceit gives hints about classical instances being in scope. During this process, it processesDecidable.recs and matches to pin blame on a non-reducing instance.
-
-
@[ext]attribute-
#4543 and #4762 make
@[ext]realizeext_ifftheorems from userexttheorems. Fixes the attribute so that@[local ext]and@[scoped ext]are usable. The@[ext (iff := false)]option can be used to turn offext_iffrealization. -
#4694 makes "go to definition" work for the generated lemmas. Also adjusts the core library to make use of
ext_iffgeneration. -
#4710 makes
ext_ifftheorem preserve inst implicit binder types, rather than making all binder types implicit.
-
-
#evalcommand-
#4810 introduces a safer
#evalcommand that prevents evaluation of terms that containsorry. The motivation is that failing tactics, in conjunction with operations such as array accesses, can lead to the Lean process crashing. Users can use the new#eval!command to use the previous unsafe behavior. (#4829 adjusts a test.)
-
-
#4447 adds
#discr_tree_keyand#discr_tree_simp_keycommands, for helping debug discrimination tree failures. The#discr_tree_key tcommand prints the discrimination tree keys for a termt(or, if it is a single identifier, the type of that constant). It uses the default configuration for generating keys. The#discr_tree_simp_keycommand is similar to#discr_tree_key, but treats the underlying type as one of a simp lemma, that is it transforms it into an equality and produces the key of the left-hand side.For example,
#discr_tree_key (∀ {a n : Nat}, bar a (OfNat.ofNat n)) -- bar _ (@OfNat.ofNat Nat _ _) #discr_tree_simp_key Nat.add_assoc -- @HAdd.hAdd Nat Nat Nat _ (@HAdd.hAdd Nat Nat Nat _ _ _) _ -
#4741 changes option parsing to allow user-defined options from the command line. Initial options are now re-parsed and validated after importing. Command line option assignments prefixed with
weak.are silently discarded if the option name without the prefix does not exist. -
Deriving handlers
-
Metaprogramming
-
#4593 adds
unresolveNameGlobalAvoidingLocals. -
#4618 deletes deprecated functions from 2022.
-
#4642 adds
Meta.lambdaBoundedTelescope. -
#4731 adds
Meta.withErasedFVars, to enter a context with some fvars erased from the local context. -
#4777 adds assignment validation at
closeMainGoal, preventing users from circumventing the occurs check for tactics such asexact. -
#4807 introduces
Lean.Meta.PProdNmodule for packing and projecting nestedPProds. -
#5170 fixes
Syntax.unsetTrailing. A consequence of this is that "go to definition" now works on the last module name in animportblock (issue #4958).
-
Language server, widgets, and IDE extensions
-
#4727 makes it so that responses to info view requests come as soon as the relevant tactic has finished execution.
-
#4580 makes it so that whitespace changes do not invalidate imports, and so starting to type the first declaration after imports should no longer cause them to reload.
-
#4780 fixes an issue where hovering over unimported builtin names could result in a panic.
Pretty printing
-
#4558 fixes the
pp.instantiateMVarssetting and changes the default value totrue. -
#4631 makes sure syntax nodes always run their formatters. Fixes an issue where if
ppSpaceappears in amacroorelabcommand then it does not format with a space. -
#4665 fixes a bug where pretty printed signatures (for example in
#check) were overly hoverable due topp.tagAppFnsbeing set. -
#4724 makes
matchpretty printer be sensitive topp.explicit, which makes hovering over amatchin the Infoview show the underlying term. -
#4764 documents why anonymous constructor notation isn't pretty printed with flattening.
-
#4786 adjusts the parenthesizer so that only the parentheses are hoverable, implemented by having the parentheses "steal" the term info from the parenthesized expression.
-
#4854 allows arbitrarily long sequences of optional arguments to be omitted from the end of applications, versus the previous conservative behavior of omitting up to one optional argument.
Library
-
Nat -
Int-
#4903 fixes performance of
HPow Int Nat Intsynthesis by rewriting it as aNatPow Intinstance.
-
-
UInt*andFin -
Option -
GetElem-
#4603 adds
getElem_congrto help with rewriting indices.
-
-
ListandArray-
Upstreamed from Batteries: #4586 upstreams
List.attachandArray.attach, #4697 upstreamsList.SubsetandList.Sublistand API, #4706 upstreams basic material onList.PairwiseandList.Nodup, #4720 upstreams moreList.eraseAPI, #4836 and #4837 upstreamList.IsPrefix/List.IsSuffix/List.IsInfixand addDecidableinstances, #4855 upstreamsList.tail,List.findIdx,List.indexOf,List.countP,List.count, andList.range', #4856 upstreams more List lemmas, #4866 upstreamsList.pairwise_iff_getElem, #4865 upstreamsList.eraseIdxlemmas. -
#4687 adjusts
List.replicatesimp lemmas and simprocs. -
#4704 adds characterizations of
List.Sublist. -
#4707 adds simp normal form tests for
List.PairwiseandList.Nodup. -
#4765 adds simprocs for literal array accesses such as
#[1,2,3,4,5][2]. -
#4790 removes typeclass assumptions for
List.Nodup.eraseP. -
#4801 adds efficient
usizefunctions for array types. -
#4820 changes
List.filterMapMto run left-to-right. -
#4835 fills in and cleans up gaps in List API.
-
#4863 splits
Init.Data.List.Lemmasinto function-specific files. -
#4875 fixes statement of
List.take_takeWhile. -
Lemmas: #4602, #4627, #4678 for
List.headandlist.getLast, #4723 forList.erase, #4742
-
-
ByteArray-
#4582 eliminates
partialfromByteArray.toListandByteArray.findIdx?.
-
-
BitVec -
Std.HashMapadded:-
#4583 adds
Std.HashMapas a verified replacement forLean.HashMap. See the PR for naming differences, but #4725 renamesHashMap.removetoHashMap.erase. -
#4682 adds
Inhabitedinstances. -
#4732 improves
BEqargument order in hash map lemmas. -
#4759 makes lemmas resolve instances via unification.
-
#4771 documents that hash maps should be used linearly to avoid expensive copies.
-
#4791 removes
biffrom hash map lemmas, which is inconvenient to work with in practice. -
#4803 adds more lemmas.
-
-
SMap-
#4690 upstreams
SMap.foldM.
-
-
BEq-
#4607 adds
PartialEquivBEq,ReflBEq,EquivBEq, andLawfulHashableclasses.
-
-
IO-
#4660 adds
IO.Process.Child.tryWait.
-
-
#4747, #4730, and #4756 add
×'syntax forPProd. Adds a delaborator forPProdandMProdvalues to pretty print as flattened angle bracket tuples. -
Other fixes or improvements
-
#4604 adds lemmas for cond.
-
#4619 changes some definitions into theorems.
-
#4616 fixes some names with duplicated namespaces.
-
#4620 fixes simp lemmas flagged by the simpNF linter.
-
#4666 makes the
Antisymmclass be aProp. -
#4621 cleans up unused arguments flagged by linter.
-
#4680 adds imports for orphaned
Initmodules. -
#4679 adds imports for orphaned
Std.Datamodules. -
#4688 adds forward and backward directions of
not_exists. -
#4689 upstreams
eq_iff_true_of_subsingleton. -
#4709 fixes precedence handling for
Reprinstances for negative numbers forIntandFloat. -
#4760 renames
TC("transitive closure") toRelation.TransGen. -
#4842 fixes
Listdeprecations. -
#4852 upstreams some Mathlib attributes applied to lemmas.
-
93ac63 improves proof.
-
#4862 and #4878 generalize the universe for
PSigma.existsand rename it toExists.of_psigma_prop.
-
Lean internals
-
Elaboration
-
#4596 enforces
isDefEqStuckExatunstuckMVarprocedure, causing isDefEq to throw a stuck defeq exception if the metavariable was created in a previous level. This results in some better error messages, and it helpsrwsucceed in synthesizing instances (see issue #2736). -
#4713 fixes deprecation warnings when there are overloaded symbols.
-
elab_as_elimalgorithm: -
#4792 adds term elaborator for
Lean.Parser.Term.namedPattern(e.g.n@(n' + 1)) to report errors when used in non-pattern-matching contexts. -
#4818 makes anonymous dot notation work when the expected type is a pi-type-valued type synonym.
-
-
Typeclass inference
-
#4646 improves
synthAppInstances, the function responsible for synthesizing instances for therwandapplytactics. Adds a synthesis loop to handle functions whose instances need to be synthesized in a complex order.
-
-
Inductive types
-
Definitions
-
Diagnostics and profiling
-
#4611 makes kernel diagnostics appear when
diagnosticsis enabled even if it is the only section. -
#4753 adds missing
profileitMfunctions. -
#4754 adds
Lean.Expr.numObjsto compute the number of allocated sub-expressions in a given expression, primarily for diagnosing performance issues. -
#4769 adds missing
withTraceNodes to improvetrace.profileroutput. -
#4781 and #4882 make the "use
set_option diagnostics true" message be conditional on current setting ofdiagnostics.
-
-
Performance
-
#4767, #4775, and #4887 add
ShareCommon.shareCommon'for sharing common terms. In an example with 16 million subterms, it is 20 times faster than the oldshareCommonprocedure. -
#4779 ensures
Expr.replaceExprpreserves DAG structure inExprs. -
#4783 documents performance issue in
Expr.replaceExpr. -
#4795 makes
Expr.find?andExpr.findExt?use the kernel implementations. -
#4799 makes
Expr.replaceuse the kernel implementation. -
#4871 makes
Expr.foldConstsuse a precise cache. -
#4890 makes
expr_eq_fnuse a precise cache.
-
-
Utilities
-
#4453 upstreams
ToExpr FilePathandcompile_time_search_path%.
-
-
Module system
-
#4652 fixes handling of
const2ModIdxinfinalizeImport, making it prefer the original module for a declaration when a declaration is re-declared.
-
-
Kernel
-
#4637 adds a check to prevent large
Natexponentiations from evaluating. Elaborator reduction is controlled by the optionexponentiation.threshold. -
#4683 updates comments in
kernel/declaration.h, making sure they reflect the current Lean 4 types. -
#4796 improves performance by using
replacewith a precise cache. -
#4700 improves performance by fixing the implementation of move constructors and move assignment operators. Expression copying was taking 10% of total runtime in some workloads. See issue #4698.
-
#4702 improves performance in
replace_rec_fn::applyby avoiding expression copies. These copies represented about 13% of time spent insave_resultin some workloads. See the same issue.
-
-
Other fixes or improvements
-
#4590 fixes a typo in some constants and
trace.profiler.useHeartbeats. -
#4617 add 'since' dates to
deprecatedattributes. -
#4625 improves the robustness of the constructor-as-variable test.
-
#4740 extends test with nice example reported on Zulip.
-
#4766 moves
Syntax.hasIdentto be available earlier and shakes dependencies. -
#4881 splits out
Lean.Language.Lean.Types. -
#4893 adds
LEAN_EXPORTforsharecommonfunctions. -
Docs: #4748 (
Command.Scope)
-
Compiler, runtime, and FFI
-
#4661 moves
Stdfromlibleansharedto much smallerlibInit_shared. This fixes the Windows build. -
#4668 fixes initialization, explicitly initializing
Stdinlean_initialize. -
#4746 adjusts
shouldExportto exclude more symbols to get below Windows symbol limit. Some exceptions are added by #4884 and #4956 to support Verso. -
#4778 adds
lean_is_exclusive_obj(Lean.isExclusiveUnsafe) andlean_set_external_data. -
#4515 fixes calling programs with spaces on Windows.
Lake
-
#4735 improves a number of elements related to Git checkouts, cloud releases, and related error handling.
-
On error, Lake now prints all top-level logs. Top-level logs are those produced by Lake outside of the job monitor (e.g., when cloning dependencies).
-
When fetching a remote for a dependency, Lake now forcibly fetches tags. This prevents potential errors caused by a repository recreating tags already fetched.
-
Git error handling is now more informative.
-
The builtin package facets
release,optRelease,extraDepare now captions in the same manner as other facets. -
afterReleaseSyncandafterReleaseAsyncnow fetchoptReleaserather thanrelease. -
Added support for optional jobs, whose failure does not cause the whole build to failure. Now
optReleaseis such a job.
-
-
#4608 adds draft CI workflow when creating new projects.
-
#4847 adds CLI options to control log levels. The
--log-level=<lv>controls the minimum log level Lake should output. For instance,--log-level=errorwill only print errors (not warnings or info). Also, adds an analogous--fail-leveloption to control the minimum log level for build failures. The existing--iofailand--wfailoptions are respectively equivalent to--fail-level=infoand--fail-level=warning. -
Docs: #4853
DevOps/CI
-
Workflows
-
#4531 makes release trigger an update of
release.lean-lang.org. -
#4598 adjusts
pr-releaseto the newlakefile.leansyntax. -
#4632 makes
pr-releaseuse the correct tag name. -
#4638 adds ability to manually trigger nightly release.
-
#4640 adds more debugging output for
restart-on-labelCI. -
#4663 bumps up waiting for 10s to 30s for
restart-on-label. -
#4664 bumps versions for
actions/checkoutandactions/upload-artifacts. -
582d6e bumps version for
actions/download-artifact. -
6d9718 adds back dropped
check-stage3. -
0768ad adds Jira sync (for FRO).
-
#4830 adds support to report CI errors on FRO Zulip.
-
#4838 adds trigger for
nightly_bump_toolchainon mathlib4 upon nightly release. -
abf420 fixes msys2.
-
#4895 deprecates Nix-based builds and removes interactive components. Users who prefer the flake build should maintain it externally.
-
-
#4669 fixes the "max dynamic symbols" metric per static library.
-
#4691 improves compatibility of
tests/list_simpfor retesting simp normal forms with Mathlib. -
#4806 updates the quickstart guide.
-
c02aa9 documents the triage team in the contribution guide.
Breaking changes
-
For
@[ext]-generatedextandext_ifflemmas, thexandyterm arguments are now implicit. Furthermore these two lemmas are now protected (#4543). -
Now
trace.profiler.useHearbeatsistrace.profiler.useHeartbeats(#4590). -
A bugfix in the structural recursion code may in some cases break existing code, when a parameter of the type of the recursive argument is bound behind indices of that type. This can usually be fixed by reordering the parameters of the function (#4672).
-
Now
List.filterMapMsequences monadic actions left-to-right (#4820). -
The effect of the
variablecommand on proofs oftheorems has been changed. Whether such section variables are accessible in the proof now depends only on the theorem signature and other top-level commands, not on the proof itself. This change ensures that-
the statement of a theorem is independent of its proof. In other words, changes in the proof cannot change the theorem statement.
-
tactics such as
inductioncannot accidentally include a section variable. -
the proof can be elaborated in parallel to subsequent declarations in a future version of Lean.
The effect of
variables on the theorem header as well as on other kinds of declarations is unchanged.Specifically, section variables are included if they
-
are directly referenced by the theorem header,
-
are included via the new
includecommand in the current section and not subsequently mentioned in anomitstatement, -
are directly referenced by any variable included by these rules, OR
-
are instance-implicit variables that reference only variables included by these rules.
For porting, a new option
deprecated.oldSectionVarsis included to locally switch back to the old behavior. -