Rewriting is most effective when guided by a small set of consistent strategies.
Rewriting is most effective when guided by a small set of consistent strategies. In Lean, uncontrolled rewriting leads to fragile proofs and poor performance. This section consolidates practical heuristics for predictable, scalable use.
Normalize to canonical forms
Choose a canonical representation and drive all expressions toward it. Examples:
- Eliminate neutral elements:
a + 0 → a - Normalize constructors: prefer
Nat.succat the outermost level - Fix argument order when using commutativity
This aligns with the simp set and reduces branching in proofs.
Separate normalization from transformation
Use simp for normalization and rw for directed changes.
-- normalization
simp
-- directed transformation
rw [h]Mixing them without structure often obscures intent. A common pattern:
- Normalize (
simp) - Transform (
rw) - Normalize again (
simp)
Control direction explicitly
Always choose rewrite direction deliberately:
rw [h] -- a → b
rw [← h] -- b → aPrefer the direction that reduces complexity or matches a known lemma. Avoid oscillating between equivalent forms.
Keep steps small
Break complex transformations into small steps:
rw [h₁]
rw [h₂]or use calc for longer chains. This improves debuggability and makes intermediate states visible.
Normalize context early
If a hypothesis will be reused, normalize it once:
rw [h] at Hor:
simp [h] at HThis avoids repeated rewriting and keeps the context consistent.
Prefer local over global effects
Use local rewrites and local simp extensions:
simp [h]Avoid adding global rules unless they are universally valid and oriented correctly. Local control reduces unintended interactions.
Use extensionality when needed
When rewriting fails due to abstraction, expose structure:
funext x
rw [h]or use ext for structures. Do not attempt to rewrite through opaque boundaries.
Switch tools when stuck
- Use
rwfor precise, single-step changes. - Use
simpfor normalization. - Use
calcfor chained reasoning. - Use
convfor targeted subterm rewriting. - Use
casesorfunextto expose structure.
Choosing the right tool is often more important than adding more lemmas.
Avoid rewrite loops
Maintain a terminating rewrite system:
- Orient lemmas toward simpler forms
- Avoid symmetric rules in
simp - Use
simp onlywhen necessary - Exclude problematic lemmas explicitly
Inspect goals frequently
After each step, check the goal:
#check ...or rely on the editor’s goal view. Early detection of mismatches prevents cascading errors.
Design lemmas for rewriting
Good rewrite lemmas:
- Have clear left-hand sides
- Reduce structural complexity
- Avoid unnecessary premises
- Compose well with other lemmas
Poorly designed lemmas create ambiguity and instability.
Summary
Effective rewriting follows a disciplined workflow: normalize to canonical forms, apply directed transformations, and maintain control over rule sets and direction. Small, explicit steps combined with appropriate tools yield proofs that are both robust and maintainable.