| ← Worked example | Index |
Key points. A goal is hypotheses above a line, a statement to prove
below it; a tactic replaces it with zero or more simpler goals. The core
loop is: try the cheapest tactic, read why it failed, find structure to
split or induct on, locate the specific lemma that matches. induction
generates one case (and hypothesis ih) per constructor, exactly
mirroring a recursive function over the same type.
Socratic questions.
rwrewroteNat.add_succand closed thesucccase ofmy_add_comm, but the same tactic failed ona + b = b + abefore any induction. What changed between the two attempts? Nothing aboutrwitself — what changed is what is available to rewrite with. Before induction there is no fact relatinga + bandb + aat all; afterinduction b, thesucccase comes withih : a + k = k + aalready in hand, givingrwsomething to substitute.- A tactic that produces no error but also does not close the goal — is that a success or a failure? Neither, and treating it as either is the mistake. It is progress to inspect: the goal state after the tactic is the actual source of truth, not the absence of a red error message. This is precisely why the goal state is checked after every tactic, not just at the end.
-
nat_mul_zero (n : Nat) : n * 0 = 0closes byrflalone. Would0 * n = 0also close byrfl? No —Nat.mulrecurses on its second argument, exactly likeNat.add, son * 0 = 0is the base clause (immediate), while0 * n = 0needs an actual induction onn, for the same left/right-asymmetry reason0 + n = ndid earlier in this chapter. - Prove
theorem and_comm_tac {P Q : Prop} (h : P ∧ Q) : Q ∧ P := by ...usingconstructor,h.left,h.right. - Prove
theorem nat_mul_zero (n : Nat) : n * 0 = 0 := by rfl— check whetherrflalone works, and if not, useinduction. - Rewrite the
modus_ponensproof from Chapter 3 in tactic mode.
Solutions: Appendix, Chapter 4.
With definitions, propositions, and tactics in hand, we pause for a brief rigor check before diving into groups.
| ← Worked example | Index | Table of contents | Ch. 5: Rigor Check → |