-
Notifications
You must be signed in to change notification settings - Fork 355
Lean 4 survival guide for Lean 3 users
Floris van Doorn edited this page May 25, 2023
·
50 revisions
- Lean 4 cheatsheet: https://github.com/madvorak/lean4-cheatsheet/blob/main/lean-tactics.pdf
- [manual] The most important differences with Lean 3 are documented in the Lean 4 manual: https://leanprover.github.io/lean4/doc/lean3changes.html
- Function notation changed from
λ x, f x
tofun x => f x
orλ x => f x
. If you import (almost) any file from mathlib, you can also usefun x ↦ f x
orλ x ↦ f x
. -
Π x : A, P x
is not legal anymore. Use∀ x : A, P x
or(x : A) → P x
- For structures,
{ field1 := value1, field2 := value2, ..parent1, ..parent2 }
is now entered as
{ parent1
parent2 with
field1 := value1
field2 := value2 }
If you have no additional fields, this becomes { parent1, parent2 with }
.
- Pattern matching notation is different, you can use the following examples. Note the use of
=>
instead of:=
(you cannot use↦
here) and that there is noend
ending amatch
.
def Option.str1 : Option Nat → String
| some a => "some " ++ toString a
| none => "none"
def Option.str2 (x : Option Nat) : String :=
match x with
| some a => "some " ++ toString a
| none => "none"
def Option.str3 : Option Nat → String :=
fun
| some a => "some " ++ toString a
| none => "none"
- For infix notation like
+
you cannot use(+)
or(+ n)
anymore, instead use(· + ·)
or(· + n)
. The·
(entered with\.
, not\cdot
) is an anonymous lambda expression. The lambda expression will be inserted at the nearest enclosing parentheses (see [manual]). -
f $ x
has a new notationf <| x
(although the old notation still works) - Lean is whitespace sensitive. This generally means that you end a multi-line command (like
by
,do
,match
, the tactic mode·
, ...) by unindenting the first line after the command.
example : (True → p) → q → p ∧ q := by
intros hp hq
constructor
· apply hp
trivial
exact hq
In the above example the last line is not in scope of the ·
anymore, since it is indented less than the line above it. This tactic block would raise an error if you add two additional spaces in front of the last line.
- Enter tactic mode by using
by
and then a newline, and indenting the tactics. Example:
example : True := by
trivial
- Don't place comma's after tactics, you can go to the next tactic if you write it on a new line (in the same column)
- If you have multiple goals, you can work on the first goal using
· <tactics>
instead of{<tactics>}
. Note that·
is\.
, not\cdot
.
example : (True → p) → q → p ∧ q := by
intros hp hq
constructor
· apply hp
trivial
· exact hq
- If you want multiple tactics on the same line, you can use
tac1; tac2
(which corresponds totac1, tac2
in Lean 3) ortac1 <;> tac2
(which corresponds totac1; tac2
in Lean 3) - Certain new Lean 4 tactics (like
refine
) treat_
and?_
differently._
should be used for implicit arguments that can be figured out by the elaborator.?_
should be used for underscores that produce a new subgoal. You can name these subgoals using?myName
instead of?_
.
- Lean 3's
refine
is Lean 4'srefine'
. - Lean 3's
cases
is Lean 4'scases'
- Lean 3's
induction
is Lean 4'sinduction'
- The square brackets in
rw [h]
are mandatory -
split
has been removed. Useconstructor
.
(This list is taken from the porting wiki. The instructions there might be more up to date in certain edge cases. There are also some examples on that page)
- Terms of
Prop
s (e.g. proofs, theorem names) are insnake_case
. -
Prop
s andType
s (orSort
) (inductive types, structures, classes) are inUpperCamelCase
. - Functions are named the same way as their return values (e.g. a function of type
A → B → C
is named as though it is a term of typeC
). - All other terms of
Type
s (basically anything else) are inlowerCamelCase
. - When something named with
UpperCamelCase
is part of something named withsnake_case
, it is referenced inlowerCamelCase
. - Acronyms like
LE
are written upper-/lowercase as a group, depending on what the first character would be. - Rules 1-6 apply to fields of a structure or constructors of an inductive type in the same way.
There are some rare counter-exceptions to preserve local naming symmetry: e.g., we use Ne
rather than NE
to follow the example of Eq
; outParam
has a Sort
output but is not UpperCamelCase
; etc. Any such counter-exceptions should be discussed on Zulip.
- Named implicit arguments, like
f (x := 3)
(see [manual]) -
f ..
for multiple unnamed arguments (see [manual]) -
#align
is a command to connect Lean 3 names to Lean 4 names, used by mathport. They will be deleted from mathlib at some point after the port is finished.
- Metaprogramming works completely differently in Lean 4, see the Lean 4 Metaprogramming book and Functional Programming in Lean.