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 → c⊢ a → c
a:Propb:Propc:Prophab:a → bhbc:b → cha:a⊢ c
a:Propb:Propc:Prophab:a → bhbc:b → cha:ahb:b⊢ c
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:a⊢ c
a:Propb:Propc:Prophab:a → bhbc:b → cha:ahb:b⊢ c
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:a⊢ c
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:a⊢ b
a:Propb:Prophab:a → bha:ahb:b⊢ b
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 + n⊢ n + n = n + n
n:ℕm:ℕ := n + n⊢ m = 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 n⊢ P 7
P:ℕ → Proph:P 7⊢ P 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 = 0⊢ f a + 1 = 1
f:ℕ → ℕa:ℕh:f a = 0hf:f a = 0⊢ f 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 → Q⊢ Q
α:TypeP:α → PropQ:Proph:∀ (x : α), P x → Qa:αha:P a⊢ Q
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:a⊢ c
a:Propb:Propc:Prophab:a → bhbc:b → cha:ahb:b⊢ c
a:Propb:Propc:Prophab:a → bhbc:b → cha:ahb:bhc:c⊢ c
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:a⊢ c
a:Propb:Propc:Prophab:a → bhbc:b → cha:a⊢ b
a:Propb:Propc:Prophab:a → bhbc:b → cha:ahb:b⊢ b
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:a⊢ b
a:Propb:Prophab:a → bha:a⊢ a
All goals completed! 🐙
example (a b : Prop) (hab : a → b) (ha : a) : b := a:Propb:Prophab:a → bha:a⊢ b
All goals completed! 🐙
end Forward