Tactic mode is the interactive, goal-directed style of proof in Lean 4. You enter it with theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/leanprover/lean4/llms.txt
Use this file to discover all available pages before exploring further.
by keyword, and from that point you issue a sequence of tactics that progressively transform proof goals until none remain. Each tactic consumes one or more goals and may produce new subgoals.
The Tactic State
When working in an IDE with the Lean 4 language server, you see the tactic state at the cursor position:⊢ contains your local hypotheses (variables and assumptions). The line after ⊢ is the current goal — the type you must inhabit to complete the proof.
Multiple goals are displayed stacked. Use
· (focused dot) or case labels to work on a specific goal. The <;> combinator applies a tactic to all goals produced by the previous tactic.Introducing Hypotheses
intro / intros
intro moves universally-quantified variables and implication antecedents from the goal into the context. intros (plural) does the same repeatedly until the goal is no longer a binder.
intro also supports inline destructuring patterns when introducing a pair or product type from the goal:
Closing Goals
exact
exact e closes the goal when e has exactly the required type.
assumption
assumption searches the local context for a hypothesis that matches the goal.
trivial
trivial tries several cheap tactics in sequence: rfl, trivial (recursively), assumption, and decide. It closes simple goals like ⊢ True.
contradiction
contradiction closes the goal when the hypotheses contain an obvious contradiction — for example h₁ : p and h₂ : ¬p, or h : False, or a hypothesis of an uninhabited inductive type.
Applying Lemmas
apply
apply f unifies the conclusion of f with the current goal and creates new goals for each unresolved premise of f.
refine
refine e is like exact, but allows ?_ placeholders that become new goals.
Rewriting
rw
rw [h] rewrites the goal using the equation h : a = b (left-to-right by default). Use ←h to rewrite right-to-left. You can provide a list: rw [h₁, h₂, ...].
rw [h] at hyp rewrites in a hypothesis instead of the goal.
simp
simp applies a curated set of lemmas tagged @[simp] repeatedly until no further simplifications apply. It subsumes many common proof steps.
simp [h₁, h₂] adds extra lemmas to the simp set. simp only [h] uses only the given lemmas (no default simp set). simp at h simplifies a hypothesis.
Arithmetic Tactics
omega
omega is a complete decision procedure for linear arithmetic over Nat and Int. It handles equalities, inequalities, divisibility by literals, and natural-number subtraction.
grind
grind is a powerful general-purpose automation tactic that combines congruence closure, equational reasoning, E-matching, case splitting, and multiple specialized solvers (including linear arithmetic and ring arithmetic). It is especially effective at goals involving many equalities, logical connectives, and arithmetic.
grind subsumes many common arithmetic and logical goals. Use grind? to have Lean report the minimal grind only [...] invocation needed.
grind is a built-in Lean 4 tactic. The Mathlib library provides additional specialized tactics such as ring (ring equalities), linarith (linear arithmetic over ordered fields), and norm_num (concrete numeric computations). These are not part of the Lean 4 core and require importing Mathlib.lia
lia solves linear integer arithmetic goals. It is a thin wrapper around grind that enables only the linear arithmetic solver.
Nat and Int, omega is preferred since it is complete and handles natural-number subtraction. Use lia when working with integers that have signed semantics.
decide
decide proves goals of a Decidable proposition by reducing them via the kernel. It is complete for any proposition with a Decidable instance.
Case Analysis and Induction
cases
cases h performs case analysis on an inductive value h, producing one goal per constructor.
rcases
rcases h with pattern is a powerful recursive pattern-matching tactic that can destructure nested And, Or, Exists, and constructor types in one step.
obtain
obtain is like rcases but uses have-like syntax. It is especially clean for ∃ goals:
induction
induction x applies structural induction on x, producing one goal per constructor. The induction hypothesis is named ih by default.
Building Terms
constructor
constructor applies the first applicable constructor of the goal type.
left / right
left applies Or.inl; right applies Or.inr.
use (via exists)
exists e (built on refine ⟨e, ?_⟩) provides a witness for an existential goal:
Structuring Proofs
have
have h : t := e or have h : t := by tac introduces a new local hypothesis.
suffices
suffices h : t from e replaces the goal with t, using e to show the original goal follows from t.
show
show t changes the displayed form of the goal to t (which must be definitionally equal to the current goal).
Congruence and Focusing
conv
conv enters a sub-tactic mode for navigating inside a term to perform targeted rewrites.
Tactic Combinators
Tactic combinators let you sequence, branch, and repeat tactics.- Sequential: `<;>`
- Alternation: `first`
- Optional: `try`
- Repetition: `repeat`
tac₁ <;> tac₂ runs tac₁ and then applies tac₂ to every goal produced.Quick Reference Table
| Tactic | Purpose |
|---|---|
intro x | Introduce a hypothesis or variable |
exact e | Close goal with term e |
assumption | Close goal with a matching hypothesis |
apply f | Apply lemma f, creating premise goals |
refine e | Like exact with ?_ holes |
rw [h] | Rewrite with equation h |
simp | Simplify using @[simp] lemmas |
simp only [h] | Simplify using only h |
omega | Linear arithmetic over Nat/Int |
lia | Linear integer arithmetic (grind wrapper) |
grind | General-purpose: congruence, arithmetic, logic |
decide | Decidable propositions by reduction |
cases h | Case-split on inductive value |
rcases h with pat | Recursive pattern case-split |
obtain ⟨x, hx⟩ := h | Destructure ∃ or ∧ |
induction x | Structural induction |
constructor | Apply first constructor |
left / right | Apply Or.inl / Or.inr |
have h : t := ... | Introduce local hypothesis |
suffices h : t by ... | Reduce to a sufficient condition |
show t | Rename goal (definitional equality) |
conv => ... | Targeted term navigation |
trivial | Close trivial goals |
contradiction | Close contradictory contexts |
<;> | Apply tactic to all goals |
first | t₁ | t₂ | Ordered choice |
try t | Optional tactic |
repeat t | Repeat until failure |