-
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
- [manual] The most important differences with Lean 3 are documented in the Lean 4 manual.
- 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 implicit 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.
- The new
calc
-block notation is
calc
A = B := proof1
_ = C := proof2
Note that this is whitespace-sensitive!
- 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?_
.
- Take a look at the Lean 4 tactic cheat sheet: https://github.com/madvorak/lean4-cheatsheet/blob/main/lean-tactics.pdf
- 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
.
-
@[simp, priority 100]
is replaced by@[simp 100]
. Note: you can also do@[simp low]
or@[simp high]
. -
open_locale foo
is (roughly) replaced byopen scoped Foo
(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) a
. This can be used instead of something like@f _ _ _ 3 _ _ _ a
(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. - You can generally hover over more declarations/commands/... to get a pop-up with information. You can also jump to more definitions and notation (using F12). Note that when right-clicking on a declaration you can both "go to definition" and "go to declaration".
- Metaprogramming works completely differently in Lean 4, see the Lean 4 Metaprogramming book and Functional Programming in Lean.
- How to declare notation? [todo]