Formal Software Verification

5.4. Calculational Proofs🔗

A calculational proof lays a chain of equalities out for the reader, one step per line, each step justified by a rewrite or a lemma. The keyword calc composes the steps into a single transitive derivation, playing the part of Eq.trans so the writer does not have to. Each step is exactly the kind of equation that rw consumes, and a step that holds only up to associativity and commutativity is closed by the ac_rfl of Lecture 4. The layout reads as a mathematician writes it, with the running term on the left and the justification on the right.

namespace Forward theorem two_mul_example (m n : ) : 2 * m + n = m + n + m := m:n:2 * m + n = m + n + m calc 2 * m + n = (m + m) + n := m:n:2 * m + n = m + m + n All goals completed! 🐙 _ = m + n + m := m:n:m + m + n = m + n + m All goals completed! 🐙 end Forward

The same argument written with nested have steps and Eq.trans shows what calc abbreviates. The chain of two equalities becomes two named facts joined by transitivity.

namespace Forward theorem two_mul_example_have (m n : ) : 2 * m + n = m + n + m := m:n:2 * m + n = m + n + m m:n:h1:2 * m + n = m + m + n2 * m + n = m + n + m m:n:h1:2 * m + n = m + m + nh2:m + m + n = m + n + m2 * m + n = m + n + m All goals completed! 🐙 end Forward

calc also chains any transitive relation, not equality alone, and the examples include a chain over ↔ closed by Iff.trans.

5.4.1. Examples🔗

The examples below build calculational chains, justify their steps by rewrites and by lemmas, and compare calc with the alternatives it abbreviates.

Example 1. A two-step chain on ℕ, each step closed by rfl.

namespace Forward example : (1 : ) + 1 + 1 = 3 := 1 + 1 + 1 = 3 calc (1 : ) + 1 + 1 = 2 + 1 := rfl _ = 3 := rfl end Forward

Example 2. The same identity by Eq.trans, which exposes what the chain abbreviates.

namespace Forward example : (1 : ) + 1 + 1 = 3 := Eq.trans (rfl : (1 : ) + 1 + 1 = 2 + 1) (rfl : (2 : ) + 1 = 3) end Forward

Example 3. A single step justified by rewriting with commutativity.

namespace Forward example (a b : ) : a + b = b + a := a:b:a + b = b + a calc a + b = b + a := a:b:a + b = b + a All goals completed! 🐙 end Forward

Example 4. A step justified by a named lemma from Lecture 4, the associativity of our add.

namespace Forward example (l m n : ) : add (add l m) n = add l (add m n) := l:m:n:add (add l m) n = add l (add m n) calc add (add l m) n = add l (add m n) := Backward.add_assoc l m n end Forward

Example 5. A chain that mixes a rw step with an ac_rfl step, the full doubling identity.

namespace Forward example (m n : ) : 2 * m + n = m + n + m := m:n:2 * m + n = m + n + m calc 2 * m + n = (m + m) + n := m:n:2 * m + n = m + m + n All goals completed! 🐙 _ = m + n + m := m:n:m + m + n = m + n + m All goals completed! 🐙 end Forward

Example 6. A chain whose last step is ac_rfl and whose first is a rfl.

namespace Forward example (a b c : ) : a + b + c = c + (a + b) := a:b:c:a + b + c = c + (a + b) calc a + b + c = (a + b) + c := rfl _ = c + (a + b) := a:b:c:a + b + c = c + (a + b) All goals completed! 🐙 end Forward

Example 7. A chain of three equalities built from two hypotheses.

namespace Forward example (a b c d : ) (h1 : a = b) (h2 : b = c) (h3 : c = d) : a = d := a:b:c:d:h1:a = bh2:b = ch3:c = da = d calc a = b := h1 _ = c := h2 _ = d := h3 end Forward

Example 8. calc chains two biconditionals with Iff.trans exactly as it chains equalities.

namespace Forward example (a b c : Prop) (h1 : a b) (h2 : b c) : a c := a:Propb:Propc:Proph1:a bh2:b ca c calc a b := h1 _ c := h2 end Forward

Example 9. The same goal by an explicit chain and by a single simp, which shows when the chain earns its length.

namespace Forward example (a b : ) : (a + b) * 1 = a + b := a:b:(a + b) * 1 = a + b calc (a + b) * 1 = a + b := a:b:(a + b) * 1 = a + b All goals completed! 🐙 example (a b : ) : (a + b) * 1 = a + b := a:b:(a + b) * 1 = a + b All goals completed! 🐙 end Forward

Example 10. A step that reads right to left, justified by a rewrite with a reversed equation.

namespace Forward example (a b : ) (h : a = b) : b = a := a:b:h:a = bb = a calc b = a := a:b:h:a = bb = a All goals completed! 🐙 end Forward