Tactics¶
Every tactic used in these notes, including the how-to guides, with what it does, where it first appears and which library provides it. Each example is taken from a file that compiles. The table gives the overview; the sections below give the detail in the same order.
| Tactic | Does | First used | From |
|---|---|---|---|
norm_num |
proves numerical goals, unfolding what it is told | 3 | Mathlib |
rfl |
proves an equation whose sides agree by definition | 3 | Lean |
decide |
proves a goal by running a decision procedure | 3 | Lean |
intro |
introduces the variable of a ∀ or → |
4 | Lean |
cases |
splits on the constructors of a type | 4 | Lean |
· |
focuses on the first remaining goal | 4 | Lean |
<;> |
runs a tactic on every goal the previous produced | 4 | Lean |
left |
chooses the left side of a disjunction | 5 | Lean |
have |
adds a named fact to the context | 5 | Lean |
at |
aims a tactic at a hypothesis | 5 | Lean |
contradiction |
closes a goal whose context is impossible | 5 | Lean |
by_cases |
splits on whether a statement holds | 6 | Lean |
rw |
rewrites the goal using an equation | 6 | Lean |
rcases |
takes apart an ∨ or ∧ hypothesis |
6 | Lean |
exact |
closes the goal with a given proof | 6 | Lean |
exact? |
searches for a lemma that closes the goal | 6 | Lean |
trace_state |
prints the goal to the build output | how-to | Lean |
constructor |
splits a goal such as ↔ into its parts |
explanation | Lean |
refine |
supplies a proof with holes left as new goals | explanation | Lean |
simp only |
unfolds the named definitions and nothing else | how-to | Lean |
linarith |
proves a linear consequence of the hypotheses | how-to | Mathlib |
nlinarith |
as linarith, allowing products of hypotheses |
how-to | Mathlib |
positivity |
proves that an expression is positive or non-negative | how-to | Mathlib |
apply |
uses a lemma backwards, leaving its assumptions | how-to | Lean |
obtain |
unpacks an ∃ or ∧ hypothesis |
how-to | Lean |
apply?, rw? |
search for a lemma to apply or rewrite with | how-to | Lean |
ring |
proves equations that hold by algebra alone | how-to | Mathlib |
ext |
proves two functions or strategies equal pointwise | how-to | Lean |
show |
restates the goal in an equivalent form | how-to | Lean |
norm_num¶
Proves goals that are arithmetic once definitions are unfolded, such as
inequalities between numerals. Definitions it may unfold are passed in
brackets; without them it treats payoff as opaque and makes no progress. It
builds a proof from Mathlib lemmas and never computes with real numbers, which
is why it works where decide does not.
rfl¶
Proves a = b when the two sides are equal by definition, by computing both.
It proves equalities only; on an inequality it fails with a type mismatch. In
these notes it is used as a term after := rather than inside by.
decide¶
Proves a goal by finding a decision procedure for it and running it. It works for concrete statements about natural numbers, integers and finite types, and fails on real numbers, whose comparisons have no procedure. See Computation and the real numbers.
intro¶
Proves a goal of the form ∀ x, P x or P → Q by naming the variable or the
hypothesis and moving it into the context. Several names may be given at once,
and a goal ¬ P is treated as P → False.
Before and after intro opponent:
cases¶
Splits a variable of an inductive type into one goal per constructor,
substituting the constructor for the variable in the goal and in every
hypothesis. On Action it produces the goals case cooperate and
case defect.
The focusing dot¶
·, typed \., focuses on the first remaining goal. The tactics indented
beneath it must close that goal, and Lean reports an error if they do not.
The combinator <;>¶
t <;> s runs t, then runs s on every goal that t produced.
left¶
Proves P ∨ Q by committing to P, leaving P as the goal. The tactic
right commits to Q.
have¶
Adds a named fact to the context. The fact is often a hypothesis applied to
particular arguments, since a proof of a ∀ statement is a function.
at¶
Many tactics act on the goal by default; at h makes them act on the
hypothesis h instead. In the example above, norm_num [payoff] at tempted
reduces the hypothesis to False, which closes the goal.
contradiction¶
Closes the goal when the context contains something impossible, such as a
hypothesis h : a ≠ a or h : False. The goal itself need not be true.
by_cases¶
by_cases h : P splits into two goals, case pos with h : P and case neg
with h : ¬P. It works for any statement, whether or not a type has
constructors to split on.
rw¶
rw [h], where h : a = b, replaces every a in the goal by b. After
rewriting it tries to close the goal by reflexivity, which is why rw [same]
above finishes its case. Adding at h' rewrites a hypothesis instead.
rcases¶
Takes a hypothesis apart according to a pattern. a | b splits a disjunction
into two goals; ⟨a, b⟩ splits a conjunction into two hypotheses; _ discards
a part, which then appears in the context with a dagger, as in right✝.
exact¶
exact e closes the goal when e is a proof of exactly that goal. The two
uses above apply the Mathlib lemmas le_of_lt : a < b → a ≤ b and
le_of_eq : a = b → a ≤ b to hypotheses from the context.
exact?¶
Searches the imported libraries for a lemma that closes the goal and reports
it as a suggestion, in the form Try this: exact .... It is for exploring;
the suggestion is then written into the proof in its place.
trace_state¶
Prints the current goals as an informational message without changing them,
so that they appear in the output of lake build. See Read a goal without an
infoview.
constructor¶
Splits a goal built from a structure into one goal per part. On P ↔ Q it
produces the two directions, P → Q and Q → P.
simp only¶
simp only [f, g] unfolds the definitions f and g, and simplifies with
the given lemmas only. Plain simp would also use every lemma Mathlib marks
for simplification, which is more powerful and less predictable.
linarith¶
Proves a goal that follows from the hypotheses by adding them and multiplying
them by constants. It works by assuming the goal is false and deriving a
contradiction. It does not unfold definitions, so simp only usually comes
first. See Prove an inequality.
nlinarith¶
As linarith, but it also multiplies pairs of hypotheses together, which
handles products such as a probability times a payoff. It accepts extra facts
as hints in brackets.
positivity¶
Proves goals of the form 0 < e or 0 ≤ e by the structure of e: squares,
sums of non-negative terms, products of positive terms and so on.
apply¶
apply f closes the goal with the lemma f when its conclusion matches,
leaving each of its assumptions as a new goal. See Use a
hypothesis.
obtain¶
obtain ⟨x, h⟩ := e takes apart a proof e of ∃ x, P x or of P ∧ Q,
naming the pieces.
apply? and rw?¶
Like exact?, these search the imported libraries: apply? for a lemma that
applies to the goal, possibly leaving further goals, and rw? for an equation
to rewrite with. See Find a lemma.
ring¶
Proves an equation between expressions in a commutative ring, such as the real numbers, when it follows from the laws of algebra alone: expanding, collecting terms and cancelling. It uses no hypotheses.
ext¶
Reduces an equality between functions, or between structures built from
functions such as mixed strategies, to an equality at each argument. After
ext posture the goal is about the value at an arbitrary posture.
show¶
show P replaces the goal with P, provided the two are the same statement
once definitions are unfolded. It is used to make a goal readable, or to put it
in the form a following tactic expects.
refine¶
refine e closes the goal with a term e that may contain holes written ?_.
Each hole becomes a new goal. Above, the first half of a conjunction is
supplied at once and the second is left to prove.