Lean 4.8.0 (2024-06-05)
Language features, tactics, and metaprograms
-
Functional induction principles. #3432, #3620, #3754, #3762, #3738, #3776, #3898.
Derived from the definition of a (possibly mutually) recursive function, a functional induction principle is created that is tailored to proofs about that function.
For example from:
def ackermann : Nat → Nat → Nat | 0, m => m + 1 | n+1, 0 => ackermann n 1 | n+1, m+1 => ackermann n (ackermann (n + 1) m)
we get
ackermann.induct (motive : Nat → Nat → Prop) (case1 : ∀ (m : Nat), motive 0 m) (case2 : ∀ (n : Nat), motive n 1 → motive (Nat.succ n) 0) (case3 : ∀ (n m : Nat), motive (n + 1) m → motive n (ackermann (n + 1) m) → motive (Nat.succ n) (Nat.succ m)) (x x : Nat) : motive x x
It can be used in the
inductiontactic using theusingsyntax:induction n, m using ackermann.induct
-
The termination checker now recognizes more recursion patterns without an explicit
termination_by. In particular the idiom of counting up to an upper bound, as indef Array.sum (arr : Array Nat) (i acc : Nat) : Nat := if _ : i < arr.size then Array.sum arr (i+1) (acc + arr[i]) else accis recognized without having to say
termination_by arr.size - i. -
#3629, #3655, #3747: Adds
@[induction_eliminator]and@[cases_eliminator]attributes to be able to define custom eliminators for theinductionandcasestactics, replacing the@[eliminator]attribute. Gives custom eliminators forNatso thatinductionandcasesput goal states into terms of0andn + 1rather thanNat.zeroandNat.succ n. Added optiontactic.customEliminatorsto control whether to use custom eliminators. Added a hack forrcases/rintro/obtainto use the custom eliminator forNat. -
Shorter instances names. There is a new algorithm for generating names for anonymous instances. Across Std and Mathlib, the median ratio between lengths of new names and of old names is about 72%. With the old algorithm, the longest name was 1660 characters, and now the longest name is 202 characters. The new algorithm's 95th percentile name length is 67 characters, versus 278 for the old algorithm. While the new algorithm produces names that are 1.2% less unique, it avoids cross-project collisions by adding a module-based suffix when it does not refer to declarations from the same "project" (modules that share the same root). #3089 and #3934.
-
8d2adf Importing two different files containing proofs of the same theorem is no longer considered an error. This feature is particularly useful for theorems that are automatically generated on demand (e.g., equational theorems).
-
84b091 Lean now generates an error if the type of a theorem is not a proposition.
-
Definition transparency. 47a343.
@[reducible],@[semireducible], and@[irreducible]are now scoped and able to be set for imported declarations. -
simp/dsimp-
#3607 enables kernel projection reduction in
dsimp -
b24fbf and acdb00:
dsimproccommand to define defeq-preserving simplification procedures. -
#3624 makes
dsimpnormalize raw nat literals asOfNat.ofNatapplications. -
#3628 makes
simpcorrectly handleOfScientific.ofScientificliterals. -
#3654 makes
dsimp?report used simprocs. -
dee074 fixes equation theorem handling in
simpfor non-recursive definitions. -
#3819 improved performance when simp encounters a loop.
-
#3821 fixes discharger/cache interaction.
-
#3824 keeps
simpfrom breakingCharliterals. -
#3838 allows
Natinstances matching to be more lenient. -
#3870 documentation for
simpconfiguration options. -
#3972 fixes simp caching.
-
#4044 improves cache behavior for "well-behaved" dischargers.
-
-
omega -
rfl -
#3719 upstreams the
rw?tactic, with fixes and improvements in #3783, #3794, #3911. -
conv -
#guard_msgs-
#3617 introduces whitespace protection using the
⏎character. -
#3883: The
#guard_msgscommand now has options to change whitespace normalization and sensitivity to message ordering. For example,#guard_msgs (whitespace := lax) in cmdcollapses whitespace before checking messages, and#guard_msgs (ordering := sorted) in cmdsorts the messages in lexicographic order before checking. -
#3931 adds an unused variables ignore function for
#guard_msgs. -
#3912 adds a diff between the expected and actual outputs. This feature is currently disabled by default, but can be enabled with
set_option guard_msgs.diff true. Depending on user feedback, this option may default totruein a future version of Lean.
-
-
donotation-
#3820 makes it an error to lift
(<- ...)out of a pureif ... then ... else ...
-
-
Lazy discrimination trees
-
#3610 fixes a name collision for
LazyDiscrTreethat could lead to cache poisoning. -
#3677 simplifies and fixes
LazyDiscrTreehandling forexact?/apply?. -
#3685 moves general
exact?/apply?functionality intoLazyDiscrTree. -
#3769 has lemma selection improvements for
rw?andLazyDiscrTree. -
#3818 improves ordering of matches.
-
-
#3590 adds
inductive.autoPromoteIndicesoption to be able to disable auto promotion of indices in theinductivecommand. -
Miscellaneous bug fixes and improvements
-
#3606 preserves
cacheanddischargeDepthfields inLean.Meta.Simp.Result.mkEqSymm. -
#3633 makes
elabTermEnsuringTyperespecterrToSorry, improving error recovery of thehavetactic. -
#3647 enables
noncomputable unsafedefinitions, for deferring implementations until later. -
#3672 adjust namespaces of tactics.
-
#3725 fixes
Ordderive handler for indexed inductive types with unused alternatives. -
#3893 improves performance of derived
Ordinstances. -
#3771 changes error reporting for failing tactic macros. Improves
rflerror message. -
#3745 fixes elaboration of generalized field notation if the object of the notation is an optional parameter.
-
#3799 makes commands such as
universe,variable,namespace, etc. require that their argument appear in a later column. Commands that can optionally parse anidentor parse any number ofidents generally should require that theidentusecolGt. This keeps typos in commands from being interpreted as identifiers. -
#3815 lets the
splittactic be used for writing code. -
#3822 adds missing info in
inductiontactic forwithclauses of the form| cstr a b c => ?_. -
#3806 fixes
withSetOptionIncombinator. -
#3844 removes unused
trace.Elab.syntaxoption. -
#3896 improves hover and go-to-def for
attributecommand. -
#3989 makes linter options more discoverable.
-
#3916 fixes go-to-def for syntax defined with
@[builtin_term_parser]. -
#3962 fixes how
solveByElimhandlessymmlemmas, makingexact?/apply?usable again. -
#3968 improves the
@[deprecated]attribute, adding(since := "<date>")field. -
#3768 makes
#printcommand show structure fields. -
#3974 makes
exact?%behave likeby exact?rather thanby apply?. -
#3994 makes elaboration of
he ▸ hnotation more predictable. -
#3991 adjusts transparency for
decreasing_trivialmacros. -
#4092 improves performance of
binop%andbinrel%expression tree elaborators.
-
-
Docs: #3748, #3796, #3800, #3874, #3863, #3862, #3891, #3873, #3908, #3872.
Language server and IDE extensions
-
#3602 enables
importauto-completions. -
#3608 fixes issue leanprover/vscode-lean4#392. Diagnostic ranges had an off-by-one error that would misplace goal states for example.
-
#3014 introduces snapshot trees, foundational work for incremental tactics and parallelism. #3849 adds basic incrementality API.
-
#3271 adds support for server-to-client requests.
-
#3656 fixes jump to definition when there are conflicting names from different files. Fixes issue #1170.
-
#3691, #3925, #3932 keep semantic tokens synchronized (used for semantic highlighting), with performance improvements.
-
#3247 and #3730 add diagnostics to run "Restart File" when a file dependency is saved.
-
#3722 uses the correct module names when displaying references.
-
#3728 makes errors in header reliably appear and makes the "Import out of date" warning be at "hint" severity. #3739 simplifies the text of this warning.
-
#3778 fixes #3462, where info nodes from before the cursor would be used for computing completions.
-
#3985 makes trace timings appear in Infoview.
Pretty printing
-
#3797 fixes the hovers over binders so that they show their types.
-
#3640 and #3735: Adds attribute
@[pp_using_anonymous_constructor]to make structures pretty print as⟨x, y, z⟩rather than as{a := x, b := y, c := z}. This attribute is applied toSigma,PSigma,PProd,Subtype,And, andFin. -
#3749 Now structure instances pretty print with parent structures' fields inlined. That is, if
BextendsA, then{ toA := { x := 1 }, y := 2 }now pretty prints as{ x := 1, y := 2 }. Setting optionpp.structureInstances.flattento false turns this off. -
#3737, #3744 and #3750: Option
pp.structureProjectionsis renamed topp.fieldNotation, and there is now a suboptionpp.fieldNotation.generalizedto enable pretty printing function applications using generalized field notation (defaults to true). Field notation can be disabled on a function-by-function basis using the@[pp_nodot]attribute. The notation is not used for theorems. -
#4071 fixes interaction between app unexpanders and
pp.fieldNotation.generalized -
#3625 makes
delabConstWithSignature(used by#check) have the ability to put arguments "after the colon" to avoid printing inaccessible names. -
#3798, #3978, #3798: Adds options
pp.mvars(default: true) andpp.mvars.withType(default: false). Whenpp.mvarsis false, expression metavariables pretty print as?_and universe metavariables pretty print as_. Whenpp.mvars.withTypeis true, expression metavariables pretty print with a type ascription. These can be set when using#guard_msgsto make tests not depend on the particular names of metavariables. -
#3917 makes binders hoverable and gives them docstrings.
-
#4034 makes hovers for RHS terms in
matchexpressions in the Infoview reliably show the correct term.
Library
-
Bool/Prop -
Nat -
Int-
Theorems: #3890
-
-
UInts-
#3960 improves performance of upcasting.
-
-
ArrayandSubarray -
List-
#3785 upstreams tail-recursive List operations and
@[csimp]lemmas.
-
-
BitVec -
String -
IO-
#4097 adds
IO.getTaskStatewhich returns whether a task is finished, actively running, or waiting on other Tasks to finish.
-
-
Refactors
-
#3605 reduces imports for
Init.Data.NatandInit.Data.Int. -
#3613 reduces imports for
Init.Omega.Int. -
#3634 upstreams
Std.Data.Natand #3635 upstreamsStd.Data.Int. -
#3790 reduces more imports for
omega. -
#3694 extends
GetEleminterface withgetElem!andgetElem?to simplify containers likeRBMap. -
#3865 renames
Option.toMonad(see breaking changes below). -
#3882 unifies
lexOrdwithcompareLex.
-
-
Other fixes or improvements
-
#3765 makes
Quotient.soundbe atheorem. -
#3645 fixes
System.FilePath.parentin the case of absolute paths. -
#3660
ByteArray.toUInt64LE!andByteArray.toUInt64BE!were swapped. -
#3881, #3887 fix linearity issues in
HashMap.insertIfNew,HashSet.erase, andHashMap.erase. TheHashMap.insertIfNewfix improvesimportperformance. -
#3830 ensures linearity in
Parsec.many*Core. -
#3930 adds
FS.Stream.isTtyfield. -
#3866 deprecates
Option.toBoolin favor ofOption.isSome. -
#3975 upstreams
Data.List.InitandData.Array.Initmaterial from Std. -
#3942 adds instances that make
ac_rflwork without Mathlib. -
#4010 changes
Fin.inductionto use structural induction. -
02753f fixes bug in
reduceLeDiffsimproc. -
#4097 adds
IO.TaskStateandIO.getTaskStateto get the task from the Lean runtime's task manager.
-
-
Docs: #3615, #3664, #3707, #3734, #3868, #3861, #3869, #3858, #3856, #3857, #3867, #3864, #3860, #3859, #3871, #3919.
Lean internals
-
Defeq and WHNF algorithms
-
#3616 gives better support for reducing
Nat.recexpressions. -
#3774 add tracing for "non-easy" WHNF cases.
-
#3807 fixes an
isDefEqperformance issue, now trying structure eta after lazy delta reduction. -
#3816 fixes
.yesWithDeltaIbehavior to prevent increasing transparency level when reducing projections. -
#3837 improves heuristic at
isDefEq. -
#3965 improves
isDefEqfor constraints of the formt.i =?= s.i. -
#3977 improves
isDefEqProj. -
#3981 adds universe constraint approximations to be able to solve
u =?= max u ?vusing?v = u. These approximations are only applied when universe constraints cannot be postponed anymore. -
#4004 improves
isDefEqProjduring typeclass resolution. -
#4012 adds
backward.isDefEq.lazyProjDeltaandbackward.isDefEq.lazyWhnfCorebackwards compatibility flags.
-
-
Kernel
-
Discrimination trees
-
Typeclass instance synthesis
-
Definition processing
-
#3661, #3767 changes automatically generated equational theorems to be named using suffix
.eq_<idx>instead of._eq_<idx>, and.eq_definstead of._unfold. (See breaking changes below.) #3675 adds a mechanism to reserve names. #3803 fixes reserved name resolution inside namespaces and fixes handling ofmatcher declarations and equation lemmas. -
#3662 causes auxiliary definitions nested inside theorems to become
defs if they are not proofs. -
#4006 makes proposition fields of
structures be theorems. -
#4018 makes it an error for a theorem to be
extern. -
#4047 improves performance making equations for well-founded recursive definitions.
-
-
Refactors
-
#3614 avoids unfolding in
Lean.Meta.evalNat. -
#3621 centralizes functionality for
Fix/GuessLex/FunIndin theArgsPackermodule. -
#3186 rewrites the UnusedVariable linter to be more performant.
-
#3589 removes coercion from
StringtoName(see breaking changes below). -
#3237 removes the
linesfield fromFileMap. -
#3951 makes msg parameter to
throwTacticExoptional.
-
-
Diagnostics
-
#4016, #4019, #4020, #4030, #4031, c3714b, #4049 adds
set_option diagnostics truefor diagnostic counters. Tracks number of unfolded declarations, instances, reducible declarations, used instances, recursor reductions,isDefEqheuristic applications, among others. This option is suggested in exceptional situations, such as at deterministic timeout and maximum recursion depth. -
283587 adds diagnostic information for
simp. -
#4043 adds diagnostic information for congruence theorems.
-
#4048 display diagnostic information for
set_option diagnostics true in <tactic>andset_option diagnostics true in <term>.
-
-
Other features
-
#3800 adds environment extension to record which definitions use structural or well-founded recursion.
-
#3801
trace.profilercan now export to Firefox Profiler. -
#3918, #3953 adds
@[builtin_doc]attribute to make docs and location of a declaration available as a builtin. -
#3939 adds the
lean --jsonCLI option to print messages as JSON. -
#3075 improves
test_externcommand. -
#3970 gives monadic generalization of
FindExpr.
-
-
Other fixes: #3622, #3726, #3823, #3897, #3964, #3946, #4007, #4026.
Compiler, runtime, and FFI
-
#3632 makes it possible to allocate and free thread-local runtime resources for threads not started by Lean itself.
-
#3627 improves error message about compacting closures.
-
#3692 fixes deadlock in
IO.Promise.resolve. -
#3753 catches error code from
MoveFileExon Windows. -
#4028 fixes a double
resetbug inResetReusetransformation. -
6e731b removes
interpretercopy constructor to avoid potential memory safety issues.
Lake
-
TOML Lake configurations. #3298, #4104.
Lake packages can now use TOML as a alternative configuration file format instead of Lean. If the default
lakefile.leanis missing, Lake will also look for alakefile.toml. The TOML version of the configuration supports a restricted set of the Lake configuration options, only including those which can easily mapped to a TOML data structure. The TOML syntax itself fully compiles with the TOML v1.0.0 specification.As part of the introduction of this new feature, we have been helping maintainers of some major packages within the ecosystem switch to this format. For example, the following is Aesop's new
lakefile.toml:leanprover-community/aesop/lakefile.toml
name = "aesop" defaultTargets = ["Aesop"] testRunner = "test" precompileModules = false [[require]] name = "batteries" git = "https://github.com/leanprover-community/batteries" rev = "main" [[lean_lib]] name = "Aesop" [[lean_lib]] name = "AesopTest" globs = ["AesopTest.+"] leanOptions = {linter.unusedVariables = false} [[lean_exe]] name = "test" srcDir = "scripts"To assist users who wish to transition their packages between configuration file formats, there is also a new
lake translate-configcommand for migrating to/from TOML.Running
lake translate-config tomlwill produce alakefile.tomlversion of a package'slakefile.lean. Any configuration options unsupported by the TOML format will be discarded during translation, but the originallakefile.leanwill remain so that you can verify the translation looks good before deleting it. -
Build progress overhaul. #3835, #4115, #4127, #4220, #4232, #4236.
Builds are now managed by a top-level Lake build monitor, this makes the output of Lake builds more standardized and enables producing prettier and more configurable progress reports.
As part of this change, job isolation has improved. Stray I/O and other build related errors in custom targets are now properly isolated and caught as part of their job. Import errors no longer cause Lake to abort the entire build and are instead localized to the build jobs of the modules in question.
Lake also now uses ANSI escape sequences to add color and produce progress lines that update in-place; this can be toggled on and off using
--ansi/--no-ansi.--wfailand--iofailoptions have been added that causes a build to fail if any of the jobs log a warning (--wfail) or produce any output or log information messages (--iofail). Unlike some other build systems, these options do NOT convert these logs into errors, and Lake does not abort jobs on such a log (i.e., dependent jobs will still continue unimpeded). -
lake test. #3779.Lake now has a built-in
testcommand which will run a script or executable labelled@[test_runner](in Lean) or defined as thetestRunner(in TOML) in the root package.Lake also provides a
lake check-testcommand which will exit with code0if the package has a properly configured test runner or error with1otherwise. -
lake lean. #3793.The new command
lake lean <file> [-- <args...>]functions likelake env lean <file> <args...>, except that it builds the imports offilebefore runninglean. This makes it very useful for running test or example code that imports modules that are not guaranteed to have been built beforehand. -
Miscellaneous bug fixes and improvements
-
#3609
LEAN_GITHASHenvironment variable to override the detected Git hash for Lean when computing traces, useful for testing custom builds of Lean. -
#3795 improves relative package directory path normalization in the pre-rename check.
-
#3957 fixes handling of packages that appear multiple times in a dependency tree.
-
#3999 makes it an error for there to be a mismatch between a package name and what it is required as. Also adds a special message for the
std-to-batteriesrename. -
#4033 fixes quiet mode.
-
-
Docs: #3704.
DevOps
-
#3600 runs nix-ci more uniformly.
-
#3612 avoids argument limits when building on Windows.
-
#3682 builds Lean's
.ofiles in parallel to rest of core. -
#3601 changes the way Lean is built on Windows (see breaking changes below). As a result, Lake now dynamically links executables with
supportInterpreter := trueon Windows tolibleanshared.dllandlibInit_shared.dll. Therefore, such executables will not run unless those shared libraries are co-located with the executables or part ofPATH. Running the executable vialake exewill ensure these libraries are part ofPATH.In a related change, the signature of the
nativeFacetsLake configuration options has changed from a staticArrayto a function(shouldExport : Bool) → Array. See its docstring or Lake's README for further details on the changed option. -
#3690 marks "Build matrix complete" as canceled if the build is canceled.
-
#3700, #3702, #3701, #3834, #3923: fixes and improvements for std and mathlib CI.
-
#3712 fixes
nix build .on macOS. -
#3717 replaces
shell.nixin devShell withflake.nix. -
#3971 prevents stage0 changes via the merge queue.
-
#3979 adds handling for
changes-stage0label. -
#3952 adds a script to summarize GitHub issues.
-
18a699 fixes asan linking
Breaking changes
-
Due to the major Lake build refactor, code using the affected parts of the Lake API or relying on the previous output format of Lake builds is likely to have been broken. We have tried to minimize the breakages and, where possible, old definitions have been marked
@[deprecated]with a reference to the new alternative. -
Executables configured with
supportInterpreter := trueon Windows should now be run vialake exeto function properly. -
Automatically generated equational theorems are now named using suffix
.eq_<idx>instead of._eq_<idx>, and.eq_definstead of._unfold. Example:
def fact : Nat → Nat
| 0 => 1
| n+1 => (n+1) * fact n
theorem ex : fact 0 = 1 := by unfold fact; decide
#check fact.eq_1
-- fact.eq_1 : fact 0 = 1
#check fact.eq_2
-- fact.eq_2 (n : Nat) : fact (Nat.succ n) = (n + 1) * fact n
#check fact.eq_def
/-
fact.eq_def :
∀ (x : Nat),
fact x =
match x with
| 0 => 1
| Nat.succ n => (n + 1) * fact n
-/
-
The coercion from
StringtoNamewas removed. Previously, it wasName.mkSimple, which does not separate strings at dots, but experience showed that this is not always the desired coercion. For the previous behavior, manually insert a call toName.mkSimple. -
The
Subarrayfieldsas,h₁andh₂have been renamed toarray,start_le_stop, andstop_le_array_size, respectively. This more closely follows standard Lean conventions. Deprecated aliases for the field projections were added; these will be removed in a future release. -
The change to the instance name algorithm (described above) can break projects that made use of the auto-generated names.
-
Option.toMonadhas been renamed toOption.getMand the unneeded[Monad m]instance argument has been removed.