Formal Software Verification

5.5. Forward Reasoning with Tactics🔗

Real proofs interleave the two directions. In tactic mode, have h : P := pf and have h : P := by … add a proved fact to the context, and let x := t adds an abbreviation, both working forwards while the surrounding proof works backwards. The specialize tactic of Lecture 2 and the elimination obtain ⟨…⟩ := h are further forward steps. The composition of implications, proved forwards as a term earlier in this lecture, reads in the mixed style as one forward have inside a backward proof.

namespace Forward theorem prop_comp_tactical (a b c : Prop) (hab : a b) (hbc : b c) : a c := a:Propb:Propc:Prophab:a bhbc:b ca c a:Propb:Propc:Prophab:a bhbc:b cha:ac a:Propb:Propc:Prophab:a bhbc:b cha:ahb:bc All goals completed! 🐙 end Forward

The forward have builds b from ha and hab, and the backward exact closes the goal with hbc applied to it. The mixed proof is often the shortest, because it takes each fact from wherever it is easiest to reach.

5.5.1. Examples🔗

The examples below add facts with have, abbreviate with let, instantiate with specialize, eliminate with obtain, and mix the two directions.

Example 1. A forward have builds the intermediate fact, and a backward exact closes the goal.

namespace Forward example (a b c : Prop) (hab : a b) (hbc : b c) (ha : a) : c := a:Propb:Propc:Prophab:a bhbc:b cha:ac a:Propb:Propc:Prophab:a bhbc:b cha:ahb:bc All goals completed! 🐙 end Forward

Example 2. The same theorem written purely backwards, for contrast.

namespace Forward example (a b c : Prop) (hab : a b) (hbc : b c) (ha : a) : c := a:Propb:Propc:Prophab:a bhbc:b cha:ac All goals completed! 🐙 end Forward

Example 3. have … := by … proves the intermediate fact by its own tactic block.

namespace Forward example (a b : Prop) (hab : a b) (ha : a) : b := a:Propb:Prophab:a bha:ab a:Propb:Prophab:a bha:ahb:bb All goals completed! 🐙 end Forward

Example 4. let x := t abbreviates a term, and show restates the goal in terms of the abbreviation.

namespace Forward example (n : ) : n + n = n + n := n:n + n = n + n n:m: := n + nn + n = n + n n:m: := n + nm = m All goals completed! 🐙 end Forward

Example 5. specialize instantiates a universal hypothesis forwards, recalling Lecture 2.

namespace Forward example (P : Prop) (h : n, P n) : P 7 := P: Proph: (n : ), P nP 7 P: Proph:P 7P 7 All goals completed! 🐙 end Forward

Example 6. A forward have makes a subsequent simp succeed.

namespace Forward example (f : ) (a : ) (h : f a = 0) : f a + 1 = 1 := f: a:h:f a = 0f a + 1 = 1 f: a:h:f a = 0hf:f a = 0f a + 1 = 1 All goals completed! 🐙 end Forward

Example 7. obtain ⟨a, ha⟩ := h eliminates an existential hypothesis forwards, naming its witness.

namespace Forward example (α : Type) (P : α Prop) (Q : Prop) (hex : x, P x) (h : x, P x Q) : Q := α:TypeP:α PropQ:Prophex: x, P xh: (x : α), P x QQ α:TypeP:α PropQ:Proph: (x : α), P x Qa:αha:P aQ All goals completed! 🐙 end Forward

Example 8. Two have steps chained, the second using the first.

namespace Forward example (a b c : Prop) (hab : a b) (hbc : b c) (ha : a) : c := a:Propb:Propc:Prophab:a bhbc:b cha:ac a:Propb:Propc:Prophab:a bhbc:b cha:ahb:bc a:Propb:Propc:Prophab:a bhbc:b cha:ahb:bhc:cc All goals completed! 🐙 end Forward

Example 9. A proof mixing a backward apply with a forward have.

namespace Forward example (a b c : Prop) (hab : a b) (hbc : b c) (ha : a) : c := a:Propb:Propc:Prophab:a bhbc:b cha:ac a:Propb:Propc:Prophab:a bhbc:b cha:ab a:Propb:Propc:Prophab:a bhbc:b cha:ahb:bb All goals completed! 🐙 end Forward

Example 10. The same theorem backward-only and mixed, so the mixed one shows its economy.

namespace Forward example (a b : Prop) (hab : a b) (ha : a) : b := a:Propb:Prophab:a bha:ab a:Propb:Prophab:a bha:aa All goals completed! 🐙 example (a b : Prop) (hab : a b) (ha : a) : b := a:Propb:Prophab:a bha:ab All goals completed! 🐙 end Forward